From c8c4a273c9b3d8795785b82c98f056d2787586ee Mon Sep 17 00:00:00 2001 From: shadow2560 <24191064+shadow2560@users.noreply.github.com> Date: Fri, 20 Dec 2024 18:42:28 +0100 Subject: [PATCH 01/25] Init and close Set service so auto language work now. (#31) * Init and close Set service so auto language work now. Signed-off-by: shadow2560 <24191064+shadow2560@users.noreply.github.com> * Init and close Set service place moved into services init/close order. Signed-off-by: shadow2560 <24191064+shadow2560@users.noreply.github.com> --------- Signed-off-by: shadow2560 <24191064+shadow2560@users.noreply.github.com> --- sphaira/source/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sphaira/source/main.cpp b/sphaira/source/main.cpp index 2c5663c..1a5c72e 100644 --- a/sphaira/source/main.cpp +++ b/sphaira/source/main.cpp @@ -59,6 +59,8 @@ void userAppInit(void) { diagAbortWithResult(rc); if (R_FAILED(rc = accountInitialize(is_application ? AccountServiceType_Application : AccountServiceType_System))) diagAbortWithResult(rc); + if (R_FAILED(rc = setInitialize())) + diagAbortWithResult(rc); log_nxlink_init(); } @@ -66,6 +68,7 @@ void userAppInit(void) { void userAppExit(void) { log_nxlink_exit(); + setExit(); accountExit(); nifmExit(); psmExit(); From dd6371997c5f472671109d2ba45f24fdd967a4c9 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 01:21:45 +0000 Subject: [PATCH 02/25] fix core3 being pinned at 100% due to nxlink polling. this was caused due to https://github.com/ITotalJustice/sphaira/commit/9966e57e1222727520dc48290d49ed034d5bc1f8 --- sphaira/source/nxlink.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphaira/source/nxlink.cpp b/sphaira/source/nxlink.cpp index d0f2f3c..9ca7a8a 100644 --- a/sphaira/source/nxlink.cpp +++ b/sphaira/source/nxlink.cpp @@ -224,7 +224,7 @@ void loop(void* args) { }; while (!g_quit) { - svcSleepThread(1000000); + svcSleepThread(1e+8); if (poll_network_change()) { continue; @@ -267,7 +267,7 @@ void loop(void* args) { sockaddr_in sa_remote{}; while (!g_quit) { - svcSleepThread(10000); + svcSleepThread(1e+8); if (poll_network_change()) { break; From 55c952a51fcef53ff62822d26eaec1e9affbe759 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:30:32 +0000 Subject: [PATCH 03/25] add stars in homebrew menu (hbmenu feature) fixes #22 --- CMakeLists.txt | 7 ++ sphaira/include/nro.hpp | 2 + sphaira/include/ui/menus/homebrew.hpp | 15 +++- sphaira/source/ui/menus/homebrew.cpp | 111 ++++++++++++++++++++++---- 4 files changed, 117 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7622d68..2446358 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,5 +42,12 @@ function(dkp_fatal_if_not_found var package) endif() endfunction(dkp_fatal_if_not_found var package) +# disable exceptions and rtti in order to shrink final binary size. +add_compile_options( + "$<$:-fno-exceptions>" + "$<$:-fno-exceptions>" + "$<$:-fno-rtti>" +) + add_subdirectory(hbl) add_subdirectory(sphaira) diff --git a/sphaira/include/nro.hpp b/sphaira/include/nro.hpp index d7742ab..717fd1c 100644 --- a/sphaira/include/nro.hpp +++ b/sphaira/include/nro.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "fs.hpp" namespace sphaira { @@ -28,6 +29,7 @@ struct NroEntry { int image{}; // nvg image int x,y,w,h{}; // image bool is_nacp_valid{}; + std::optional has_star{std::nullopt}; auto GetName() const -> const char* { return nacp.lang[0].name; diff --git a/sphaira/include/ui/menus/homebrew.hpp b/sphaira/include/ui/menus/homebrew.hpp index d385c30..4d71126 100644 --- a/sphaira/include/ui/menus/homebrew.hpp +++ b/sphaira/include/ui/menus/homebrew.hpp @@ -9,8 +9,11 @@ namespace sphaira::ui::menu::homebrew { enum SortType { SortType_Updated, - SortType_Size, SortType_Alphabetical, + SortType_Size, + SortType_UpdatedStar, + SortType_AlphabeticalStar, + SortType_SizeStar, }; enum OrderType { @@ -36,6 +39,10 @@ struct Menu final : MenuBase { return m_entries; } + auto IsStarEnabled() -> bool { + return m_sort.Get() >= SortType_UpdatedStar; + } + static Result InstallHomebrew(const fs::FsPath& path, const NacpStruct& nacp, const std::vector& icon); static Result InstallHomebrewFromPath(const fs::FsPath& path); @@ -46,9 +53,9 @@ struct Menu final : MenuBase { std::size_t m_start{}; std::size_t m_index{}; // where i am in the array - option::OptionLong m_sort{INI_SECTION, "sort", SortType::SortType_Updated}; + option::OptionLong m_sort{INI_SECTION, "sort", SortType::SortType_AlphabeticalStar}; option::OptionLong m_order{INI_SECTION, "order", OrderType::OrderType_Decending}; - option::OptionBool m_hide_sphaira{INI_SECTION, "hide_sphaira", false};} -; + option::OptionBool m_hide_sphaira{INI_SECTION, "hide_sphaira", false}; +}; } // namespace sphaira::ui::menu::homebrew diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index 2bd4cdd..aba493a 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -17,6 +17,12 @@ namespace sphaira::ui::menu::homebrew { namespace { +auto GenerateStarPath(const fs::FsPath& nro_path) -> fs::FsPath { + fs::FsPath out{}; + const auto dilem = std::strrchr(nro_path.s, '/'); + std::snprintf(out, sizeof(out), "%.*s.%s.star", dilem - nro_path.s + 1, nro_path.s, dilem + 1); + return out; +} } // namespace @@ -74,8 +80,11 @@ Menu::Menu() : MenuBase{"Homebrew"_i18n} { SidebarEntryArray::Items sort_items; sort_items.push_back("Updated"_i18n); - sort_items.push_back("Size"_i18n); sort_items.push_back("Alphabetical"_i18n); + sort_items.push_back("Size"_i18n); + sort_items.push_back("Updated (Star)"_i18n); + sort_items.push_back("Alphabetical (Star)"_i18n); + sort_items.push_back("Size (Star)"_i18n); SidebarEntryArray::Items order_items; order_items.push_back("Decending"_i18n); @@ -90,6 +99,10 @@ Menu::Menu() : MenuBase{"Homebrew"_i18n} { m_order.Set(index_out); SortAndFindLastFile(); }, m_order.Get())); + + options->Add(std::make_shared("Hide Sphaira"_i18n, m_hide_sphaira.Get(), [this](bool& enable){ + m_hide_sphaira.Set(enable); + }, "Enabled"_i18n, "Disabled"_i18n)); })); #if 0 @@ -113,10 +126,6 @@ Menu::Menu() : MenuBase{"Homebrew"_i18n} { )); }, true)); - options->Add(std::make_shared("Hide Sphaira"_i18n, m_hide_sphaira.Get(), [this](bool& enable){ - m_hide_sphaira.Set(enable); - }, "Enabled"_i18n, "Disabled"_i18n)); - options->Add(std::make_shared("Install Forwarder"_i18n, [this](){ App::Push(std::make_shared( "WARNING: Installing forwarders will lead to a ban!"_i18n, @@ -151,6 +160,7 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { const u64 max_entry_display = 9; const u64 nro_total = m_entries.size(); const u64 cursor_pos = m_index; + fs::FsNativeSd fs; // only draw scrollbar if needed if (nro_total > max_entry_display) { @@ -187,18 +197,18 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { nvgSave(vg); nvgScissor(vg, x, y, w - 30.f, h); // clip { + bool has_star = false; + if (IsStarEnabled()) { + if (!e.has_star.has_value()) { + e.has_star = fs.FileExists(GenerateStarPath(e.path)); + } + has_star = e.has_star.value(); + } + const float font_size = 18; - const float diff = 32; - #if 1 - gfx::drawTextArgs(vg, x + 148, y + 45, font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, "%s", e.GetName()); + gfx::drawTextArgs(vg, x + 148, y + 45, font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, "%s%s", has_star ? "\u2605 " : "", e.GetName()); gfx::drawTextArgs(vg, x + 148, y + 80, font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, e.GetAuthor()); gfx::drawTextArgs(vg, x + 148, y + 115, font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, e.GetDisplayVersion()); - #else - gfx::drawTextArgs(vg, x + 148, y + 35, font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, "%s", e.GetName()); - gfx::drawTextArgs(vg, x + 148, y + 35 + (diff * 1), font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, e.GetAuthor()); - gfx::drawTextArgs(vg, x + 148, y + 35 + (diff * 2), font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, e.GetDisplayVersion()); - // gfx::drawTextArgs(vg, x + 148, y + 110, font_size, NVG_ALIGN_LEFT, theme->elements[text_id].colour, "PlayCount: %u", e.hbini.launch_count); - #endif } nvgRestore(vg); } @@ -219,6 +229,26 @@ void Menu::SetIndex(std::size_t index) { } const auto& e = m_entries[m_index]; + + if (IsStarEnabled()) { + const auto star_path = GenerateStarPath(m_entries[m_index].path); + if (fs::FsNativeSd().FileExists(star_path)) { + SetAction(Button::R3, Action{"Unstar"_i18n, [this](){ + fs::FsNativeSd().DeleteFile(GenerateStarPath(m_entries[m_index].path)); + App::Notify("Unstarred "_i18n + m_entries[m_index].GetName()); + SortAndFindLastFile(); + }}); + } else { + SetAction(Button::R3, Action{"Star"_i18n, [this](){ + fs::FsNativeSd().CreateFile(GenerateStarPath(m_entries[m_index].path)); + App::Notify("Starred "_i18n + m_entries[m_index].GetName()); + SortAndFindLastFile(); + }}); + } + } else { + RemoveAction(Button::R3); + } + // TimeCalendarTime caltime; // timeToCalendarTimeWithMyRule() // todo: fix GetFileTimeStampRaw being different to timeGetCurrentTime @@ -276,12 +306,31 @@ void Menu::ScanHomebrew() { } void Menu::Sort() { + if (IsStarEnabled()) { + fs::FsNativeSd fs; + fs::FsPath star_path; + for (auto& p : m_entries) { + p.has_star = fs.FileExists(GenerateStarPath(p.path)); + if (p.has_star) { + log_write("found star: %s\n", p.path.s); + } else { + log_write("no star: %s\n", p.path.s); + } + } + } + // returns true if lhs should be before rhs const auto sort = m_sort.Get(); const auto order = m_order.Get(); const auto sorter = [this, sort, order](const NroEntry& lhs, const NroEntry& rhs) -> bool { switch (sort) { + case SortType_UpdatedStar: + if (lhs.has_star.value() && !rhs.has_star.value()) { + return true; + } else if (!lhs.has_star.value() && rhs.has_star.value()) { + return false; + } case SortType_Updated: { auto lhs_timestamp = lhs.hbini.timestamp; auto rhs_timestamp = rhs.hbini.timestamp; @@ -300,6 +349,13 @@ void Menu::Sort() { return lhs_timestamp < rhs_timestamp; } } break; + + case SortType_SizeStar: + if (lhs.has_star.value() && !rhs.has_star.value()) { + return true; + } else if (!lhs.has_star.value() && rhs.has_star.value()) { + return false; + } case SortType_Size: { if (lhs.size == rhs.size) { return strcasecmp(lhs.GetName(), rhs.GetName()) < 0; @@ -309,6 +365,13 @@ void Menu::Sort() { return lhs.size < rhs.size; } } break; + + case SortType_AlphabeticalStar: + if (lhs.has_star.value() && !rhs.has_star.value()) { + return true; + } else if (!lhs.has_star.value() && rhs.has_star.value()) { + return false; + } case SortType_Alphabetical: { if (order == OrderType_Decending) { return strcasecmp(lhs.GetName(), rhs.GetName()) < 0; @@ -325,7 +388,27 @@ void Menu::Sort() { } void Menu::SortAndFindLastFile() { + const auto path = m_entries[m_index].path; Sort(); + SetIndex(0); + + s64 index = -1; + for (u64 i = 0; i < m_entries.size(); i++) { + if (path == m_entries[i].path) { + index = i; + break; + } + } + + if (index >= 0) { + // guesstimate where the position is + if (index >= 9) { + m_start = (index - 9) / 3 * 3 + 3; + } else { + m_start = 0; + } + SetIndex(index); + } } Result Menu::InstallHomebrew(const fs::FsPath& path, const NacpStruct& nacp, const std::vector& icon) { From 8f1084b24f3d9cac3eaa741c95e6a53a8c53abb4 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:32:36 +0000 Subject: [PATCH 04/25] fix text bounds in option box fixes #28 --- sphaira/source/ui/option_box.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sphaira/source/ui/option_box.cpp b/sphaira/source/ui/option_box.cpp index 9e64fb4..10463d3 100644 --- a/sphaira/source/ui/option_box.cpp +++ b/sphaira/source/ui/option_box.cpp @@ -102,9 +102,15 @@ auto OptionBox::OnLayoutChange() -> void { } auto OptionBox::Draw(NVGcontext* vg, Theme* theme) -> void { + const float padding = 15; gfx::dimBackground(vg); gfx::drawRect(vg, m_pos, theme->elements[ThemeEntryID_SELECTED].colour); - gfx::drawText(vg, {m_pos.x + (m_pos.w / 2.f), m_pos.y + 110.f}, 26.f, theme->elements[ThemeEntryID_TEXT].colour, m_message.c_str(), NVG_ALIGN_CENTER | NVG_ALIGN_TOP); + + nvgSave(vg); + nvgTextLineHeight(vg, 1.5); + gfx::drawTextBox(vg, m_pos.x + padding, m_pos.y + 110.f, 26.f, m_pos.w - padding*2, theme->elements[ThemeEntryID_TEXT].colour, m_message.c_str(), NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); + nvgRestore(vg); + gfx::drawRect(vg, m_spacer_line, theme->elements[ThemeEntryID_TEXT].colour); for (auto&p: m_entries) { From aa03256fd4c15f85675b77d9e7cdf2fed61fa107 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:35:26 +0000 Subject: [PATCH 05/25] better naming for menu tabs (Fs -> Files, Apps, App -> Store) fixes #30 --- sphaira/include/ui/menus/main_menu.hpp | 2 ++ sphaira/source/ui/menus/main_menu.cpp | 32 ++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/sphaira/include/ui/menus/main_menu.hpp b/sphaira/include/ui/menus/main_menu.hpp index cf7ec99..9cedb0b 100644 --- a/sphaira/include/ui/menus/main_menu.hpp +++ b/sphaira/include/ui/menus/main_menu.hpp @@ -14,6 +14,8 @@ enum class UpdateState { None, // update available! Update, + // there was an error whilst checking for updates. + Error, }; // this holds 2 menus and allows for switching between them diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 798e501..1b71d7f 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -147,7 +147,13 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v MainMenu::MainMenu() { DownloadMemoryAsync("https://api.github.com/repos/ITotalJustice/sphaira/releases/latest", "", [this](std::vector& data, bool success){ - m_update_state = UpdateState::None; + m_update_state = UpdateState::Error; + ON_SCOPE_EXIT( log_write("update status: %u\n", (u8)m_update_state) ); + + if (!success) { + return false; + } + auto json = yyjson_read((const char*)data.data(), data.size(), 0); R_UNLESS(json, false); ON_SCOPE_EXIT(yyjson_doc_free(json)); @@ -160,7 +166,10 @@ MainMenu::MainMenu() { const auto version = yyjson_get_str(tag_key); R_UNLESS(version, false); - R_UNLESS(std::strcmp(APP_VERSION, version) < 0, false); + if (std::strcmp(APP_VERSION, version) >= 0) { + m_update_state = UpdateState::None; + return true; + } auto assets = yyjson_obj_get(root, "assets"); R_UNLESS(assets, false); @@ -320,8 +329,15 @@ void MainMenu::OnLRPress(std::shared_ptr menu, Button b) { if (m_current_menu == m_homebrew_menu) { m_current_menu = menu; RemoveAction(b); + if (b == Button::L) { + AddOnRPress(); + } else { + AddOnLPress(); + } } else { m_current_menu = m_homebrew_menu; + AddOnRPress(); + AddOnLPress(); } m_current_menu->OnFocusGained(); @@ -329,22 +345,18 @@ void MainMenu::OnLRPress(std::shared_ptr menu, Button b) { for (auto [button, action] : m_actions) { m_current_menu->SetAction(button, action); } - - if (b == Button::L) { - AddOnRPress(); - } else { - AddOnLPress(); - } } void MainMenu::AddOnLPress() { - SetAction(Button::L, Action{"Fs"_i18n, [this]{ + const auto label = m_current_menu == m_homebrew_menu ? "Files" : "Apps"; + SetAction(Button::L, Action{i18n::get(label), [this]{ OnLRPress(m_filebrowser_menu, Button::L); }}); } void MainMenu::AddOnRPress() { - SetAction(Button::R, Action{"App"_i18n, [this]{ + const auto label = m_current_menu == m_homebrew_menu ? "Store" : "Apps"; + SetAction(Button::R, Action{i18n::get(label), [this]{ OnLRPress(m_app_store_menu, Button::R); }}); } From 0edd7c400fcdeb9df86351853e16dc0211800ca0 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 16:46:10 +0000 Subject: [PATCH 06/25] add support for swedish translations (needed for pr merge) --- sphaira/source/i18n.cpp | 4 ++-- sphaira/source/ui/menus/main_menu.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sphaira/source/i18n.cpp b/sphaira/source/i18n.cpp index cbc0090..c50a4ad 100644 --- a/sphaira/source/i18n.cpp +++ b/sphaira/source/i18n.cpp @@ -41,6 +41,7 @@ bool init(long index) { u64 languageCode; SetLanguage setLanguage = SetLanguage_ENGB; + std::string lang_name = "en"; switch (index) { case 0: // auto @@ -60,9 +61,9 @@ bool init(long index) { case 9: setLanguage = SetLanguage_NL; break; // "Dutch" case 10: setLanguage = SetLanguage_PT; break; // "Portuguese" case 11: setLanguage = SetLanguage_RU; break; // "Russian" + case 12: lang_name = "se"; break; // "Swedish" } - std::string lang_name; switch (setLanguage) { case SetLanguage_JA: lang_name = "ja"; break; case SetLanguage_FR: lang_name = "fr"; break; @@ -75,7 +76,6 @@ bool init(long index) { case SetLanguage_PT: lang_name = "pt"; break; case SetLanguage_RU: lang_name = "ru"; break; case SetLanguage_ZHTW: lang_name = "zh"; break; - default: lang_name = "en"; break; } const fs::FsPath sdmc_path = "/config/sphaira/i18n/" + lang_name + ".json"; diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 1b71d7f..81239d3 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -215,6 +215,7 @@ MainMenu::MainMenu() { language_items.push_back("Dutch"); language_items.push_back("Portuguese"); language_items.push_back("Russian"); + language_items.push_back("Swedish"); options->AddHeader("Header"_i18n); options->AddSpacer(); From 79da00e09865d190a86c0baf9efada9c55b59295 Mon Sep 17 00:00:00 2001 From: HenryBaby Date: Sat, 21 Dec 2024 17:47:26 +0100 Subject: [PATCH 07/25] Swedish translation (#26) --- assets/romfs/i18n/se.json | 114 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 assets/romfs/i18n/se.json diff --git a/assets/romfs/i18n/se.json b/assets/romfs/i18n/se.json new file mode 100644 index 0000000..9f32065 --- /dev/null +++ b/assets/romfs/i18n/se.json @@ -0,0 +1,114 @@ +{ + "Launch" : "Starta", + "Options" : "Alternativ", + "Homebrew Options" : "Homebrew-alternativ", + "Sort By" : "Sortera efter", + "Sort Options" : "Sorteringsalternativ", + "Updated" : "Uppdaterad", + "Size" : "Storlek", + "Alphabetical" : "Alfabetisk", + "Decending" : "Fallande", + "Ascending" : "Stigande", + "Sort" : "Sortera", + "Order" : "Ordning", + "Info" : "Info", + "Delete" : "Radera", + "Hide Sphaira" : "Dölj Sphaira", + "Are you sure you want to delete " : "Är du säker på att du vill radera ", + "Install Forwarder" : "Installera forwarder", + "WARNING: Installing forwarders will lead to a ban!" : "VARNING: Att installera forwarders leder till en avstängning!", + "Back" : "Tillbaka", + "Install" : "Installera", + "Fs" : "Fs", + "App" : "App", + "Menu" : "Meny", + "Homebrew" : "Homebrew", + "FileBrowser" : "Filbläddrare", + "Open" : "Öppna", + "Theme Options" : "Temaalternativ", + "Select Theme" : "Välj tema", + "Shuffle" : "Blanda", + "Music" : "Musik", + "Show Hidden" : "Visa dolda", + "Folders First" : "Mappar först", + "Hidden Last" : "Dolda sist", + "Yes" : "Ja", + "No" : "Nej", + "Network Options" : "Nätverksalternativ", + "Nxlink" : "Nxlink", + "Check for update" : "Sök efter uppdatering", + "File Options" : "Filalternativ", + "Cut" : "Klipp ut", + "Copy" : "Kopiera", + "Rename" : "Byt namn", + "Advanced Options" : "Avancerade alternativ", + "Create File" : "Skapa fil", + "Create Folder" : "Skapa mapp", + "View as text" : "Visa som text", + "View as text (unfinished)" : "Visa som text (ofärdig)", + "Set Archive Bit" : "Ordna Archive Bit", + "AppStore Options" : "AppStore-alternativ", + "All" : "Alla", + "Games" : "Spel", + "Emulators" : "Emulatorer", + "Tools" : "Verktyg", + "Advanced" : "Avancerat", + "Themes" : "Teman", + "Legacy" : "Legacy", + "Misc" : "Övrigt", + "Downloads" : "Nedladdningar", + "Filter" : "Filter", + "Search" : "Sök", + "Menu Options" : "Menyalternativ", + "Header" : "Rubrik", + "Theme" : "Tema", + "Network" : "Nätverk", + "Logging" : "Loggning", + "Enabled" : "Aktiverad", + "Disabled" : "Avaktiverad", + "Replace hbmenu on exit" : "Ersätt hbmenu vid avslut", + "Misc Options" : "Övriga alternativ", + "Themezer" : "Themezer", + "Irs" : "Irs", + "Web" : "Webb", + "Download" : "Ladda ner", + "Next Page" : "Nästa sida", + "Prev Page" : "Föregående sida", + "Pad " : "Handkontroll ", + " (Unconnected)" : " (Ej ansluten)", + "HandHeld" : "Handhållen", + " (Available)" : " (Tillgänglig)", + "0 (Sideways)" : "0 (Sido)", + "90 (Flat)" : "90 (Platt)", + "180 (-Sideways)" : "180 (-Sido)", + "270 (Upside down)" : "270 (Upp och ner)", + "Grey" : "Grå", + "Ironbow" : "Ironbow", + "Green" : "Grön", + "Red" : "Röd", + "Blue" : "Blå", + "All leds" : "Alla lysdioder", + "Bright group" : "Ljusstark grupp", + "Dim group" : "Dämpad grupp", + "None" : "Ingen", + "Normal image" : "Normal bild", + "Negative image" : "Negativ bild", + "320x240" : "320x240", + "160x120" : "160x120", + "80x60" : "80x60", + "40x30" : "40x30", + "20x15" : "20x15", + "Controller" : "Kontroll", + "Rotation" : "Rotation", + "Colour" : "Färg", + "Light Target" : "Ljusmål", + "Gain" : "Förstärkning", + "Negative Image" : "Negativ bild", + "Format" : "Format", + "Trimming Format" : "Trimformat", + "External Light Filter" : "Extern ljusfilter", + "Load Default" : "Ladda standard", + "No Internet" : "Ingen internetanslutning", + "[Applet Mode]" : "[Applet-läge]", + "Language": "Språk" +} From c8ae2a787225b0eefb6ca98a9c77503393c2beac Mon Sep 17 00:00:00 2001 From: Yorunokyujitsu <164279972+Yorunokyujitsu@users.noreply.github.com> Date: Sun, 22 Dec 2024 01:49:48 +0900 Subject: [PATCH 08/25] Almost all strings for translation. (#32) * Almost all strings for translation * Remove nonexistent strings. --------- Co-authored-by: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> --- assets/romfs/i18n/de.json | 214 +++++++++++----- assets/romfs/i18n/en.json | 320 +++++++++++++++--------- assets/romfs/i18n/es.json | 214 +++++++++++----- assets/romfs/i18n/fr.json | 214 +++++++++++----- assets/romfs/i18n/it.json | 214 +++++++++++----- assets/romfs/i18n/ja.json | 224 ++++++++++++----- assets/romfs/i18n/ko.json | 210 +++++++++++----- assets/romfs/i18n/nl.json | 214 +++++++++++----- assets/romfs/i18n/pt.json | 214 +++++++++++----- assets/romfs/i18n/ru.json | 214 +++++++++++----- assets/romfs/i18n/zh.json | 217 +++++++++++----- sphaira/source/app.cpp | 14 +- sphaira/source/owo.cpp | 15 +- sphaira/source/ui/menus/appstore.cpp | 24 +- sphaira/source/ui/menus/file_viewer.cpp | 3 +- sphaira/source/ui/menus/filebrowser.cpp | 44 ++-- sphaira/source/ui/menus/homebrew.cpp | 2 +- sphaira/source/ui/menus/irs_menu.cpp | 2 +- sphaira/source/ui/menus/main_menu.cpp | 27 +- sphaira/source/ui/menus/themezer.cpp | 14 +- sphaira/source/ui/option_list.cpp | 5 +- sphaira/source/ui/popup_list.cpp | 5 +- sphaira/source/ui/progress_box.cpp | 5 +- sphaira/source/ui/sidebar.cpp | 9 +- 24 files changed, 1839 insertions(+), 799 deletions(-) diff --git a/assets/romfs/i18n/de.json b/assets/romfs/i18n/de.json index e991e62..02cc5b9 100644 --- a/assets/romfs/i18n/de.json +++ b/assets/romfs/i18n/de.json @@ -1,114 +1,208 @@ { - "Launch": "Start", + "[Applet Mode]": "[Applet-Modus]", + "No Internet": "Kein Internet", + "Fs": "Fs", + "App": "App", + "Menu": "Menu", "Options": "Optionen", - "Homebrew Options": "Homebrew-Optionen", + "OK": "", + "Back": "Zurück", + "Select": "", + "Open": "Öffnen", + "Launch": "Start", + "Info": "Info", + "Install": "Installieren", + "Delete": "Löschen", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "Herunterladen", + "Next Page": "Nächste Seite", + "Prev Page": "Vorherige Seite", + "Yes": "Ja", + "No": "Nein", + "Enabled": "Aktiviert", + "Disabled": "Deaktiviert", + "Sort By": "Sortieren nach", "Sort Options": "Sortieroptionen", + "Filter": "Filter", + "Sort": "Sortieren", + "Order": "Befehl", + "Search": "Suchen", "Updated": "Aktualisiert", + "Downloads": "Downloads", "Size": "Größe", "Alphabetical": "Alphabetisch", + "Likes": "", + "ID": "", "Decending": "Absteigend", + "Descending (down)": "Absteigend", + "Desc": "Absteigend", "Ascending": "Aufsteigend", - "Sort": "Sortieren", - "Order": "Befehl", - "Info": "Info", - "Delete": "Löschen", - "Hide Sphaira": "Sphaira verstecken", - "Are you sure you want to delete ": "Mit dem Löschvorgang fortfahren?", - "Install Forwarder": "Forwarder installieren", - "WARNING: Installing forwarders will lead to a ban!": "ACHTUNG: Die Installation von Forwardern führt zu einem Ban!", - "Back": "Zurück", - "Install": "Installieren", - "Fs": "Fs", - "App": "App", - "Menu": "Menu", - "Homebrew": "Homebrew", - "FileBrowser": "DateiBrowser", - "Open": "Öffnen", + "Ascending (Up)": "Aufsteigend", + "Asc": "Aufsteigend", + + "Menu Options": "Menüoptionen", + "Header": "Header", + "Theme": "Theme", "Theme Options": "Themenoptionen", "Select Theme": "Wählen Sie Theme aus", "Shuffle": "Shuffle", "Music": "Musik", - "Show Hidden": "Versteckte anzeigen", - "Folders First": "Ordner zuerst", - "Hidden Last": "Zuletzt versteckt", - "Yes": "Ja", - "No": "Nein", + "Network": "Netzwerk", "Network Options": "Netzwerkoptionen", "Nxlink": "Nxlink", - "Check for update": "Nach Updates suchen", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "Sprache", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Logging", + "Replace hbmenu on exit": "Ersetzen Sie hbmenu beim Beenden", + "Misc": "Sonstiges", + "Misc Options": "Verschiedene Optionen", + "Web": "Web", + + "FileBrowser": "DateiBrowser", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", "File Options": "Dateioptionen", + "Show Hidden": "Versteckte anzeigen", + "Folders First": "Ordner zuerst", + "Hidden Last": "Zuletzt versteckt", "Cut": "Ausschneiden", "Copy": "Kopieren", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "Umbenennen", + "Set New File Name": "", + "Advanced": "Erweitert", "Advanced Options": "Erweiterte Optionen", "Create File": "Datei erstellen", + "Set File Name": "", "Create Folder": "Ordner erstellen", - "View as text": "Als Text anzeigen", + "Set Folder Name": "", "View as text (unfinished)": "Als Text anzeigen (unfertig)", "Set Archive Bit": "Archivbit setzen", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "Homebrew", + "Homebrew Options": "Homebrew-Optionen", + "Hide Sphaira": "Sphaira verstecken", + "Install Forwarder": "Forwarder installieren", + "WARNING: Installing forwarders will lead to a ban!": "ACHTUNG: Die Installation von Forwardern führt zu einem Ban!", + "Installing Forwarder": "", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "", + "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sortieren: %s | Befehl: %s", "AppStore Options": "AppStore-Optionen", "All": "Alle", "Games": "Spiele", "Emulators": "Emulatoren", "Tools": "Werkzeuge", - "Advanced": "Erweitert", "Themes": "Themes", "Legacy": "Legacy", - "Misc": "Sonstiges", - "Downloads": "Downloads", - "Filter": "Filter", - "Search": "Suchen", - "Menu Options": "Menüoptionen", - "Header": "Header", - "Theme": "Theme", - "Network": "Netzwerk", - "Logging": "Logging", - "Enabled": "Aktiviert", - "Disabled": "Deaktiviert", - "Replace hbmenu on exit": "Ersetzen Sie hbmenu beim Beenden", - "Misc Options": "Verschiedene Optionen", - "Themezer": "Themezer", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "Irs", - "Web": "Web", - "Download": "Herunterladen", - "Next Page": "Nächste Seite", - "Prev Page": "Vorherige Seite", + "Ambient Noise Level: ": "", + "Controller": "Controller", "Pad ": "Unterlage ", + " (Available)": " (Verfügbar)", " (Unconnected)": " (Nicht verbunden)", "HandHeld": "Handheld", - " (Available)": " (Verfügbar)", + "Rotation": "Drehung", "0 (Sideways)": "0 (Seitwärts)", "90 (Flat)": "90 (flach)", "180 (-Sideways)": "180 (-Seitwärts)", "270 (Upside down)": "270 (verkehrt herum)", + "Colour": "Farbe", "Grey": "Grau", "Ironbow": "Eisenbogen", "Green": "Grün", "Red": "Rot", "Blue": "Blau", + "Light Target": "Leichtes Ziel", "All leds": "Alle LEDs", "Bright group": "Helle Gruppe", "Dim group": "Dunkle Gruppe", "None": "Keiner", - "Normal image": "Normales Bild", - "Negative image": "Negatives Bild", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80x60", - "40x30": "40x30", - "20x15": "20x15", - "Controller": "Controller", - "Rotation": "Drehung", - "Colour": "Farbe", - "Light Target": "Leichtes Ziel", "Gain": "Gain", "Negative Image": "Negatives Bild", + "Normal image": "Normales Bild", + "Negative image": "Negatives Bild", "Format": "Format", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "Zuschneideformat", "External Light Filter": "Externer Lichtfilter", "Load Default": "Standardoptionen laden", - "No Internet": "Kein Internet", - "[Applet Mode]": "[Applet-Modus]", - "Language": "Sprache" -} + + "Themezer": "Themezer", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "Mit dem Löschvorgang fortfahren?", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/en.json b/assets/romfs/i18n/en.json index 49575d0..e0dc5ba 100644 --- a/assets/romfs/i18n/en.json +++ b/assets/romfs/i18n/en.json @@ -1,114 +1,208 @@ { - "Launch" : "Launch", - "Options" : "Options", - "Homebrew Options" : "Homebrew Options", - "Sort By" : "Sort By", - "Sort Options" : "Sort Options", - "Updated" : "Updated", - "Size" : "Size", - "Alphabetical" : "Alphabetical", - "Decending" : "Decending", - "Ascending" : "Ascending", - "Sort" : "Sort", - "Order" : "Order", - "Info" : "Info", - "Delete" : "Delete", - "Hide Sphaira" : "Hide Sphaira", - "Are you sure you want to delete " : "Are you sure you want to delete ", - "Install Forwarder" : "Install Forwarder", - "WARNING: Installing forwarders will lead to a ban!" : "WARNING: Installing forwarders will lead to a ban!", - "Back" : "Back", - "Install" : "Install", - "Fs" : "Fs", - "App" : "App", - "Menu" : "Menu", - "Homebrew" : "Homebrew", - "FileBrowser" : "FileBrowser", - "Open" : "Open", - "Theme Options" : "Theme Options", - "Select Theme" : "Select Theme", - "Shuffle" : "Shuffle", - "Music" : "Music", - "Show Hidden" : "Show Hidden", - "Folders First" : "Folders First", - "Hidden Last" : "Hidden Last", - "Yes" : "Yes", - "No" : "No", - "Network Options" : "Network Options", - "Nxlink" : "Nxlink", - "Check for update" : "Check for update", - "File Options" : "File Options", - "Cut" : "Cut", - "Copy" : "Copy", - "Rename" : "Rename", - "Advanced Options" : "Create File", - "Create File" : "Create File", - "Create Folder" : "Create Folder", - "View as text" : "View as text", - "View as text (unfinished)" : "View as text (unfinished)", - "Set Archive Bit" : "Set Archive Bit", - "AppStore Options" : "AppStore Options", - "All" : "All", - "Games" : "Games", - "Emulators" : "Emulators", - "Tools" : "Tools", - "Advanced" : "Advanced", - "Themes" : "Themes", - "Legacy" : "Legacy", - "Misc" : "Misc", - "Downloads" : "Downloads", - "Filter" : "Filter", - "Search" : "Search", - "Menu Options" : "Menu Options", - "Header" : "Header", - "Theme" : "Theme", - "Network" : "Network", - "Logging" : "Logging", - "Enabled" : "Enabled", - "Disabled" : "Disabled", - "Replace hbmenu on exit" : "Replace hbmenu on exit", - "Misc Options" : "Misc Options", - "Themezer" : "Themezer", - "Irs" : "Irs", - "Web" : "Web", - "Download" : "Download", - "Next Page" : "Next Page", - "Prev Page" : "Prev Page", - "Pad " : "Pad ", - " (Unconnected)" : " (Unconnected)", - "HandHeld" : "HandHeld", - " (Available)" : " (Available)", - "0 (Sideways)" : "0 (Sideways)", - "90 (Flat)" : "90 (Flat)", - "180 (-Sideways)" : "180 (-Sideways)", - "270 (Upside down)" : "270 (Upside down)", - "Grey" : "Grey", - "Ironbow" : "Ironbow", - "Green" : "Green", - "Red" : "Red", - "Blue" : "Blue", - "All leds" : "All leds", - "Bright group" : "Bright group", - "Dim group" : "Dim group", - "None" : "None", - "Normal image" : "Normal image", - "Negative image" : "Negative image", - "320x240" : "320x240", - "160x120" : "160x120", - "80x60" : "80x60", - "40x30" : "40x30", - "20x15" : "20x15", - "Controller" : "Controller", - "Rotation" : "Rotation", - "Colour" : "Colour", - "Light Target" : "Light Target", - "Gain" : "Gain", - "Negative Image" : "Negative Image", - "Format" : "Format", - "Trimming Format" : "Trimming Format", - "External Light Filter" : "External Light Filter", - "Load Default" : "Load Default", - "No Internet" : "No Internet", - "[Applet Mode]" : "[Applet Mode]", - "Language": "Language" -} + "[Applet Mode]": "[Applet Mode]", + "No Internet": "No Internet", + "Fs": "Fs", + "App": "App", + "Menu": "Menu", + "Options": "Options", + "OK": "OK", + "Back": "Back", + "Select": "Select", + "Open": "Open", + "Launch": "Launch", + "Info": "Info", + "Install": "Install", + "Delete": "Delete", + "Changelog": "Changelog", + "Details": "Details", + "Update": "Update", + "Remove": "Remove", + "Download": "Download", + "Next Page": "Next Page", + "Prev Page": "Prev Page", + "Yes": "Yes", + "No": "No", + "Enabled": "Enabled", + "Disabled": "Disabled", + + "Sort By": "Sort By", + "Sort Options": "Sort Options", + "Filter": "Filter", + "Sort": "Sort", + "Order": "Order", + "Search": "Search", + "Updated": "Updated", + "Downloads": "Downloads", + "Size": "Size", + "Alphabetical": "Alphabetical", + "Likes": "Likes", + "ID": "ID", + "Decending": "Decending", + "Descending (down)": "Descending (down)", + "Desc": "Desc", + "Ascending": "Ascending", + "Ascending (Up)": "Ascending (Up)", + "Asc": "Asc", + + "Menu Options": "Menu Options", + "Header": "Header", + "Theme": "Theme", + "Theme Options": "Theme Options", + "Select Theme": "Select Theme", + "Shuffle": "Shuffle", + "Music": "Music", + "Network": "Network", + "Network Options": "Network Options", + "Nxlink": "Nxlink", + "Nxlink Connected": "Nxlink Connected", + "Nxlink Upload": "Nxlink Upload", + "Nxlink Finished": "Nxlink Finished", + "Language": "Language", + "Auto": "Auto", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Logging", + "Replace hbmenu on exit": "Replace hbmenu on exit", + "Misc": "Misc", + "Misc Options": "Misc Options", + "Web": "Web", + + "FileBrowser": "FileBrowser", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", + "File Options": "File Options", + "Show Hidden": "Show Hidden", + "Folders First": "Folders First", + "Hidden Last": "Hidden Last", + "Cut": "Cut", + "Copy": "Copy", + "Paste": "Paste", + "Paste ": "Paste ", + " file(s)?": " file(s)?", + "Rename": "Rename", + "Set New File Name": "Set New File Name", + "Advanced": "Advanced", + "Advanced Options": "Advanced Options", + "Create File": "Create File", + "Set File Name": "Set File Name", + "Create Folder": "Create Folder", + "Set Folder Name": "Set Folder Name", + "View as text (unfinished)": "View as text (unfinished)", + "Set Archive Bit": "Set Archive Bit", + "Warning! Setting the archive bit cannot be undone!": "Warning! Setting the archive bit cannot be undone!", + "Empty...": "Empty...", + "Open with DayBreak?": "Open with DayBreak?", + "Launch option for: ": "Launch option for: ", + + "Homebrew": "Homebrew", + "Homebrew Options": "Homebrew Options", + "Hide Sphaira": "Hide Sphaira", + "Install Forwarder": "Install Forwarder", + "WARNING: Installing forwarders will lead to a ban!": "WARNING: Installing forwarders will lead to a ban!", + "Installing Forwarder": "Installing Forwarder", + "Creating Program": "Creating Program", + "Creating Control": "Creating Control", + "Creating Meta": "Creating Meta", + "Writing Nca": "Writing Nca", + "Updating ncm databse": "Updating ncm databse", + "Pushing application record": "Pushing application record", + "Installed!": "Installed!", + "Failed to install forwarder": "Failed to install forwarder", + + "AppStore": "AppStore", + "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sort: %s | Order: %s", + "AppStore Options": "AppStore Options", + "All": "All", + "Games": "Games", + "Emulators": "Emulators", + "Tools": "Tools", + "Themes": "Themes", + "Legacy": "Legacy", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "More by Author", + "Leave Feedback": "Leave Feedback", + + "Irs": "Irs", + "Ambient Noise Level: ": "Ambient Noise Level: ", + "Controller": "Controller", + "Pad ": "Pad ", + " (Available)": " (Available)", + " (Unconnected)": " (Unconnected)", + "HandHeld": "HandHeld", + "Rotation": "Rotation", + "0 (Sideways)": "0 (Sideways)", + "90 (Flat)": "90 (Flat)", + "180 (-Sideways)": "180 (-Sideways)", + "270 (Upside down)": "270 (Upside down)", + "Colour": "Colour", + "Grey": "Grey", + "Ironbow": "Ironbow", + "Green": "Green", + "Red": "Red", + "Blue": "Blue", + "Light Target": "Light Target", + "All leds": "All leds", + "Bright group": "Bright group", + "Dim group": "Dim group", + "None": "None", + "Gain": "Gain", + "Negative Image": "Negative Image", + "Normal image": "Normal image", + "Negative image": "Negative image", + "Format": "Format", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", + "Trimming Format": "Trimming Format", + "External Light Filter": "External Light Filter", + "Load Default": "Load Default", + + "Themezer": "Themezer", + "Themezer Options": "Themezer Options", + "Nsfw": "Nsfw", + "Page": "Page", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "Enter Page Number", + "Bad Page": "Bad Page", + "Download theme?": "Download theme?", + + "Installing ": "Installing ", + "Uninstalling ": "Uninstalling ", + "Deleting ": "Deleting ", + "Deleting": "Deleting", + "Pasting ": "Pasting ", + "Pasting": "Pasting", + "Removing ": "Removing ", + "Scanning ": "Scanning ", + "Creating ": "Creating ", + "Copying ": "Copying ", + "Downloading ": "Downloading ", + "Checking MD5": "Checking MD5", + "Loading...": "Loading...", + "Loading": "Loading", + "Empty!": "Empty!", + "Not Ready...": "Not Ready...", + "Error loading page!": "Error loading page!", + "Update avaliable: ": "Update avaliable: ", + "Download update: ": "Download update: ", + "Failed to download update": "Failed to download update", + "Delete Selected files?": "Delete Selected files?", + "Completely remove ": "Completely remove ", + "Are you sure you want to delete ": "Are you sure you want to delete ", + "Are you sure you wish to cancel?": "Are you sure you wish to cancel?" +} \ No newline at end of file diff --git a/assets/romfs/i18n/es.json b/assets/romfs/i18n/es.json index 2424338..213c51a 100644 --- a/assets/romfs/i18n/es.json +++ b/assets/romfs/i18n/es.json @@ -1,114 +1,208 @@ { - "Launch": "Lanzamiento", + "[Applet Mode]": "[Modo subprograma]", + "No Internet": "sin internet", + "Fs": "fs", + "App": "Aplicación", + "Menu": "Menú", "Options": "Opciones", - "Homebrew Options": "Opciones de elaboración casera", + "OK": "", + "Back": "Atrás", + "Select": "", + "Open": "Abierto", + "Launch": "Lanzamiento", + "Info": "Información", + "Install": "Instalar", + "Delete": "Borrar", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "Descargar", + "Next Page": "Página siguiente", + "Prev Page": "Página anterior", + "Yes": "Sí", + "No": "No", + "Enabled": "Activado", + "Disabled": "Desactivado", + "Sort By": "Ordenar por", "Sort Options": "Opciones de clasificación", + "Filter": "Filtrar", + "Sort": "Clasificar", + "Order": "Orden", + "Search": "Buscar", "Updated": "Actualizado", + "Downloads": "Descargas", "Size": "Tamaño", "Alphabetical": "Alfabético", + "Likes": "", + "ID": "", "Decending": "Descendente", + "Descending (down)": "Descendente", + "Desc": "Descendente", "Ascending": "Ascendente", - "Sort": "Clasificar", - "Order": "Orden", - "Info": "Información", - "Delete": "Borrar", - "Hide Sphaira": "Ocultar Sphaira", - "Are you sure you want to delete ": "¿Estás seguro de que quieres eliminar? ", - "Install Forwarder": "Instalar reenviador", - "WARNING: Installing forwarders will lead to a ban!": "ADVERTENCIA: ¡La instalación de reenviadores dará lugar a una prohibición!", - "Back": "Atrás", - "Install": "Instalar", - "Fs": "fs", - "App": "Aplicación", - "Menu": "Menú", - "Homebrew": "cerveza casera", - "FileBrowser": "Explorador de archivos", - "Open": "Abierto", + "Ascending (Up)": "Ascendente", + "Asc": "Ascendente", + + "Menu Options": "Opciones de menú", + "Header": "Encabezamiento", + "Theme": "Tema", "Theme Options": "Opciones de tema", "Select Theme": "Seleccionar tema", "Shuffle": "Barajar", "Music": "Música", + "Network": "Red", + "Network Options": "Opciones de red", + "Nxlink": "Nxlink", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "Idioma", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Explotación florestal", + "Replace hbmenu on exit": "Reemplazar hbmenu al salir", + "Misc": "Varios", + "Misc Options": "Opciones varias", + "Web": "Web", + + "FileBrowser": "Explorador de archivos", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", + "File Options": "Opciones de tema", "Show Hidden": "Mostrar oculto", "Folders First": "Carpetas primero", "Hidden Last": "Oculto último", - "Yes": "Sí", - "No": "No", - "Network Options": "Opciones de red", - "Nxlink": "nxenlace", - "Check for update": "Buscar actualizaciones", - "File Options": "Opciones de archivo", "Cut": "Cortar", "Copy": "Copiar", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "Rebautizar", + "Set New File Name": "", + "Advanced": "Avanzado", "Advanced Options": "Crear archivo", "Create File": "Crear archivo", + "Set File Name": "", "Create Folder": "Crear carpeta", - "View as text": "Ver como texto", + "Set Folder Name": "", "View as text (unfinished)": "Ver como texto (sin terminar)", "Set Archive Bit": "Establecer bit de archivo", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "cerveza casera", + "Homebrew Options": "Opciones de elaboración casera", + "Hide Sphaira": "Ocultar Sphaira", + "Install Forwarder": "Instalar reenviador", + "WARNING: Installing forwarders will lead to a ban!": "ADVERTENCIA: ¡La instalación de reenviadores dará lugar a una prohibición!", + "Installing Forwarder": "", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "", + "Filter: %s | Sort: %s | Order: %s": "Filtrar: %s | Clasificar: %s | Orden: %s", "AppStore Options": "Opciones de la tienda de aplicaciones", "All": "Todo", "Games": "Juegos", "Emulators": "Emuladores", "Tools": "Herramientas", - "Advanced": "Avanzado", "Themes": "Temas", "Legacy": "Legado", - "Misc": "Varios", - "Downloads": "Descargas", - "Filter": "Filtrar", - "Search": "Buscar", - "Menu Options": "Opciones de menú", - "Header": "Encabezamiento", - "Theme": "Tema", - "Network": "Red", - "Logging": "Explotación florestal", - "Enabled": "Activado", - "Disabled": "Desactivado", - "Replace hbmenu on exit": "Reemplazar hbmenu al salir", - "Misc Options": "Opciones varias", - "Themezer": "Temazer", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "irs", - "Web": "Web", - "Download": "Descargar", - "Next Page": "Página siguiente", - "Prev Page": "Página anterior", + "Ambient Noise Level: ": "", + "Controller": "Controlador", "Pad ": "Almohadilla ", + " (Available)": " (Disponible)", " (Unconnected)": " (Desconectado)", "HandHeld": "Portátil", - " (Available)": " (Disponible)", + "Rotation": "Rotación", "0 (Sideways)": "0 (de lado)", "90 (Flat)": "90 (plano)", "180 (-Sideways)": "180 (-de lado)", "270 (Upside down)": "270 (al revés)", + "Colour": "Color", "Grey": "Gris", "Ironbow": "arco de hierro", "Green": "Verde", "Red": "Rojo", "Blue": "Azul", + "Light Target": "Objetivo de luz", "All leds": "todos los leds", "Bright group": "grupo brillante", "Dim group": "grupo tenue", "None": "Ninguno", - "Normal image": "imagen normal", - "Negative image": "Imagen negativa", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80x60", - "40x30": "40x30", - "20x15": "20x15", - "Controller": "Controlador", - "Rotation": "Rotación", - "Colour": "Color", - "Light Target": "Objetivo de luz", "Gain": "Ganar", "Negative Image": "Imagen negativa", + "Normal image": "imagen normal", + "Negative image": "Imagen negativa", "Format": "Formato", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "Formato de recorte", "External Light Filter": "Filtro de luz externo", "Load Default": "Cargar predeterminado", - "No Internet": "sin internet", - "[Applet Mode]": "[Modo subprograma]", - "Language": "Idioma" -} + + "Themezer": "Temazer", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "¿Estás seguro de que quieres eliminar? ", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/fr.json b/assets/romfs/i18n/fr.json index c18d2ad..4e4e594 100644 --- a/assets/romfs/i18n/fr.json +++ b/assets/romfs/i18n/fr.json @@ -1,114 +1,208 @@ { - "Launch": "Exécuter", + "[Applet Mode]": "[Mode Applet]", + "No Internet": "Pas d'Internet", + "Fs": "Fs", + "App": "App.", + "Menu": "Menu", "Options": "Options", - "Homebrew Options": "Options Homebrew", + "OK": "", + "Back": "Retour", + "Select": "", + "Open": "Ouvrir", + "Launch": "Exécuter", + "Info": "Info.", + "Install": "Installer", + "Delete": "Supprimer", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "Télécharger", + "Next Page": "Page Suiv.", + "Prev Page": "Page Préc.", + "Yes": "Oui", + "No": "Non", + "Enabled": "Activé(e)", + "Disabled": "Désactivé(e)", + "Sort By": "Tri Par", "Sort Options": "Options de Tri", + "Filter": "Filtre", + "Sort": "Tri", + "Order": "Ordre", + "Search": "Recherche", "Updated": "Mis à jour", + "Downloads": "Téléchargements", "Size": "Taille", "Alphabetical": "Alphabétique", + "Likes": "", + "ID": "", "Decending": "Décroissant", + "Descending (down)": "Décroissant", + "Desc": "Décroissant", "Ascending": "Croissant", - "Sort": "Tri", - "Order": "Ordre", - "Info": "Info.", - "Delete": "Supprimer", - "Hide Sphaira": "Masquer Sphaira", - "Are you sure you want to delete ": "Êtes-vous sûr de vouloir supprimer ", - "Install Forwarder": "Installer le Forwarder", - "WARNING: Installing forwarders will lead to a ban!": "ATTENTION: L'installation de forwarders entraînera un ban!", - "Back": "Retour", - "Install": "Installer", - "Fs": "Fs", - "App": "App.", - "Menu": "Menu", - "Homebrew": "Homebrew", - "FileBrowser": "Navigateur de Fichiers", - "Open": "Ouvrir", + "Ascending (Up)": "Croissant", + "Asc": "Croissant", + + "Menu Options": "Options des Menus", + "Header": "En-tête", + "Theme": "Thème", "Theme Options": "Options de Thème", "Select Theme": "Choisir un Thème", "Shuffle": "Aléatoire", "Music": "Musique", - "Show Hidden": "Afficher Masqués", - "Folders First": "Dossiers en Premier", - "Hidden Last": "Masqués en Dernier", - "Yes": "Oui", - "No": "Non", + "Network": "Réseau", "Network Options": "Options Réseau", "Nxlink": "Nxlink", - "Check for update": "Vérification d'une mise à jour", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "Langue", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Journalisation", + "Replace hbmenu on exit": "Remplacer hbmenu en sortie", + "Misc": "Divers", + "Misc Options": "Options Diverses", + "Web": "Web", + + "FileBrowser": "Navigateur de Fichiers", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", "File Options": "Options de Fichier", + "Show Hidden": "Afficher Masqués", + "Folders First": "Dossiers en Premier", + "Hidden Last": "Masqués en Dernier", "Cut": "Couper", "Copy": "Copier", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "Renommer", + "Set New File Name": "", + "Advanced": "Avancé", "Advanced Options": "Options Avancées", "Create File": "Créer un Fichier", + "Set File Name": "", "Create Folder": "Créer un Dossier", - "View as text": "Afficher sous forme de texte", + "Set Folder Name": "", "View as text (unfinished)": "Afficher sous forme de texte (inachevé)", "Set Archive Bit": "Définir le Bit d'Archive", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "Homebrew", + "Homebrew Options": "Options Homebrew", + "Hide Sphaira": "Masquer Sphaira", + "Install Forwarder": "Installer le Forwarder", + "WARNING: Installing forwarders will lead to a ban!": "ATTENTION: L'installation de forwarders entraînera un ban!", + "Installing Forwarder": "", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "", + "Filter: %s | Sort: %s | Order: %s": "Filtre: %s | Tri: %s | Ordre: %s", "AppStore Options": "Options de l'AppStore", "All": "Tous", "Games": "Jeux", "Emulators": "Émulateurs", "Tools": "Outils", - "Advanced": "Avancé", "Themes": "Thèmes", "Legacy": "Legacy", - "Misc": "Divers", - "Downloads": "Téléchargements", - "Filter": "Filtre", - "Search": "Recherche", - "Menu Options": "Options des Menus", - "Header": "En-tête", - "Theme": "Thème", - "Network": "Réseau", - "Logging": "Journalisation", - "Enabled": "Activé(e)", - "Disabled": "Désactivé(e)", - "Replace hbmenu on exit": "Remplacer hbmenu en sortie", - "Misc Options": "Options Diverses", - "Themezer": "Themezer", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "Irs", - "Web": "Web", - "Download": "Télécharger", - "Next Page": "Page Suiv.", - "Prev Page": "Page Préc.", + "Ambient Noise Level: ": "", + "Controller": "Contrôleur", "Pad ": "Manette ", + " (Available)": " (Disponible)", " (Unconnected)": " (Non connectée)", "HandHeld": "Portable", - " (Available)": " (Disponible)", + "Rotation": "Rotation", "0 (Sideways)": "0 (Paysage)", "90 (Flat)": "90 (Portrait)", "180 (-Sideways)": "180 (-Paysage)", "270 (Upside down)": "270 (Inversé)", + "Colour": "Couleur", "Grey": "Gris", "Ironbow": "Ironbow", "Green": "Vert", "Red": "Rouge", "Blue": "Bleu", + "Light Target": "Luminosité", "All leds": "Toutes les LED", "Bright group": "Groupe lumineux", "Dim group": "Groupe sombre", "None": "Aucun", - "Normal image": "Image normale", - "Negative image": "Négatif", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80x60", - "40x30": "40x30", - "20x15": "20x15", - "Controller": "Contrôleur", - "Rotation": "Rotation", - "Colour": "Couleur", - "Light Target": "Luminosité", "Gain": "Gain", "Negative Image": "Négatif", + "Normal image": "Image normale", + "Negative image": "Négatif", "Format": "Format", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "Format de Découpe", "External Light Filter": "Filtre de Lumière Externe", "Load Default": "Charger par Défaut", - "No Internet": "Pas d'Internet", - "[Applet Mode]": "[Mode Applet]", - "Language": "Langue" -} + + "Themezer": "Themezer", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "Êtes-vous sûr de vouloir supprimer ", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/it.json b/assets/romfs/i18n/it.json index 8b734cb..97c5421 100644 --- a/assets/romfs/i18n/it.json +++ b/assets/romfs/i18n/it.json @@ -1,114 +1,208 @@ { - "Launch": "Lancia", + "[Applet Mode]": "[Modalità applet]", + "No Internet": "Niente Internet", + "Fs": "Fs", + "App": "App", + "Menu": "Menu", "Options": "Opzioni", - "Homebrew Options": "Opzioni Homebrew", + "OK": "", + "Back": "Indietro", + "Select": "", + "Open": "Apri", + "Launch": "Lancia", + "Info": "Informazioni", + "Install": "Installa", + "Delete": "Elimina", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "Download", + "Next Page": "Pagina successiva", + "Prev Page": "Pagina precedente", + "Yes": "Sì", + "No": "No", + "Enabled": "Abilitato", + "Disabled": "Disabilitato", + "Sort By": "Ordina per", "Sort Options": "Opzioni filtro", + "Filter": "Filtro", + "Sort": "Riordina", + "Order": "Ordina", + "Search": "Ricerca", "Updated": "Aggiornato", + "Downloads": "Download", "Size": "Misurare", "Alphabetical": "Alfabetico", + "Likes": "", + "ID": "", "Decending": "Decrescente", + "Descending (down)": "Decrescente", + "Desc": "Decrescente", "Ascending": "Crescente", - "Sort": "Riordina", - "Order": "Ordina", - "Info": "Informazioni", - "Delete": "Elimina", - "Hide Sphaira": "Nascondi Sphaira", - "Are you sure you want to delete ": "Sei sicuro di voler eliminare? ", - "Install Forwarder": "Installa forwarder", - "WARNING: Installing forwarders will lead to a ban!": "ATTENZIONE: l'installazione di forwarder porterà al ban!", - "Back": "Indietro", - "Install": "Installa", - "Fs": "Fs", - "App": "App", - "Menu": "Menu", - "Homebrew": "Homebrew", - "FileBrowser": "FileBrowser", - "Open": "Apri", + "Ascending (Up)": "Crescente", + "Asc": "Crescente", + + "Menu Options": "Opzioni menu", + "Header": "Intestazione", + "Theme": "Tema", "Theme Options": "Opzioni tema", "Select Theme": "Seleziona tema", "Shuffle": "Mescola", "Music": "Musica", - "Show Hidden": "Mostra nascosto", - "Folders First": "Prima le cartelle", - "Hidden Last": "Ultimo nascosto", - "Yes": "Sì", - "No": "No", + "Network": "Rete", "Network Options": "Opzioni di rete", "Nxlink": "Nxlink", - "Check for update": "Controlla aggiornamenti", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "Lingua", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Logging", + "Replace hbmenu on exit": "Sostituisci hbmenu all'uscita", + "Misc": "Varie", + "Misc Options": "Opzioni varie", + "Web": "Rete", + + "FileBrowser": "FileBrowser", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", "File Options": "Opzioni file", + "Show Hidden": "Mostra nascosto", + "Folders First": "Prima le cartelle", + "Hidden Last": "Ultimo nascosto", "Cut": "Taglia", "Copy": "Copia", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "Rinomina", + "Set New File Name": "", + "Advanced": "Avanzato", "Advanced Options": "Opzioni avanzate", "Create File": "Crea file", + "Set File Name": "", "Create Folder": "Crea cartella", - "View as text": "Visualizza come testo", + "Set Folder Name": "", "View as text (unfinished)": "Visualizza come testo (non finito)", "Set Archive Bit": "Imposta Archive Bit", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "Homebrew", + "Homebrew Options": "Opzioni Homebrew", + "Hide Sphaira": "Nascondi Sphaira", + "Install Forwarder": "Installa forwarder", + "WARNING: Installing forwarders will lead to a ban!": "ATTENZIONE: l'installazione di forwarder porterà al ban!", + "Installing Forwarder": "", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "", + "Filter: %s | Sort: %s | Order: %s": "Filtro: %s | Riordina: %s | Ordina: %s", "AppStore Options": "Opzioni dell'App Store", "All": "Tutto", "Games": "Giochi", "Emulators": "Emulatori", "Tools": "Strumenti", - "Advanced": "Avanzato", "Themes": "Temi", "Legacy": "Legacy", - "Misc": "Varie", - "Downloads": "Download", - "Filter": "Filtro", - "Search": "Ricerca", - "Menu Options": "Opzioni menu", - "Header": "Intestazione", - "Theme": "Tema", - "Network": "Rete", - "Logging": "Logging", - "Enabled": "Abilitato", - "Disabled": "Disabilitato", - "Replace hbmenu on exit": "Sostituisci hbmenu all'uscita", - "Misc Options": "Opzioni varie", - "Themezer": "Themezer", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "Irs", - "Web": "Rete", - "Download": "Download", - "Next Page": "Pagina successiva", - "Prev Page": "Pagina precedente", + "Ambient Noise Level: ": "", + "Controller": "Controller", "Pad ": "Pad ", + " (Available)": " (Disponibile)", " (Unconnected)": " (Non connesso)", "HandHeld": "HandHeld", - " (Available)": " (Disponibile)", + "Rotation": "Rotazione", "0 (Sideways)": "0 (Di lato)", "90 (Flat)": "90 (Piatto)", "180 (-Sideways)": "180 (-Di lato)", "270 (Upside down)": "270 (Capovolto)", + "Colour": "Colore", "Grey": "Grigio", "Ironbow": "Ironbow", "Green": "Verde", "Red": "Rosso", "Blue": "Blu", + "Light Target": "Bersaglio leggero", "All leds": "Tutti i led", "Bright group": "Gruppo brillante", "Dim group": "Gruppo debole", "None": "Nessuno", - "Normal image": "Immagine normale", - "Negative image": "Immagine negativa", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80x60", - "40x30": "40x30", - "20x15": "20×15", - "Controller": "Controller", - "Rotation": "Rotazione", - "Colour": "Colore", - "Light Target": "Bersaglio leggero", "Gain": "Guadagno", "Negative Image": "Immagine negativa", + "Normal image": "Immagine normale", + "Negative image": "Immagine negativa", "Format": "Formato", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "Formato di ritaglio", "External Light Filter": "Filtro luce esterno", "Load Default": "Carica predefinito", - "No Internet": "Niente Internet", - "[Applet Mode]": "[Modalità applet]", - "Language": "Lingua" -} + + "Themezer": "Themezer", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "Sei sicuro di voler eliminare? ", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/ja.json b/assets/romfs/i18n/ja.json index cce3015..c401dcd 100644 --- a/assets/romfs/i18n/ja.json +++ b/assets/romfs/i18n/ja.json @@ -1,114 +1,208 @@ { - "Launch": "起動", + "[Applet Mode]": "[Appletモード]", + "No Internet": "インターネットなし", + "Fs": "ファイル", + "App": "アプリ", + "Menu": "メニュー", "Options": "設定", - "Homebrew Options": "Homebrew設定", + "OK": "確認", + "Back": "戻る", + "Select": "選択", + "Open": "開く", + "Launch": "起動", + "Info": "情報", + "Install": "インストール", + "Delete": "削除", + "Changelog": "リリースノート", + "Details": "詳細", + "Update": "アップデート", + "Remove": "除去", + "Download": "ダウンロード", + "Next Page": "次のページ", + "Prev Page": "前のページ", + "Yes": "はい", + "No": "いいえ", + "Enabled": "", + "Disabled": "", + "Sort By": "並べ替え", "Sort Options": "並べ替え設定", - "Updated": "最近使った順", + "Filter": "フィルター", + "Sort": "並べ替え", + "Order": "順番", + "Search": "検索", + "Updated": "アップデート順", + "Downloads": "ダウンロード順", "Size": "ファイルサイズ", "Alphabetical": "アルファベット順", + "Likes": "いいね順", + "ID": "デベロッパー順", "Decending": "降順", + "Descending (down)": "降順", + "Desc": "降順", "Ascending": "上昇", - "Sort": "並べ替え", - "Order": "順番", - "Info": "情報", - "Delete": "消去", - "Hide Sphaira": "Sphairaを非表示", - "Are you sure you want to delete ": "消去してもよろしいですか ", - "Install Forwarder": "Forwarderのインストール", - "WARNING: Installing forwarders will lead to a ban!": "警告: ForwarderをインストールするとBANされます。", - "Back": "戻る", - "Install": "インストール", - "Fs": "ファイル", - "App": "アプリ", - "Menu": "メニュー", - "Homebrew": "Homebrew", - "FileBrowser": "ファイルブラウザ", - "Open": "開く", + "Ascending (Up)": "上昇", + "Asc": "上昇", + + "Menu Options": "メニュー設定", + "Header": "ヘッダー", + "Theme": "テーマ", "Theme Options": "テーマ設定", "Select Theme": "テーマを選ぶ", "Shuffle": "シャッフル", "Music": "BGM", - "Show Hidden": "非表示ファイルを表示", - "Folders First": "フォルダーを優先", - "Hidden Last": "非表示ファイルを劣後", - "Yes": "はい", - "No": "いいえ", + "Network": "ネットワーク", "Network Options": "ネットワーク設定", "Nxlink": "Nxlink", - "Check for update": "アップデートの確認", + "Nxlink Connected": "Nxlink 接続", + "Nxlink Upload": "Nxlink アップロード", + "Nxlink Finished": "Nxlink 終了", + "Language": "言語", + "Auto": "自動", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "ログの取得", + "Replace hbmenu on exit": "終了時に hbmenu を置き換える", + "Misc": "その他", + "Misc Options": "その他", + "Web": "ウェブブラウザ", + + "FileBrowser": "ファイルブラウザ", + "%zd files": "%zd個のファイル", + "%zd dirs": "%zd個のフォルダー", "File Options": "ファイル設定", + "Show Hidden": "非表示ファイルを表示", + "Folders First": "フォルダーを優先", + "Hidden Last": "非表示ファイルを劣後", "Cut": "切り取り", "Copy": "コピー", + "Paste": "ペースト", + "Paste ": " ", + " file(s)?": "個のファイルをペーストしますか?", "Rename": "名前の変更", - "Advanced Options": "ファイルの作成", + "Set New File Name": "新しい名前を入力", + "Advanced": "高度な", + "Advanced Options": "高度設定", "Create File": "ファイルの作成", + "Set File Name": "名前を入力", "Create Folder": "フォルダーの作成", - "View as text": "テキストとして表示", + "Set Folder Name": "名前を入力", "View as text (unfinished)": "テキストとして表示 (未完成)", "Set Archive Bit": "アーカイブビットの設定", + "Warning! Setting the archive bit cannot be undone!": "警告: アーカイブビットの設定は取り消せません!", + "Empty...": "このフォルダーは空です", + "Open with DayBreak?": "DayBreakで開きますか?", + "Launch option for: ": "起動設定: ", + + "Homebrew": "Homebrew", + "Homebrew Options": "Homebrew設定", + "Hide Sphaira": "Sphairaを非表示", + "Install Forwarder": "Forwarderのインストール", + "WARNING: Installing forwarders will lead to a ban!": "警告: ForwarderをインストールするとBANされます。", + "Installing Forwarder": "Forwarderのインストール中", + "Creating Program": "プログラム作成中", + "Creating Control": "コントロール作成中", + "Creating Meta": "メター作成中", + "Writing Nca": "Nca書き取り中", + "Updating ncm databse": "ncmのDBをアップデート中", + "Pushing application record": "アプリの記録をプッシュ中", + "Installed!": "インストール完了", + "Failed to install forwarder": "Forwarderのインストール失敗", + + "AppStore": "AppStore", + "Filter: %s | Sort: %s | Order: %s": "フィルター: %s | 並べ替え: %s | 順番: %s", "AppStore Options": "AppStoreの設定", "All": "全て", "Games": "ゲーム", "Emulators": "エミュレータ", "Tools": "ツール", - "Advanced": "高度な", "Themes": "テーマ", "Legacy": "レガシー", - "Misc": "その他", - "Downloads": "ダウンロード", - "Filter": "フィルター", - "Search": "検索", - "Menu Options": "メニュー設定", - "Header": "ヘッダー", - "Theme": "テーマ", - "Network": "ネットワーク", - "Logging": "ログの取得", - "Enabled": "有効", - "Disabled": "無効", - "Replace hbmenu on exit": "終了時に hbmenu を置き換える", - "Misc Options": "その他", - "Themezer": "Themezer", + "version: %s": "バージョン: %s", + "updated: %s": "更新日: %s", + "category: %s": "カテゴリー: %s", + "extracted: %.2f MiB": "容量: %.2f MiB", + "app_dls: %s": "ダウンロード: %s", + "More by Author": "ディベロッパーの他のアプリを見る", + "Leave Feedback": "意見を残す", + "Irs": "Joy-Con IRカメラ", - "Web": "ウェブブラウザ", - "Download": "ダウンロード", - "Next Page": "次のページ", - "Prev Page": "前のページ", - "Pad ": "パッド ", + "Ambient Noise Level: ": "ノイズレベル: ", + "Controller": "コントローラー", + "Pad ": "Joy-Con ", + " (Available)": " (利用可能)", " (Unconnected)": " (未接続)", "HandHeld": "ハンドヘルド", - " (Available)": " (利用可能)", - "0 (Sideways)": "0(横)", - "90 (Flat)": "90(フラット)", + "Rotation": "回転", + "0 (Sideways)": "0 (横)", + "90 (Flat)": "90 (フラット)", "180 (-Sideways)": "180 (-横)", - "270 (Upside down)": "270(上下逆さま)", + "270 (Upside down)": "270 (上下逆さま)", + "Colour": "色", "Grey": "グレー", "Ironbow": "アイアンボウ", "Green": "緑", "Red": "赤", "Blue": "青", + "Light Target": "ライトターゲット", "All leds": "すべてのLED", "Bright group": "明るいグループ", "Dim group": "薄暗いグループ", "None": "なし", + "Gain": "増幅", + "Negative Image": "ネガティブなイメージ", "Normal image": "通常画像", "Negative image": "ネガティブなイメージ", + "Format": "解像度", "320x240": "320×240", "160x120": "160×120", "80x60": "80×60", "40x30": "40×30", - "20x15": "20x15", - "Controller": "コントローラー", - "Rotation": "回転", - "Colour": "色", - "Light Target": "ライトターゲット", - "Gain": "得", - "Negative Image": "ネガティブなイメージ", - "Format": "形式", - "Trimming Format": "トリミングフォーマット", + "20x15": "20×15", + "Trimming Format": "トリミングされた解像度", "External Light Filter": "外光フィルター", - "Load Default": "デフォルトをロード", - "No Internet": "インターネットなし", - "[Applet Mode]": "[Appletモード]", - "Language": "言語" -} + "Load Default": "基本設定に戻す", + + "Themezer": "Themezer", + "Themezer Options": "Themezer設定", + "Nsfw": "アダルトテーマ", + "Page": "ページ", + "Page %zu / %zu": "ページ %zu / %zu", + "Enter Page Number": "ページの番号を入力", + "Bad Page": "ページが見つかりません", + "Download theme?": "テーマをインストールしますか?", + + "Installing ": "インストール中 ", + "Uninstalling ": "アンインストール中 ", + "Deleting ": "削除中 ", + "Deleting": "削除中", + "Pasting ": "ペースト中 ", + "Pasting": "ペースト中", + "Removing ": "除去中 ", + "Scanning ": "スキャン中 ", + "Creating ": "作成中 ", + "Copying ": "コピー中 ", + "Downloading ": "ダウンロード中 ", + "Checking MD5": "MD5を確認中 ", + "Loading...": "ロード中", + "Loading": "ロード中", + "Empty!": "何も見つかりません", + "Not Ready...": "準備ができていません", + "Error loading page!": "ページのロードエラー", + "Update avaliable: ": "アップデート可能: ", + "Download update: ": "アップデートをダウンロード: ", + "Failed to download update": "アップデートのダウンロード失敗", + "Delete Selected files?": "本当に削除しますか?", + "Completely remove ": "除去しますか ", + "Are you sure you want to delete ": "消去してもよろしいですか ", + "Are you sure you wish to cancel?": "本当に取り消しますか?" +} \ No newline at end of file diff --git a/assets/romfs/i18n/ko.json b/assets/romfs/i18n/ko.json index adf3464..416cb76 100644 --- a/assets/romfs/i18n/ko.json +++ b/assets/romfs/i18n/ko.json @@ -1,114 +1,208 @@ { - "Launch": "실행", + "[Applet Mode]": "[애플릿 모드]", + "No Internet": "네트워크 연결 없음", + "Fs": "파일 탐색기", + "App": "앱", + "Menu": "메뉴", "Options": "설정", - "Homebrew Options": "홈브류 설정", + "OK": "확인", + "Back": "뒤로", + "Select": "선택", + "Open": "열기", + "Launch": "실행", + "Info": "정보", + "Install": "설치", + "Delete": "삭제", + "Changelog": "변경 내역", + "Details": "상세", + "Update": "업데이트", + "Remove": "제거", + "Download": "다운로드", + "Next Page": "다음 페이지", + "Prev Page": "이전 페이지", + "Yes": "예", + "No": "아니요", + "Enabled": "", + "Disabled": "", + "Sort By": "정렬", "Sort Options": "정렬 설정", + "Filter": "필터", + "Sort": "분류", + "Order": "정렬", + "Search": "검색", "Updated": "업데이트순", + "Downloads": "다운로드순", "Size": "크기순", "Alphabetical": "알파벳순", + "Likes": "좋아요순", + "ID": "작성자순", "Decending": "내림차순", + "Descending (down)": "내림차순", + "Desc": "내림차순", "Ascending": "오름차순", - "Sort": "분류", - "Order": "정렬", - "Info": "정보", - "Delete": "삭제", - "Hide Sphaira": "Sphaira 숨기기", - "Are you sure you want to delete ": "정말 삭제하시겠습니까? ", - "Install Forwarder": "바로가기 설치", - "WARNING: Installing forwarders will lead to a ban!": "주의: 바로가기 설치시 BAN 위험이 있습니다!", - "Back": "뒤로", - "Install": "설치", - "Fs": "파일 탐색기", - "App": "앱", - "Menu": "메뉴", - "Homebrew": "홈브류", - "FileBrowser": "파일 탐색기", - "Open": "열기", + "Ascending (Up)": "오름차순", + "Asc": "오름차순", + + "Menu Options": "메뉴", + "Header": "헤더", + "Theme": "테마", "Theme Options": "테마 설정", "Select Theme": "테마 선택", "Shuffle": "셔플", "Music": "BGM", - "Show Hidden": "숨겨진 항목 표시", - "Folders First": "폴더 우선 정렬", - "Hidden Last": "숨겨진 항목 후순 정렬", - "Yes": "예", - "No": "아니요", + "Network": "네트워크", "Network Options": "네트워크 설정", "Nxlink": "Nxlink", - "Check for update": "업데이트 확인", + "Nxlink Connected": "Nxlink 연결됨", + "Nxlink Upload": "Nxlink 업로드", + "Nxlink Finished": "Nxlink 종료됨", + "Language": "언어", + "Auto": "자동", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "로깅", + "Replace hbmenu on exit": "hbmenu를 교체", + "Misc": "기타", + "Misc Options": "기타", + "Web": "웹 브라우저", + + "FileBrowser": "파일 탐색기", + "%zd files": "%zd개의 파일", + "%zd dirs": "%zd개의 폴더", "File Options": "파일 설정", + "Show Hidden": "숨겨진 항목 표시", + "Folders First": "폴더 우선 정렬", + "Hidden Last": "숨겨진 항목 후순 정렬", "Cut": "잘라내기", "Copy": "복사", + "Paste": "붙여넣기", + "Paste ": " ", + " file(s)?": "개 항목을 붙여넣으시겠습니까?", "Rename": "이름 바꾸기", + "Set New File Name": "새 파일명 입력", + "Advanced": "고급", "Advanced Options": "고급 설정", "Create File": "파일 생성", + "Set File Name": "파일명 입력", "Create Folder": "새 폴더", - "View as text": "텍스트로 보기", + "Set Folder Name": "폴더명 입력", "View as text (unfinished)": "텍스트로 보기 (미완성)", "Set Archive Bit": "아카이브 비트 설정", + "Warning! Setting the archive bit cannot be undone!": "경고: 아카이브 비트 설정은 취소할 수 없습니다!", + "Empty...": "비어있습니다...", + "Open with DayBreak?": "DayBreak로 여시겠습니까?", + "Launch option for: ": "실행 옵션: ", + + "Homebrew": "홈브류", + "Homebrew Options": "홈브류 설정", + "Hide Sphaira": "Sphaira 숨기기", + "Install Forwarder": "바로가기 설치", + "WARNING: Installing forwarders will lead to a ban!": "주의: 바로가기 설치시 BAN 위험이 있습니다!", + "Installing Forwarder": "바로가기 설치중...", + "Creating Program": "프로그램 작성중...", + "Creating Control": "컨트롤 작성중...", + "Creating Meta": "메타 작성중...", + "Writing Nca": "Nca 쓰는중...", + "Updating ncm databse": "ncm 데이터베이스 업데이트중...", + "Pushing application record": "응용 프로그램 기록 푸시중...", + "Installed!": "설치 완료!", + "Failed to install forwarder": "바로가기 설치 실패", + + "AppStore": "앱스토어", + "Filter: %s | Sort: %s | Order: %s": "필터: %s | 분류: %s | 정렬: %s", "AppStore Options": "앱스토어 설정", "All": "전체", "Games": "게임", "Emulators": "에뮬레이터", "Tools": "도구", - "Advanced": "고급", "Themes": "테마", "Legacy": "레거시", - "Misc": "기타", - "Downloads": "다운로드순", - "Filter": "필터", - "Search": "검색", - "Menu Options": "메뉴", - "Header": "헤더", - "Theme": "테마", - "Network": "네트워크", - "Logging": "로깅", - "Enabled": "", - "Disabled": "", - "Replace hbmenu on exit": "종료 시 hbmenu 교체", - "Misc Options": "기타", - "Themezer": "Themezer", + "version: %s": "버전: %s", + "updated: %s": "갱신일: %s", + "category: %s": "카테고리: %s", + "extracted: %.2f MiB": "용량: %.2f MiB", + "app_dls: %s": "다운로드 횟수: %s", + "More by Author": "개발자의 다른 앱 더보기", + "Leave Feedback": "피드백 남기기", + "Irs": "Joy-Con IR 카메라", - "Web": "웹 브라우저", - "Download": "다운로드", - "Next Page": "다음 페이지", - "Prev Page": "이전 페이지", - "Pad ": "Joy-Con ", - " (Unconnected)": " (연결 없음)", - "HandHeld": "본체 연결", + "Ambient Noise Level: ": "노이즈 레벨: ", + "Controller": "컨트롤러", + "Pad ": "조이콘 ", " (Available)": " (사용 가능)", + " (Unconnected)": " (연결 없음)", + "HandHeld": "- 본체 연결", + "Rotation": "화면 회전", "0 (Sideways)": "0 (좌회전)", "90 (Flat)": "90 (정방향)", "180 (-Sideways)": "180 (우회전)", "270 (Upside down)": "270 (역전)", + "Colour": "컬러 팔레트", "Grey": "그레이", "Ironbow": "아이언보우", "Green": "그린", "Red": "레드", "Blue": "블루", + "Light Target": "반사 표적", "All leds": "모든 LED 켜기", "Bright group": "Bright LED 켜기", "Dim group": "Dim LED 켜기", "None": "LED 끄기", + "Gain": "대비", + "Negative Image": "화상 이미지", "Normal image": "일반", "Negative image": "반전", + "Format": "해상도", "320x240": "320×240", "160x120": "160×120", "80x60": "80×60", "40x30": "40×30", "20x15": "20×15", - "Controller": "컨트롤러", - "Rotation": "화면 회전", - "Colour": "팔레트", - "Light Target": "반사 표적", - "Gain": "대비", - "Negative Image": "화상 이미지", - "Format": "해상도", "Trimming Format": "트리밍 해상도", "External Light Filter": "외부 조명 필터", "Load Default": "기본값으로 설정", - "No Internet": "네트워크 연결 없음", - "[Applet Mode]": "[애플릿 모드]", - "Language": "언어" -} + + "Themezer": "Themezer", + "Themezer Options": "Themezer 설정", + "Nsfw": "선정성 테마", + "Page": "페이지", + "Page %zu / %zu": "페이지 %zu / %zu", + "Enter Page Number": "페이지 번호 입력", + "Bad Page": "잘못된 페이지", + "Download theme?": "테마를 내려받으시겠습니까?", + + "Installing ": "설치중... ", + "Uninstalling ": "설치 제거중... ", + "Deleting ": "삭제중... ", + "Deleting": "삭제중...", + "Pasting ": "붙여넣는중... ", + "Pasting": "붙여넣는중...", + "Removing ": "제거중... ", + "Scanning ": "스캔중... ", + "Creating ": "작성중... ", + "Copying ": "복사중... ", + "Downloading ": "다운로드중... ", + "Checking MD5": "MD5 확인중... ", + "Loading...": "로딩중...", + "Loading": "로딩중...", + "Empty!": "찾을 수 없습니다!", + "Not Ready...": "준비되지 않았습니다...", + "Error loading page!": "페이지 로딩 오류!", + "Update avaliable: ": "업데이트 가능: ", + "Download update: ": "업데이트 다운로드: ", + "Failed to download update": "업데이트 다운로드 실패!", + "Delete Selected files?": "정말 삭제하시겠습니까?", + "Completely remove ": "제거하시겠습니까 ", + "Are you sure you want to delete ": "sdmc:", + "Are you sure you wish to cancel?": "정말 취소하시겠습니까?" +} \ No newline at end of file diff --git a/assets/romfs/i18n/nl.json b/assets/romfs/i18n/nl.json index 47ec9e3..2fb541d 100644 --- a/assets/romfs/i18n/nl.json +++ b/assets/romfs/i18n/nl.json @@ -1,114 +1,208 @@ { - "Launch": "Launch", + "[Applet Mode]": "[Applet-modus]", + "No Internet": "Geen internet", + "Fs": "Fs", + "App": "App", + "Menu": "Menu", "Options": "Opties", - "Homebrew Options": "Homebrew-opties", + "OK": "", + "Back": "Terug", + "Select": "", + "Open": "Open", + "Launch": "Launch", + "Info": "Info", + "Install": "Installeren", + "Delete": "Verwijderen", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "Downloaden", + "Next Page": "Volgende pagina", + "Prev Page": "Vorige pagina", + "Yes": "Ja", + "No": "Nee", + "Enabled": "Ingeschakeld", + "Disabled": "Gehandicapt", + "Sort By": "Sorteer op", "Sort Options": "Sorteeropties", + "Filter": "Filter", + "Sort": "Soort", + "Order": "Volgorde", + "Search": "Zoekopdracht", "Updated": "Bijgewerkt", + "Downloads": "Downloads", "Size": "Maat", "Alphabetical": "Alfabetisch", + "Likes": "", + "ID": "", "Decending": "Aflopend", + "Descending (down)": "Aflopend", + "Desc": "Aflopend", "Ascending": "Oplopend", - "Sort": "Soort", - "Order": "Volgorde", - "Info": "Info", - "Delete": "Verwijderen", - "Hide Sphaira": "Verberg Sphaira", - "Are you sure you want to delete ": "Weet u zeker dat u wilt verwijderen ", - "Install Forwarder": "Forwarder installeren", - "WARNING: Installing forwarders will lead to a ban!": "WAARSCHUWING: Het installeren van forwarders leidt tot een ban!", - "Back": "Terug", - "Install": "Installeren", - "Fs": "Fs", - "App": "App", - "Menu": "Menu", - "Homebrew": "Zelf brouwen", - "FileBrowser": "Bestandsbrowser", - "Open": "Open", + "Ascending (Up)": "Oplopend", + "Asc": "Oplopend", + + "Menu Options": "Menu-opties", + "Header": "Koptekst", + "Theme": "Thema", "Theme Options": "Thema Opties", "Select Theme": "Selecteer Thema", "Shuffle": "Schudden", "Music": "Muziek", - "Show Hidden": "Toon verborgen", - "Folders First": "Mappen eerst", - "Hidden Last": "Verborgen laatste", - "Yes": "Ja", - "No": "Nee", + "Network": "Netwerk", "Network Options": "Netwerkopties", "Nxlink": "Nxlink", - "Check for update": "Controleer op update", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "Taal", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Loggen", + "Replace hbmenu on exit": "Vervang hbmenu bij afsluiten", + "Misc": "Diversen", + "Misc Options": "Diverse opties", + "Web": "Web", + + "FileBrowser": "Bestandsbrowser", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", "File Options": "Bestandsopties", + "Show Hidden": "Toon verborgen", + "Folders First": "Mappen eerst", + "Hidden Last": "Verborgen laatste", "Cut": "Snee", "Copy": "Kopiëren", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "Hernoemen", + "Set New File Name": "", + "Advanced": "Geavanceerd", "Advanced Options": "Bestand maken", "Create File": "Bestand maken", + "Set File Name": "", "Create Folder": "Map maken", - "View as text": "Bekijk als tekst", + "Set Folder Name": "", "View as text (unfinished)": "Bekijk als tekst (onvoltooid)", "Set Archive Bit": "Archiefbit instellen", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "Zelf brouwen", + "Homebrew Options": "Homebrew-opties", + "Hide Sphaira": "Verberg Sphaira", + "Install Forwarder": "Forwarder installeren", + "WARNING: Installing forwarders will lead to a ban!": "WAARSCHUWING: Het installeren van forwarders leidt tot een ban!", + "Installing Forwarder": "", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "", + "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Soort: %s | Volgorde: %s", "AppStore Options": "AppStore-opties", "All": "Alle", "Games": "Spellen", "Emulators": "Emulators", "Tools": "Hulpmiddelen", - "Advanced": "Geavanceerd", "Themes": "Thema's", "Legacy": "Nalatenschap", - "Misc": "Diversen", - "Downloads": "Downloads", - "Filter": "Filter", - "Search": "Zoekopdracht", - "Menu Options": "Menu-opties", - "Header": "Koptekst", - "Theme": "Thema", - "Network": "Netwerk", - "Logging": "Loggen", - "Enabled": "Ingeschakeld", - "Disabled": "Gehandicapt", - "Replace hbmenu on exit": "Vervang hbmenu bij afsluiten", - "Misc Options": "Diverse opties", - "Themezer": "Themamaker", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "Ir", - "Web": "Web", - "Download": "Downloaden", - "Next Page": "Volgende pagina", - "Prev Page": "Vorige pagina", + "Ambient Noise Level: ": "", + "Controller": "Controleur", "Pad ": "Pad ", + " (Available)": " (Beschikbaar)", " (Unconnected)": " (Niet verbonden)", "HandHeld": "Handbediende", - " (Available)": " (Beschikbaar)", + "Rotation": "Rotatie", "0 (Sideways)": "0 (zijwaarts)", "90 (Flat)": "90 (plat)", "180 (-Sideways)": "180 (-zijwaarts)", "270 (Upside down)": "270 (ondersteboven)", + "Colour": "Kleur", "Grey": "Grijs", "Ironbow": "Ijzerboog", "Green": "Groente", "Red": "Rood", "Blue": "Blauw", + "Light Target": "Licht doel", "All leds": "Alle leds", "Bright group": "Heldere groep", "Dim group": "Dim groep", "None": "Geen", - "Normal image": "Normaal beeld", - "Negative image": "Negatief beeld", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80x60", - "40x30": "40x30", - "20x15": "20x15", - "Controller": "Controleur", - "Rotation": "Rotatie", - "Colour": "Kleur", - "Light Target": "Licht doel", "Gain": "Verdienen", "Negative Image": "Negatief beeld", + "Normal image": "Normaal beeld", + "Negative image": "Negatief beeld", "Format": "Formaat", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "Trimformaat", "External Light Filter": "Extern lichtfilter", "Load Default": "Standaard laden", - "No Internet": "Geen internet", - "[Applet Mode]": "[Applet-modus]", - "Language": "Taal" -} + + "Themezer": "Themamaker", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "Weet u zeker dat u wilt verwijderen ", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/pt.json b/assets/romfs/i18n/pt.json index d8460c4..22d3548 100644 --- a/assets/romfs/i18n/pt.json +++ b/assets/romfs/i18n/pt.json @@ -1,114 +1,208 @@ { - "Launch": "Iniciar", + "[Applet Mode]": "[Modo Applet]", + "No Internet": "Sem Internet", + "Fs": "Fs", + "App": "Aplicativo", + "Menu": "Menu", "Options": "Opções", - "Homebrew Options": "Opções do Homebrew", + "OK": "", + "Back": "Voltar", + "Select": "", + "Open": "Abrir", + "Launch": "Iniciar", + "Info": "Informações", + "Install": "Instalar", + "Delete": "Excluir", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "Download", + "Next Page": "Próxima página", + "Prev Page": "Página anterior", + "Yes": "Sim", + "No": "Não", + "Enabled": "Habilitado", + "Disabled": "Desabilitado", + "Sort By": "Ordenar por", "Sort Options": "Opções de classificação", + "Filter": "Filtro", + "Sort": "Organizar", + "Order": "Ordem", + "Search": "Procurar", "Updated": "Atualizado", + "Downloads": "Downloads", "Size": "Tamanho", "Alphabetical": "Alfabético", + "Likes": "", + "ID": "", "Decending": "Decrescente", + "Descending (down)": "Decrescente", + "Desc": "Decrescente", "Ascending": "Ascendente", - "Sort": "Organizar", - "Order": "Ordem", - "Info": "Informações", - "Delete": "Excluir", - "Hide Sphaira": "Esconder Sphaira", - "Are you sure you want to delete ": "Excluir ", - "Install Forwarder": "Instalar forwarder", - "WARNING: Installing forwarders will lead to a ban!": "AVISO: Isso pode resultar em um banimento!", - "Back": "Voltar", - "Install": "Instalar", - "Fs": "Fs", - "App": "Aplicativo", - "Menu": "Menu", - "Homebrew": "Homebrew", - "FileBrowser": "Navegador de arquivos", - "Open": "Abrir", + "Ascending (Up)": "Ascendente", + "Asc": "Ascendente", + + "Menu Options": "Opções do menu", + "Header": "Cabeçalho", + "Theme": "Tema", "Theme Options": "Opções de tema", "Select Theme": "Selecionar tema", "Shuffle": "Embaralhar", "Music": "Música", - "Show Hidden": "Mostrar oculto", - "Folders First": "Pastas primeiro", - "Hidden Last": "Oculto por último", - "Yes": "Sim", - "No": "Não", + "Network": "Rede", "Network Options": "Opções de rede", "Nxlink": "Nxlink", - "Check for update": "Verificar se há atualização", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "Idioma", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Logging", + "Replace hbmenu on exit": "Substitua hbmenu ao sair", + "Misc": "Diversos", + "Misc Options": "Opções diversas", + "Web": "Rede", + + "FileBrowser": "Navegador de arquivos", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", "File Options": "Opções de arquivo", + "Show Hidden": "Mostrar oculto", + "Folders First": "Pastas primeiro", + "Hidden Last": "Oculto por último", "Cut": "Cortar", "Copy": "Copiar", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "Renomear", + "Set New File Name": "", + "Advanced": "Avançado", "Advanced Options": "Criar arquivo", "Create File": "Criar arquivo", + "Set File Name": "", "Create Folder": "Criar pasta", - "View as text": "Ver como texto", + "Set Folder Name": "", "View as text (unfinished)": "Ver como texto (inacabado)", "Set Archive Bit": "Definir bit de arquivo", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "Homebrew", + "Homebrew Options": "Opções do Homebrew", + "Hide Sphaira": "Esconder Sphaira", + "Install Forwarder": "Instalar forwarder", + "WARNING: Installing forwarders will lead to a ban!": "AVISO: Isso pode resultar em um banimento!", + "Installing Forwarder": "", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "", + "Filter: %s | Sort: %s | Order: %s": "Filtro: %s | Organizar: %s | Ordem: %s", "AppStore Options": "Opções da AppStore", "All": "Todos", "Games": "Jogos", "Emulators": "Emuladores", "Tools": "Ferramentas", - "Advanced": "Avançado", "Themes": "Temas", "Legacy": "Legado", - "Misc": "Diversos", - "Downloads": "Downloads", - "Filter": "Filtro", - "Search": "Procurar", - "Menu Options": "Opções do menu", - "Header": "Cabeçalho", - "Theme": "Tema", - "Network": "Rede", - "Logging": "Logging", - "Enabled": "Habilitado", - "Disabled": "Desabilitado", - "Replace hbmenu on exit": "Substitua hbmenu ao sair", - "Misc Options": "Opções diversas", - "Themezer": "Themezer", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "Irs", - "Web": "Rede", - "Download": "Download", - "Next Page": "Próxima página", - "Prev Page": "Página anterior", + "Ambient Noise Level: ": "", + "Controller": "Controle", "Pad ": "Pad ", + " (Available)": " (Disponível)", " (Unconnected)": " (Desconectado)", "HandHeld": "Portátil", - " (Available)": " (Disponível)", + "Rotation": "Rotação", "0 (Sideways)": "0 (Lateralmente)", "90 (Flat)": "90 (plano)", "180 (-Sideways)": "180 (-Lateralmente)", "270 (Upside down)": "270 (De cabeça para baixo)", + "Colour": "Cor", "Grey": "Cinza", "Ironbow": "Arco de ferro", "Green": "Verde", "Red": "Vermelho", "Blue": "Azul", + "Light Target": "Alvo leve", "All leds": "Todos os LEDs", "Bright group": "Grupo claro", "Dim group": "Grupo escuro", "None": "Nenhum", - "Normal image": "Imagem normal", - "Negative image": "Imagem negativa", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80x60", - "40x30": "40x30", - "20x15": "20x15", - "Controller": "Controle", - "Rotation": "Rotação", - "Colour": "Cor", - "Light Target": "Alvo leve", "Gain": "Ganho", "Negative Image": "Imagem negativa", + "Normal image": "Imagem normal", + "Negative image": "Imagem negativa", "Format": "Formatar", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "Formato de corte", "External Light Filter": "Filtro de luz externo", "Load Default": "Carregar padrão", - "No Internet": "Sem Internet", - "[Applet Mode]": "[Modo Applet]", - "Language": "Idioma" -} + + "Themezer": "Themezer", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "Excluir ", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/ru.json b/assets/romfs/i18n/ru.json index d5696c7..34cdd7a 100644 --- a/assets/romfs/i18n/ru.json +++ b/assets/romfs/i18n/ru.json @@ -1,114 +1,208 @@ { + "[Applet Mode]": "[Режим апплета]", + "No Internet": "Нет Интернета", + "Fs": "Фс", + "App": "Приложение", + "Menu": "Меню", + "Options": "Параметры темы", + "OK": "", + "Back": "Назад", + "Select": "", + "Open": "Открыть", "Launch": "Запуск", - "Options": "Параметры", - "Homebrew Options": "Параметры Homebrew", + "Info": "Информация", + "Install": "Установить", + "Delete": "Удалить", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "Скачать", + "Next Page": "Следующая страница", + "Prev Page": "Предыдущая страница", + "Yes": "Да", + "No": "Нет", + "Enabled": "Включено", + "Disabled": "Отключено", + "Sort By": "Сортировать по", "Sort Options": "Параметры сортировки", + "Filter": "Фильтр", + "Sort": "Сортировать", + "Order": "Порядок", + "Search": "Поиск", "Updated": "Обновлено", + "Downloads": "Загрузки", "Size": "Размер", "Alphabetical": "По наименованию", + "Likes": "", + "ID": "", "Decending": "По убыванию", + "Descending (down)": "По убыванию", + "Desc": "По убыванию", "Ascending": "По возрастанию", - "Sort": "Сортировать", - "Order": "Порядок", - "Info": "Информация", - "Delete": "Удалить", - "Hide Sphaira": "Скрыть Sphaira", - "Are you sure you want to delete ": "Вы уверены, что хотите удалить ", - "Install Forwarder": "Установить форвардер", - "WARNING: Installing forwarders will lead to a ban!": "ВНИМАНИЕ: Установка форвардеров приведет к бану!", - "Back": "Назад", - "Install": "Установить", - "Fs": "Фс", - "App": "Приложение", - "Menu": "Меню", - "Homebrew": "Homebrew", - "FileBrowser": "Файловый менеджер", - "Open": "Открыть", + "Ascending (Up)": "По возрастанию", + "Asc": "По возрастанию", + + "Menu Options": "Параметры меню", + "Header": "Заголовок", + "Theme": "Тема", "Theme Options": "Параметры темы", "Select Theme": "Выберите тему", "Shuffle": "Перетасовать", "Music": "Музыка", - "Show Hidden": "Показать скрытые", - "Folders First": "Папки в первую очередь", - "Hidden Last": "Скрытые в последнюю очередь", - "Yes": "Да", - "No": "Нет", + "Network": "Сеть", "Network Options": "Параметры сети", "Nxlink": "Nxlink", - "Check for update": "Проверить наличие обновлений", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "Язык", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "Журналирование", + "Replace hbmenu on exit": "Заменить hbmenu при выходе", + "Misc": "Прочее", + "Misc Options": "Прочие параметры", + "Web": "Интернет", + + "FileBrowser": "Файловый менеджер", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", "File Options": "Параметры файла", + "Show Hidden": "Показать скрытые", + "Folders First": "Папки в первую очередь", + "Hidden Last": "Скрытые в последнюю очередь", "Cut": "Вырезать", "Copy": "Копировать", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "Переименовать", + "Set New File Name": "", + "Advanced": "Продвинутые", "Advanced Options": "Расширенные параметры", "Create File": "Создать файл", + "Set File Name": "", "Create Folder": "Создать папку", - "View as text": "Посмотреть как текст", + "Set Folder Name": "", "View as text (unfinished)": "Посмотреть как текст (незакончено)", "Set Archive Bit": "Установить Archive Bit", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "Homebrew", + "Homebrew Options": "Параметры Homebrew", + "Hide Sphaira": "Скрыть Sphaira", + "Install Forwarder": "Установить форвардер", + "WARNING: Installing forwarders will lead to a ban!": "ВНИМАНИЕ: Установка форвардеров приведет к бану!", + "Installing Forwarder": "Установить форвардер", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "", + "Filter: %s | Sort: %s | Order: %s": "Фильтр: %s | Сортировать: %s | Порядок: %s", "AppStore Options": "Параметры магазина приложений", "All": "Все", "Games": "Игры", "Emulators": "Эмуляторы", "Tools": "Инструменты", - "Advanced": "Продвинутые", "Themes": "Темы", "Legacy": "Легаси", - "Misc": "Прочее", - "Downloads": "Загрузки", - "Filter": "Фильтр", - "Search": "Поиск", - "Menu Options": "Параметры меню", - "Header": "Заголовок", - "Theme": "Тема", - "Network": "Сеть", - "Logging": "Журналирование", - "Enabled": "Включено", - "Disabled": "Отключено", - "Replace hbmenu on exit": "Заменить hbmenu при выходе", - "Misc Options": "Прочие параметры", - "Themezer": "Themezer", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "Irs", - "Web": "Интернет", - "Download": "Скачать", - "Next Page": "Следующая страница", - "Prev Page": "Предыдущая страница", + "Ambient Noise Level: ": "", + "Controller": "Контроллер", "Pad ": "Pad ", + " (Available)": " (Доступно)", " (Unconnected)": " (Не подключено)", "HandHeld": "Портативный", - " (Available)": " (Доступно)", + "Rotation": "Вращение", "0 (Sideways)": "0 (набок)", "90 (Flat)": "90 (ровно)", "180 (-Sideways)": "180 (-вбок)", "270 (Upside down)": "270 (перевернуто)", + "Colour": "Цвет", "Grey": "Серый", "Ironbow": "Стальной", "Green": "Зеленый", "Red": "Красный", "Blue": "Синий", + "Light Target": "Световая мишень", "All leds": "Все светодиоды", "Bright group": "Яркая группа", "Dim group": "Тусклая группа", "None": "Никто", - "Normal image": "Обычное изображение", - "Negative image": "Негативное изображение", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80х60", - "40x30": "40x30", - "20x15": "20x15", - "Controller": "Контроллер", - "Rotation": "Вращение", - "Colour": "Цвет", - "Light Target": "Световая мишень", "Gain": "Прирост", "Negative Image": "Негативное изображение", + "Normal image": "Обычное изображение", + "Negative image": "Негативное изображение", "Format": "Формат", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "Формат обрезки", "External Light Filter": "Внешний светофильтр", "Load Default": "Загрузить умолчания", - "No Internet": "Нет Интернета", - "[Applet Mode]": "[Режим апплета]", - "Language": "Язык" -} + + "Themezer": "Themezer", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "Вы уверены, что хотите удалить ", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/zh.json b/assets/romfs/i18n/zh.json index 41c4fef..3dfdd31 100644 --- a/assets/romfs/i18n/zh.json +++ b/assets/romfs/i18n/zh.json @@ -1,115 +1,208 @@ { - "Launch": "启动", + "[Applet Mode]": "[小程序模式]", + "No Internet": "网络未连接", + "Fs": "文件系统", + "App": "插件", + "Menu": "菜单", "Options": "选项", - "Homebrew Options": "插件选项", + "OK": "", + "Back": "返回", + "Select": "", + "Open": "打开", + "Launch": "启动", + "Info": "信息", + "Install": "安装", + "Delete": "删除", + "Changelog": "", + "Details": "", + "Update": "", + "Remove": "", + "Download": "下载", + "Next Page": "下一页", + "Prev Page": "上一页", + "Yes": "是", + "No": "否", + "Enabled": "启用", + "Disabled": "禁用", + "Sort By": "排序方式", "Sort Options": "排序选项", + "Filter": "筛选", + "Sort": "排序", + "Order": "顺序", + "Search": "搜索", "Updated": "最近使用", + "Downloads": "下载", "Size": "大小", "Alphabetical": "按字母顺序", + "Likes": "", + "ID": "", "Decending": "降序", + "Descending (down)": "降序", + "Desc": "降序", "Ascending": "升序", - "Sort": "排序", - "Order": "顺序", - "Info": "信息", - "Delete": "删除", - "Hide Sphaira": "在插件列表中隐藏Sphaira", - "Are you sure you want to delete ": "您确定要删除吗 ", - "Install Forwarder": "安装前端应用", - "WARNING: Installing forwarders will lead to a ban!": "警告:安装前端应用可能导致ban机!", - "Back": "返回", - "Install": "安装", - "Fs": "文件系统", - "App": "插件", - "Menu": "菜单", - "Homebrew": "插件列表", - "AppStore": "插件商店", - "FileBrowser": "文件浏览", - "Open": "打开", + "Ascending (Up)": "升序", + "Asc": "升序", + + "Menu Options": "菜单选项", + "Header": "标题", + "Theme": "主题", "Theme Options": "主题选项", "Select Theme": "选择主题", "Shuffle": "随机播放", "Music": "音乐", + "Network": "网络", + "Network Options": "网络选项", + "Nxlink": "Nxlink", + "Nxlink Connected": "", + "Nxlink Upload": "", + "Nxlink Finished": "", + "Language": "语言", + "Auto": "", + "English": "English", + "Japanese": "日本語", + "French": "Français", + "German": "Deutsch", + "Italian": "Italiano", + "Spanish": "Español", + "Chinese": "中文", + "Korean": "한국어", + "Dutch": "Dutch", + "Portuguese": "Português", + "Russian": "Русский", + "Logging": "日志", + "Replace hbmenu on exit": "退出后用Sphaira替换hbmenu", + "Misc": "杂项", + "Misc Options": "杂项设置", + "Web": "网页浏览器", + + "FileBrowser": "文件浏览", + "%zd files": "%zd files", + "%zd dirs": "%zd dirs", + "File Options": "文件选项", "Show Hidden": "显示隐藏项目", "Folders First": "文件夹靠前", "Hidden Last": "隐藏项目置后", - "Yes": "是", - "No": "否", - "Network Options": "网络选项", - "Nxlink": "Nxlink开发工具", - "Check for update": "检查更新", - "File Options": "文件选项", "Cut": "剪切", "Copy": "复制", + "Paste": "", + "Paste ": "", + " file(s)?": "", "Rename": "重命名", + "Set New File Name": "", + "Advanced": "高级", "Advanced Options": "高级选项", "Create File": "新建文件", + "Set File Name": "", "Create Folder": "新建文件夹", - "View as text": "以文本形式查看", + "Set Folder Name": "", "View as text (unfinished)": "以文本形式查看(未完善)", "Set Archive Bit": "设置存档标志", + "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", + "Open with DayBreak?": "", + "Launch option for: ": "", + + "Homebrew": "插件列表", + "Homebrew Options": "插件选项", + "Hide Sphaira": "在插件列表中隐藏Sphaira", + "Install Forwarder": "安装前端应用", + "WARNING: Installing forwarders will lead to a ban!": "警告:安装前端应用可能导致ban机!", + "Installing Forwarder": "", + "Creating Program": "", + "Creating Control": "", + "Creating Meta": "", + "Writing Nca": "", + "Updating ncm databse": "", + "Pushing application record": "", + "Installed!": "", + "Failed to install forwarder": "", + + "AppStore": "插件商店", + "Filter: %s | Sort: %s | Order: %s": "筛选: %s | 排序: %s | 顺序: %s", "AppStore Options": "插件商店选项", "All": "全部", "Games": "游戏", "Emulators": "模拟器", "Tools": "工具", - "Advanced": "高级", "Themes": "主题", "Legacy": "可更新", - "Misc": "杂项", - "Downloads": "下载", - "Filter": "筛选", - "Search": "搜索", - "Menu Options": "菜单选项", - "Header": "标题", - "Theme": "主题", - "Network": "网络", - "Logging": "日志", - "Enabled": "启用", - "Disabled": "禁用", - "Replace hbmenu on exit": "退出后用Sphaira替换hbmenu", - "Misc Options": "杂项设置", - "Themezer": "在线主题", + "version: %s": "version: %s", + "updated: %s": "updated: %s", + "category: %s": "category: %s", + "extracted: %.2f MiB": "extracted: %.2f MiB", + "app_dls: %s": "app_dls: %s", + "More by Author": "", + "Leave Feedback": "", + "Irs": "红外成像", - "Web": "网页浏览器", - "Download": "下载", - "Next Page": "下一页", - "Prev Page": "上一页", + "Ambient Noise Level: ": "", + "Controller": "控制器", "Pad ": "手柄 ", - " (Unconnected)": " (未连接)", - "HandHeld": "手持式", " (Available)": " (可用的)", + " (Unconnected)": " (未连接)", + "HandHeld": "", + "Rotation": "", "0 (Sideways)": "0度", "90 (Flat)": "90度", "180 (-Sideways)": "180度", "270 (Upside down)": "270度", + "Colour": "颜色", "Grey": "灰色", "Ironbow": "紫黄", "Green": "绿色", "Red": "红色", "Blue": "蓝色", + "Light Target": "光源目标", "All leds": "全部", "Bright group": "亮色组", "Dim group": "暗色组", "None": "无", - "Normal image": "正常图像", - "Negative image": "负片图像", - "320x240": "320x240", - "160x120": "160x120", - "80x60": "80x60", - "40x30": "40x30", - "20x15": "20x15", - "Controller": "控制器", - "Rotation": "旋转", - "Colour": "颜色", - "Light Target": "光源目标", "Gain": "增益", "Negative Image": "负片图像", + "Normal image": "正常图像", + "Negative image": "负片图像", "Format": "格式", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", "Trimming Format": "裁剪格式", "External Light Filter": "外部光滤镜", "Load Default": "加载默认值", - "No Internet": "网络未连接", - "[Applet Mode]": "[小程序模式]", - "Language": "语言" -} + + "Themezer": "在线主题", + "Themezer Options": "", + "Nsfw": "", + "Page": "", + "Page %zu / %zu": "Page %zu / %zu", + "Enter Page Number": "", + "Bad Page": "", + "Download theme?": "", + + "Installing ": "", + "Uninstalling ": "", + "Deleting ": "", + "Deleting": "", + "Pasting ": "", + "Pasting": "", + "Removing ": "", + "Scanning ": "", + "Creating ": "", + "Copying ": "", + "Downloading ": "", + "Checking MD5": "", + "Loading...": "", + "Loading": "", + "Empty!": "", + "Not Ready...": "", + "Error loading page!": "", + "Update avaliable: ": "", + "Download update: ": "", + "Failed to download update": "", + "Delete Selected files?": "", + "Completely remove ": "", + "Are you sure you want to delete ": "您确定要删除吗 ", + "Are you sure you wish to cancel?": "" +} \ No newline at end of file diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 28e8bcf..f731dab 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -251,18 +251,18 @@ void App::Loop() { switch (arg.type) { case NxlinkCallbackType_Connected: log_write("[NxlinkCallbackType_Connected]\n"); - App::Notify("Nxlink Connected"); + App::Notify("Nxlink Connected"_i18n); break; case NxlinkCallbackType_WriteBegin: log_write("[NxlinkCallbackType_WriteBegin] %s\n", arg.file.filename); - App::Notify("Nxlink Upload"); + App::Notify("Nxlink Upload"_i18n); break; case NxlinkCallbackType_WriteProgress: // log_write("[NxlinkCallbackType_WriteProgress]\n"); break; case NxlinkCallbackType_WriteEnd: log_write("[NxlinkCallbackType_WriteEnd] %s\n", arg.file.filename); - App::Notify("Nxlink Finished"); + App::Notify("Nxlink Finished"_i18n); break; } } else if constexpr(std::is_same_v) { @@ -446,10 +446,10 @@ auto App::Install(OwoConfig& config) -> Result { if (R_FAILED(rc)) { App::PlaySoundEffect(SoundEffect_Error); - App::Push(std::make_shared(rc, "Failed to install forwarder")); + App::Push(std::make_shared(rc, "Failed to install forwarder"_i18n)); } else { App::PlaySoundEffect(SoundEffect_Install); - App::Notify("Installed!"); + App::Notify("Installed!"_i18n); } return rc; @@ -476,10 +476,10 @@ auto App::Install(ui::ProgressBox* pbox, OwoConfig& config) -> Result { if (R_FAILED(rc)) { App::PlaySoundEffect(SoundEffect_Error); - App::Push(std::make_shared(rc, "Failed to install forwarder")); + App::Push(std::make_shared(rc, "Failed to install forwarder"_i18n)); } else { App::PlaySoundEffect(SoundEffect_Install); - App::Notify("Installed!"); + App::Notify("Installed!"_i18n); } return rc; diff --git a/sphaira/source/owo.cpp b/sphaira/source/owo.cpp index 1b0eada..7288e15 100644 --- a/sphaira/source/owo.cpp +++ b/sphaira/source/owo.cpp @@ -11,6 +11,7 @@ #include "defines.hpp" #include "app.hpp" #include "ui/progress_box.hpp" +#include "i18n.hpp" namespace sphaira { namespace { @@ -1027,7 +1028,7 @@ auto install_forwader_internal(ui::ProgressBox* pbox, OwoConfig& config, NcmStor R_UNLESS(!config.main.empty(), OwoError_BadArgs); R_UNLESS(!config.npdm.empty(), OwoError_BadArgs); - pbox->NewTransfer("Creating Program").UpdateTransfer(0, 8); + pbox->NewTransfer("Creating Program"_i18n).UpdateTransfer(0, 8); FileEntries exefs; add_file_entry(exefs, "main", config.main); add_file_entry(exefs, "main.npdm", config.npdm); @@ -1059,7 +1060,7 @@ auto install_forwader_internal(ui::ProgressBox* pbox, OwoConfig& config, NcmStor // create control { - pbox->NewTransfer("Creating Control").UpdateTransfer(1, 8); + pbox->NewTransfer("Creating Control"_i18n).UpdateTransfer(1, 8); // patch nacp NcapPatch nacp_patch{}; nacp_patch.tid = tid; @@ -1082,7 +1083,7 @@ auto install_forwader_internal(ui::ProgressBox* pbox, OwoConfig& config, NcmStor NcmContentStorageRecord content_storage_record; NcmContentMetaData content_meta_data; { - pbox->NewTransfer("Creating Meta").UpdateTransfer(2, 8); + pbox->NewTransfer("Creating Meta"_i18n).UpdateTransfer(2, 8); const auto meta_entry = create_meta_nca(tid, key, storage_id, nca_entries); nca_entries.emplace_back(meta_entry.nca_entry); @@ -1099,7 +1100,7 @@ auto install_forwader_internal(ui::ProgressBox* pbox, OwoConfig& config, NcmStor ON_SCOPE_EXIT(ncmContentStorageClose(&cs)); for (const auto& nca : nca_entries) { - pbox->NewTransfer("Writing Nca").UpdateTransfer(3, 8); + pbox->NewTransfer("Writing Nca"_i18n).UpdateTransfer(3, 8); NcmContentId content_id; NcmPlaceHolderId placeholder_id; std::memcpy(&content_id, nca.hash, sizeof(content_id)); @@ -1114,7 +1115,7 @@ auto install_forwader_internal(ui::ProgressBox* pbox, OwoConfig& config, NcmStor // setup database { - pbox->NewTransfer("Updating ncm databse").UpdateTransfer(4, 8); + pbox->NewTransfer("Updating ncm databse"_i18n).UpdateTransfer(4, 8); NcmContentMetaDatabase db; R_TRY(ncmOpenContentMetaDatabase(&db, storage_id)); ON_SCOPE_EXIT(ncmContentMetaDatabaseClose(&db)); @@ -1125,7 +1126,7 @@ auto install_forwader_internal(ui::ProgressBox* pbox, OwoConfig& config, NcmStor // push record { - pbox->NewTransfer("Pushing application record").UpdateTransfer(5, 8); + pbox->NewTransfer("Pushing application record"_i18n).UpdateTransfer(5, 8); Service srv{}, *srv_ptr = &srv; bool already_installed{}; @@ -1166,7 +1167,7 @@ auto install_forwarder(ui::ProgressBox* pbox, OwoConfig& config, NcmStorageId st } auto install_forwarder(OwoConfig& config, NcmStorageId storage_id) -> Result { - App::Push(std::make_shared("Installing Forwarder", [config, storage_id](auto pbox) mutable -> bool { + App::Push(std::make_shared("Installing Forwarder"_i18n, [config, storage_id](auto pbox) mutable -> bool { return R_SUCCEEDED(install_forwarder(pbox, config, storage_id)); })); R_SUCCEED(); diff --git a/sphaira/source/ui/menus/appstore.cpp b/sphaira/source/ui/menus/appstore.cpp index bf13b21..eaf0627 100644 --- a/sphaira/source/ui/menus/appstore.cpp +++ b/sphaira/source/ui/menus/appstore.cpp @@ -370,7 +370,7 @@ auto UninstallApp(ProgressBox* pbox, const Entry& entry) -> bool { // remove directory, this will also delete manifest and info const auto dir = BuildPackageCachePath(entry); - pbox->NewTransfer("Removing " + dir); + pbox->NewTransfer("Removing "_i18n + dir); if (R_FAILED(fs.DeleteDirectoryRecursively(dir))) { log_write("failed to delete folder: %s\n", dir); } else { @@ -394,7 +394,7 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> bool { // 1. download the zip if (!pbox->ShouldExit()) { - pbox->NewTransfer("Downloading " + entry.title); + pbox->NewTransfer("Downloading "_i18n + entry.title); log_write("starting download\n"); const auto url = BuildZipUrl(entry); @@ -416,7 +416,7 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> bool { // 2. md5 check the zip if (!pbox->ShouldExit()) { - pbox->NewTransfer("Checking MD5"); + pbox->NewTransfer("Checking MD5"_i18n); log_write("starting md5 check\n"); FsFile f; @@ -792,11 +792,11 @@ void EntryMenu::Draw(NVGcontext* vg, Theme* theme) { // gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "author: %s", m_entry.author.c_str()); // text_start_y += text_inc_y; - gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "version: %s", m_entry.version.c_str()); + gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "version: %s"_i18n.c_str(), m_entry.version.c_str()); text_start_y += text_inc_y; - gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "updated: %s", m_entry.updated.c_str()); + gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "updated: %s"_i18n.c_str(), m_entry.updated.c_str()); text_start_y += text_inc_y; - gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "category: %s", m_entry.category.c_str()); + gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "category: %s"_i18n.c_str(), m_entry.category.c_str()); text_start_y += text_inc_y; // gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "license: %s", m_entry.license.c_str()); // text_start_y += text_inc_y; @@ -804,9 +804,9 @@ void EntryMenu::Draw(NVGcontext* vg, Theme* theme) { // text_start_y += text_inc_y; // gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "filesize: %.2f MiB", (double)m_entry.filesize / 1024.0); // text_start_y += text_inc_y; - gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "extracted: %.2f MiB", (double)m_entry.extracted / 1024.0); + gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "extracted: %.2f MiB"_i18n.c_str(), (double)m_entry.extracted / 1024.0); text_start_y += text_inc_y; - gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "app_dls: %s", AppDlToStr(m_entry.app_dls).c_str()); + gfx::drawTextArgs(vg, text_start_x, text_start_y, font_size, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "app_dls: %s"_i18n.c_str(), AppDlToStr(m_entry.app_dls).c_str()); text_start_y += text_inc_y; // for (const auto& option : m_options) { @@ -935,7 +935,7 @@ auto toLower(const std::string& str) -> std::string { return lower; } -Menu::Menu(const std::vector& nro_entries) : MenuBase{"AppStore"}, m_nro_entries{nro_entries} { +Menu::Menu(const std::vector& nro_entries) : MenuBase{"AppStore"_i18n}, m_nro_entries{nro_entries} { fs::FsNativeSd fs; fs.CreateDirectoryRecursively("/switch/sphaira/cache/appstore/icons"); fs.CreateDirectoryRecursively("/switch/sphaira/cache/appstore/banners"); @@ -1136,12 +1136,12 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { MenuBase::Draw(vg, theme); if (m_entries.empty()) { - gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Loading..."); + gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Loading..."_i18n.c_str()); return; } if (m_entries_current.empty()) { - gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Empty!"); + gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Empty!"_i18n.c_str()); return; } @@ -1431,7 +1431,7 @@ void Menu::Sort() { char subheader[128]{}; - std::snprintf(subheader, sizeof(subheader), "Sort: %s | Filter: %s | Order: %s", i18n::get(SORT_STR[m_sort]).c_str(), i18n::get(FILTER_STR[m_filter]).c_str(), i18n::get(ORDER_STR[m_order]).c_str()); + std::snprintf(subheader, sizeof(subheader), "Filter: %s | Sort: %s | Order: %s"_i18n.c_str(), i18n::get(FILTER_STR[m_filter]).c_str(), i18n::get(SORT_STR[m_sort]).c_str(), i18n::get(ORDER_STR[m_order]).c_str()); SetTitleSubHeading(subheader); std::sort(m_entries_current.begin(), m_entries_current.end(), sorter); diff --git a/sphaira/source/ui/menus/file_viewer.cpp b/sphaira/source/ui/menus/file_viewer.cpp index 961ae01..6885f6b 100644 --- a/sphaira/source/ui/menus/file_viewer.cpp +++ b/sphaira/source/ui/menus/file_viewer.cpp @@ -1,4 +1,5 @@ #include "ui/menus/file_viewer.hpp" +#include "i18n.hpp" namespace sphaira::ui::menu::fileview { namespace { @@ -6,7 +7,7 @@ namespace { } // namespace Menu::Menu(const fs::FsPath& path) : MenuBase{path}, m_path{path} { - SetAction(Button::B, Action{"Back", [this](){ + SetAction(Button::B, Action{"Back"_i18n, [this](){ SetPop(); }}); diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index ff20b2b..87820d8 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -469,17 +469,17 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 options->Add(std::make_shared("Show Hidden"_i18n, m_show_hidden.Get(), [this](bool& v_out){ m_show_hidden.Set(v_out); SortAndFindLastFile(); - }, "Yes"_i18n, "No")); + }, "Yes"_i18n, "No"_i18n)); options->Add(std::make_shared("Folders First"_i18n, m_folders_first.Get(), [this](bool& v_out){ m_folders_first.Set(v_out); SortAndFindLastFile(); - }, "Yes"_i18n, "No")); + }, "Yes"_i18n, "No"_i18n)); options->Add(std::make_shared("Hidden Last"_i18n, m_hidden_last.Get(), [this](bool& v_out){ m_hidden_last.Set(v_out); SortAndFindLastFile(); - }, "Yes"_i18n, "No")); + }, "Yes"_i18n, "No"_i18n)); })); if (m_entries_current.size()) { @@ -519,7 +519,7 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 if (!m_selected_files.empty() && (m_selected_type == SelectedType::Cut || m_selected_type == SelectedType::Copy)) { options->Add(std::make_shared("Paste"_i18n, [this](){ - const std::string buf = "Paste " + std::to_string(m_selected_files.size()) + " file(s)?"; + const std::string buf = "Paste "_i18n + std::to_string(m_selected_files.size()) + " file(s)?"_i18n; App::Push(std::make_shared( buf, "No"_i18n, "Yes"_i18n, 1, [this](auto op_index){ if (op_index && *op_index) { @@ -535,7 +535,7 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 std::string out; const auto& entry = GetEntry(); const auto name = entry.GetName(); - if (R_SUCCEEDED(swkbd::ShowText(out, "Set New File Name", name.c_str())) && !out.empty() && out != name) { + if (R_SUCCEEDED(swkbd::ShowText(out, "Set New File Name"_i18n.c_str(), name.c_str())) && !out.empty() && out != name) { const auto src_path = GetNewPath(entry); const auto dst_path = GetNewPath(m_path, out); @@ -563,7 +563,7 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 options->Add(std::make_shared("Create File"_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out, "Set File Name")) && !out.empty()) { + if (R_SUCCEEDED(swkbd::ShowText(out, "Set File Name"_i18n.c_str())) && !out.empty()) { fs::FsPath full_path; if (out[0] == '/') { full_path = out; @@ -584,7 +584,7 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 options->Add(std::make_shared("Create Folder"_i18n, [this](){ std::string out; - if (R_SUCCEEDED(swkbd::ShowText(out, "Set Folder Name")) && !out.empty()) { + if (R_SUCCEEDED(swkbd::ShowText(out, "Set Folder Name"_i18n.c_str())) && !out.empty()) { fs::FsPath full_path; if (out[0] == '/') { full_path = out; @@ -687,7 +687,7 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { const auto& text_col = theme->elements[ThemeEntryID_TEXT].colour; if (m_entries_current.empty()) { - gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, text_col, "Empty..."); + gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, text_col, "Empty..."_i18n.c_str()); return; } @@ -779,8 +779,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { nvgRestore(vg); if (e.IsDir()) { - gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) - 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_BOTTOM, theme->elements[text_id].colour, "%zd files", e.file_count); - gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) + 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP, theme->elements[text_id].colour, "%zd dirs", e.dir_count); + gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) - 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_BOTTOM, theme->elements[text_id].colour, "%zd files"_i18n.c_str(), e.file_count); + gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) + 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP, theme->elements[text_id].colour, "%zd dirs"_i18n.c_str(), e.dir_count); } else { if (!e.time_stamp.is_valid) { fs::FsNativeSd fs; @@ -877,7 +877,7 @@ void Menu::InstallForwarder() { if (op_index) { const auto assoc = assoc_list[*op_index]; log_write("pushing it\n"); - App::Push(std::make_shared("Installing Forwarder", [assoc, this](auto pbox) -> bool { + App::Push(std::make_shared("Installing Forwarder"_i18n, [assoc, this](auto pbox) -> bool { log_write("inside callback\n"); NroEntry nro{}; @@ -1325,7 +1325,7 @@ void Menu::OnDeleteCallback() { Scan(m_path); log_write("did delete\n"); } else { - App::Push(std::make_shared("Deleting", [this](auto pbox){ + App::Push(std::make_shared("Deleting"_i18n, [this](auto pbox){ fs::FsNativeSd fs; FsDirCollections collections; @@ -1338,7 +1338,7 @@ void Menu::OnDeleteCallback() { const auto full_path = GetNewPath(m_selected_path, p.name); if (p.IsDir()) { - pbox->NewTransfer("Scanning " + full_path); + pbox->NewTransfer("Scanning "_i18n + full_path); if (R_FAILED(get_collections(full_path, p.name, collections))) { log_write("failed to get dir collection: %s\n", full_path); return false; @@ -1356,7 +1356,7 @@ void Menu::OnDeleteCallback() { } const auto full_path = GetNewPath(c.path, p.name); - pbox->NewTransfer("Deleting " + full_path); + pbox->NewTransfer("Deleting "_i18n + full_path); if (p.type == FsDirEntryType_Dir) { log_write("deleting dir: %s\n", full_path); fs.DeleteDirectory(full_path); @@ -1383,7 +1383,7 @@ void Menu::OnDeleteCallback() { } const auto full_path = GetNewPath(m_selected_path, p.name); - pbox->NewTransfer("Deleting " + full_path); + pbox->NewTransfer("Deleting "_i18n + full_path); if (p.IsDir()) { log_write("deleting dir: %s\n", full_path); @@ -1422,7 +1422,7 @@ void Menu::OnPasteCallback() { Scan(m_path); log_write("did paste\n"); } else { - App::Push(std::make_shared("Pasting", [this](auto pbox){ + App::Push(std::make_shared("Pasting"_i18n, [this](auto pbox){ fs::FsNativeSd fs; if (m_selected_type == SelectedType::Cut) { @@ -1435,7 +1435,7 @@ void Menu::OnPasteCallback() { const auto src_path = GetNewPath(m_selected_path, p.name); const auto dst_path = GetNewPath(m_path, p.name); - pbox->NewTransfer("Pasting " + src_path); + pbox->NewTransfer("Pasting "_i18n + src_path); if (p.IsDir()) { fs.RenameDirectory(src_path, dst_path); @@ -1455,7 +1455,7 @@ void Menu::OnPasteCallback() { const auto full_path = GetNewPath(m_selected_path, p.name); if (p.IsDir()) { - pbox->NewTransfer("Scanning " + full_path); + pbox->NewTransfer("Scanning "_i18n + full_path); if (R_FAILED(get_collections(full_path, p.name, collections))) { log_write("failed to get dir collection: %s\n", full_path); return false; @@ -1473,10 +1473,10 @@ void Menu::OnPasteCallback() { const auto dst_path = GetNewPath(p); if (p.IsDir()) { - pbox->NewTransfer("Creating " + dst_path); + pbox->NewTransfer("Creating "_i18n + dst_path); fs.CreateDirectory(dst_path); } else { - pbox->NewTransfer("Copying " + src_path); + pbox->NewTransfer("Copying "_i18n + src_path); R_TRY_RESULT(pbox->CopyFile(src_path, dst_path), false); } } @@ -1495,7 +1495,7 @@ void Menu::OnPasteCallback() { const auto dst_path = GetNewPath(base_dst_path, p.name); log_write("creating: %s to %s\n", src_path, dst_path); - pbox->NewTransfer("Creating " + dst_path); + pbox->NewTransfer("Creating "_i18n + dst_path); fs.CreateDirectory(dst_path); } @@ -1508,7 +1508,7 @@ void Menu::OnPasteCallback() { const auto src_path = GetNewPath(c.path, p.name); const auto dst_path = GetNewPath(base_dst_path, p.name); - pbox->NewTransfer("Copying " + src_path); + pbox->NewTransfer("Copying "_i18n + src_path); log_write("copying: %s to %s\n", src_path, dst_path); R_TRY_RESULT(pbox->CopyFile(src_path, dst_path), false); } diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index aba493a..3760a89 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -112,7 +112,7 @@ Menu::Menu() : MenuBase{"Homebrew"_i18n} { #endif options->Add(std::make_shared("Delete"_i18n, [this](){ - const auto buf = "Are you sure you want to delete "_i18n + m_entries[m_index].path.toString() + "?"; + const auto buf = "Are you sure you want to delete " + m_entries[m_index].path.toString(); App::Push(std::make_shared( buf, "Back"_i18n, "Delete"_i18n, 1, [this](auto op_index){ diff --git a/sphaira/source/ui/menus/irs_menu.cpp b/sphaira/source/ui/menus/irs_menu.cpp index 07acd0c..93847cb 100644 --- a/sphaira/source/ui/menus/irs_menu.cpp +++ b/sphaira/source/ui/menus/irs_menu.cpp @@ -242,7 +242,7 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { const auto rc = irsGetImageTransferProcessorState(m_entries[m_index].m_handle, m_irs_buffer.data(), m_irs_buffer.size(), &state); if (R_SUCCEEDED(rc) && state.sampling_number != m_prev_state.sampling_number) { m_prev_state = state; - SetSubHeading("Ambient Noise Level: " + std::to_string(m_prev_state.ambient_noise_level)); + SetSubHeading("Ambient Noise Level: "_i18n + std::to_string(m_prev_state.ambient_noise_level)); updateColourArray(); } diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 81239d3..98dba55 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -204,18 +204,19 @@ MainMenu::MainMenu() { SidebarEntryArray::Items language_items; language_items.push_back("Auto"_i18n); - language_items.push_back("English"); - language_items.push_back("Japanese"); - language_items.push_back("French"); - language_items.push_back("German"); - language_items.push_back("Italian"); - language_items.push_back("Spanish"); - language_items.push_back("Chinese"); - language_items.push_back("Korean"); - language_items.push_back("Dutch"); - language_items.push_back("Portuguese"); - language_items.push_back("Russian"); - language_items.push_back("Swedish"); + + language_items.push_back("English"_i18n); + language_items.push_back("Japanese"_i18n); + language_items.push_back("French"_i18n); + language_items.push_back("German"_i18n); + language_items.push_back("Italian"_i18n); + language_items.push_back("Spanish"_i18n); + language_items.push_back("Chinese"_i18n); + language_items.push_back("Korean"_i18n); + language_items.push_back("Dutch"_i18n); + language_items.push_back("Portuguese"_i18n); + language_items.push_back("Russian"_i18n); + language_items.push_back("Swedish"_i18n); options->AddHeader("Header"_i18n); options->AddSpacer(); @@ -258,7 +259,7 @@ MainMenu::MainMenu() { if (success) { m_update_state = UpdateState::None; } else { - App::Push(std::make_shared(MAKERESULT(351, 1), "Failed to download update")); + App::Push(std::make_shared(MAKERESULT(351, 1), "Failed to download update"_i18n)); } }, 2)); })); diff --git a/sphaira/source/ui/menus/themezer.cpp b/sphaira/source/ui/menus/themezer.cpp index 4757b22..a5abfae 100644 --- a/sphaira/source/ui/menus/themezer.cpp +++ b/sphaira/source/ui/menus/themezer.cpp @@ -508,7 +508,7 @@ Menu::Menu() : MenuBase{"Themezer"_i18n} { options->Add(std::make_shared("Page"_i18n, [this](){ s64 out; - if (R_SUCCEEDED(swkbd::ShowNumPad(out, "Enter Page Number", nullptr, -1, 3))) { + if (R_SUCCEEDED(swkbd::ShowNumPad(out, "Enter Page Number"_i18n.c_str(), nullptr, -1, 3))) { if (out < m_page_index_max) { m_page_index = out; PackListDownload(); @@ -569,7 +569,7 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { MenuBase::Draw(vg, theme); if (m_pages.empty()) { - gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Empty!"); + gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Empty!"_i18n.c_str()); return; } @@ -577,15 +577,15 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) { switch (page.m_ready) { case PageLoadState::None: - gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Not Ready..."); + gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Not Ready..."_i18n.c_str()); return; case PageLoadState::Loading: - gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Loading"); + gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Loading"_i18n.c_str()); return; case PageLoadState::Done: break; case PageLoadState::Error: - gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Error loading page!"); + gfx::drawTextArgs(vg, SCREEN_WIDTH / 2.f, SCREEN_HEIGHT / 2.f, 36.f, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::YELLOW, "Error loading page!"_i18n.c_str()); return; } @@ -687,7 +687,7 @@ void Menu::InvalidateAllPages() { void Menu::PackListDownload() { const auto page_index = m_page_index + 1; char subheading[128]; - std::snprintf(subheading, sizeof(subheading), "Page %zu / %zu", m_page_index+1, m_page_index_max); + std::snprintf(subheading, sizeof(subheading), "Page %zu / %zu"_i18n.c_str(), m_page_index+1, m_page_index_max); SetSubHeading(subheading); m_index = 0; @@ -733,7 +733,7 @@ void Menu::PackListDownload() { m_page_index_max = a.pagination.page_count; char subheading[128]; - std::snprintf(subheading, sizeof(subheading), "Page %zu / %zu", m_page_index+1, m_page_index_max); + std::snprintf(subheading, sizeof(subheading), "Page %zu / %zu"_i18n.c_str(), m_page_index+1, m_page_index_max); SetSubHeading(subheading); log_write("a.pagination.page: %u\n", a.pagination.page); diff --git a/sphaira/source/ui/option_list.cpp b/sphaira/source/ui/option_list.cpp index e5a9c95..019a0ab 100644 --- a/sphaira/source/ui/option_list.cpp +++ b/sphaira/source/ui/option_list.cpp @@ -1,18 +1,19 @@ #include "ui/option_list.hpp" #include "app.hpp" #include "ui/nvg_util.hpp" +#include "i18n.hpp" namespace sphaira::ui { OptionList::OptionList(Options options) : m_options{std::move(options)} { - SetAction(Button::A, Action{"Select", [this](){ + SetAction(Button::A, Action{"Select"_i18n, [this](){ const auto& [_, func] = m_options[m_index]; func(); SetPop(); }}); - SetAction(Button::B, Action{"Back", [this](){ + SetAction(Button::B, Action{"Back"_i18n, [this](){ SetPop(); }}); } diff --git a/sphaira/source/ui/popup_list.cpp b/sphaira/source/ui/popup_list.cpp index d3d6456..6898f2e 100644 --- a/sphaira/source/ui/popup_list.cpp +++ b/sphaira/source/ui/popup_list.cpp @@ -1,6 +1,7 @@ #include "ui/popup_list.hpp" #include "ui/nvg_util.hpp" #include "app.hpp" +#include "i18n.hpp" namespace sphaira::ui { @@ -68,13 +69,13 @@ PopupList::PopupList(std::string title, Items items, Callback cb, std::size_t in m_scrollbar.Setup(Vec4{1220.f, m_line_top, 1.f, m_line_bottom - m_line_top}, m_block.h, m_items.size()); SetActions( - std::make_pair(Button::A, Action{"Select", [this](){ + std::make_pair(Button::A, Action{"Select"_i18n, [this](){ if (m_callback) { m_callback(m_index); } SetPop(); }}), - std::make_pair(Button::B, Action{"Back", [this](){ + std::make_pair(Button::B, Action{"Back"_i18n, [this](){ if (m_callback) { m_callback(std::nullopt); } diff --git a/sphaira/source/ui/progress_box.cpp b/sphaira/source/ui/progress_box.cpp index 1f99441..e7f624a 100644 --- a/sphaira/source/ui/progress_box.cpp +++ b/sphaira/source/ui/progress_box.cpp @@ -4,6 +4,7 @@ #include "app.hpp" #include "defines.hpp" #include "log.hpp" +#include "i18n.hpp" namespace sphaira::ui { namespace { @@ -17,8 +18,8 @@ void threadFunc(void* arg) { } // namespace ProgressBox::ProgressBox(const std::string& title, ProgressBoxCallback callback, ProgressBoxDoneCallback done, int cpuid, int prio, int stack_size) { - SetAction(Button::B, Action{"Back", [this](){ - App::Push(std::make_shared("Are you sure you wish to cancel?", "No", "Yes", 1, [this](auto op_index){ + SetAction(Button::B, Action{"Back"_i18n, [this](){ + App::Push(std::make_shared("Are you sure you wish to cancel?"_i18n, "No"_i18n, "Yes"_i18n, 1, [this](auto op_index){ if (op_index && *op_index) { RequestExit(); SetPop(); diff --git a/sphaira/source/ui/sidebar.cpp b/sphaira/source/ui/sidebar.cpp index 7fce7d4..b9240cb 100644 --- a/sphaira/source/ui/sidebar.cpp +++ b/sphaira/source/ui/sidebar.cpp @@ -2,6 +2,7 @@ #include "app.hpp" #include "ui/popup_list.hpp" #include "ui/nvg_util.hpp" +#include "i18n.hpp" namespace sphaira::ui { namespace { @@ -42,7 +43,7 @@ SidebarEntryBool::SidebarEntryBool(std::string title, bool option, Callback cb, , m_true_str{std::move(true_str)} , m_false_str{std::move(false_str)} { - SetAction(Button::A, Action{"OK", [this](){ + SetAction(Button::A, Action{"OK"_i18n, [this](){ m_option ^= 1; m_callback(m_option); } @@ -77,7 +78,7 @@ SidebarEntryCallback::SidebarEntryCallback(std::string title, Callback cb, bool : SidebarEntryBase{std::move(title)} , m_callback{cb} , m_pop_on_click{pop_on_click} { - SetAction(Button::A, Action{"OK", [this](){ + SetAction(Button::A, Action{"OK"_i18n, [this](){ m_callback(); if (m_pop_on_click) { SetPop(); @@ -143,7 +144,7 @@ SidebarEntryArray::SidebarEntryArray(std::string title, Items items, Callback cb )); }; - SetAction(Button::A, Action{"OK", [this](){ + SetAction(Button::A, Action{"OK"_i18n, [this](){ // m_callback(m_index); m_list_callback(); } @@ -191,7 +192,7 @@ Sidebar::Sidebar(std::string title, std::string sub, Side side, Items&& items) m_base_pos = Vec4{GetX() + 30.f, GetY() + 170.f, m_pos.w - (30.f * 2.f), 70.f}; // each item has it's own Action, but we take over B - SetAction(Button::B, Action{"Back", [this](){ + SetAction(Button::B, Action{"Back"_i18n, [this](){ SetPop(); }}); From d02fbcf282768d4d7943fc18039b1d981b6f2162 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 17:31:19 +0000 Subject: [PATCH 09/25] fix performance regression caused by #32 the issue isn't with the pr itself, however it did expose the lack of caching with the translation strings, it will continue to search for strings, even if we already found them. to solve this, i used a map to cache said strings --- sphaira/source/i18n.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/sphaira/source/i18n.cpp b/sphaira/source/i18n.cpp index c50a4ad..a97151b 100644 --- a/sphaira/source/i18n.cpp +++ b/sphaira/source/i18n.cpp @@ -3,6 +3,7 @@ #include "log.hpp" #include #include +#include namespace sphaira::i18n { namespace { @@ -10,32 +11,46 @@ namespace { std::vector g_i18n_data; yyjson_doc* json; yyjson_val* root; +std::unordered_map g_tr_cache; std::string get_internal(const char* str, size_t len) { + const std::string kkey = {str, len}; + + if (auto it = g_tr_cache.find(kkey); it != g_tr_cache.end()) { + return it->second; + } + + // add default entry + g_tr_cache.emplace(kkey, kkey); + if (!json || !root) { log_write("no json or root\n"); - return str; + return kkey; } auto key = yyjson_obj_getn(root, str, len); if (!key) { - log_write("\tfailed to find key: [%.*s]\n", len, str); - return str; + log_write("\tfailed to find key: [%s]\n", kkey.c_str()); + return kkey; } auto val = yyjson_get_str(key); auto val_len = yyjson_get_len(key); if (!val || !val_len) { - log_write("\tfailed to get value: [%.*s]\n", len, str); - return str; + log_write("\tfailed to get value: [%s]\n", kkey.c_str()); + return kkey; } - return {val, val_len}; + // update entry in cache + const std::string ret = {val, val_len}; + g_tr_cache.insert_or_assign(kkey, ret); + return ret; } } // namespace bool init(long index) { + g_tr_cache.clear(); R_TRY_RESULT(romfsInit(), false); ON_SCOPE_EXIT( romfsExit() ); From 97085ef28230662bd486b2ee01074b0cbbe260c5 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 18:01:57 +0000 Subject: [PATCH 10/25] add option in config to remove install warning prompt --- sphaira/include/app.hpp | 2 ++ sphaira/source/app.cpp | 4 ++++ sphaira/source/ui/menus/filebrowser.cpp | 27 +++++++++++++++---------- sphaira/source/ui/menus/homebrew.cpp | 18 ++++++++++------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/sphaira/include/app.hpp b/sphaira/include/app.hpp index e4b9bc7..8a8c654 100644 --- a/sphaira/include/app.hpp +++ b/sphaira/include/app.hpp @@ -64,6 +64,7 @@ class App { static auto GetLogEnable() -> bool; static auto GetReplaceHbmenuEnable() -> bool; static auto GetInstallSdEnable() -> bool; + static auto GetInstallPrompt() -> bool; static auto GetThemeShuffleEnable() -> bool; static auto GetThemeMusicEnable() -> bool; static auto GetLanguage() -> long; @@ -139,6 +140,7 @@ class App { option::OptionBool m_log_enabled{INI_SECTION, "log_enabled", false}; option::OptionBool m_replace_hbmenu{INI_SECTION, "replace_hbmenu", false}; option::OptionBool m_install_sd{INI_SECTION, "install_sd", true}; + option::OptionLong m_install_prompt{INI_SECTION, "install_prompt", true}; option::OptionBool m_theme_shuffle{INI_SECTION, "theme_shuffle", false}; option::OptionBool m_theme_music{INI_SECTION, "theme_music", true}; option::OptionLong m_language{INI_SECTION, "language", 0}; // auto diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index f731dab..65c2b02 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -367,6 +367,10 @@ auto App::GetInstallSdEnable() -> bool { return g_app->m_install_sd.Get(); } +auto App::GetInstallPrompt() -> bool { + return g_app->m_install_prompt.Get(); +} + auto App::GetThemeShuffleEnable() -> bool { return g_app->m_theme_shuffle.Get(); } diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index 87820d8..900dc2c 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -610,20 +610,18 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 if (m_entries_current.size()) { if (HasTypeInSelectedEntries(FsDirEntryType_File) && !m_selected_count && (GetEntry().GetExtension() == "nro" || !FindFileAssocFor().empty())) { options->Add(std::make_shared("Install Forwarder"_i18n, [this](){; - App::Push(std::make_shared( - "WARNING: Installing forwarders will lead to a ban!"_i18n, - "Back"_i18n, "Install"_i18n, 0, [this](auto op_index){ - if (op_index && *op_index) { - if (GetEntry().GetExtension() == "nro") { - if (R_FAILED(homebrew::Menu::InstallHomebrewFromPath(GetNewPathCurrent()))) { - log_write("failed to create forwarder\n"); - } - } else { + if (App::GetInstallPrompt()) { + App::Push(std::make_shared( + "WARNING: Installing forwarders will lead to a ban!"_i18n, + "Back"_i18n, "Install"_i18n, 0, [this](auto op_index){ + if (op_index && *op_index) { InstallForwarder(); } } - } - )); + )); + } else { + InstallForwarder(); + } })); } @@ -860,6 +858,13 @@ void Menu::SetIndex(std::size_t index) { } void Menu::InstallForwarder() { + if (GetEntry().GetExtension() == "nro") { + if (R_FAILED(homebrew::Menu::InstallHomebrewFromPath(GetNewPathCurrent()))) { + log_write("failed to create forwarder\n"); + } + return; + } + const auto assoc_list = FindFileAssocFor(); if (assoc_list.empty()) { log_write("failed to find assoc for: %s ext: %s\n", GetEntry().name, GetEntry().extension.c_str()); diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index 3760a89..e7e90fb 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -127,14 +127,18 @@ Menu::Menu() : MenuBase{"Homebrew"_i18n} { }, true)); options->Add(std::make_shared("Install Forwarder"_i18n, [this](){ - App::Push(std::make_shared( - "WARNING: Installing forwarders will lead to a ban!"_i18n, - "Back"_i18n, "Install"_i18n, 0, [this](auto op_index){ - if (op_index && *op_index) { - InstallHomebrew(); + if (App::GetInstallPrompt()) { + App::Push(std::make_shared( + "WARNING: Installing forwarders will lead to a ban!"_i18n, + "Back"_i18n, "Install"_i18n, 0, [this](auto op_index){ + if (op_index && *op_index) { + InstallHomebrew(); + } } - } - )); + )); + } else { + InstallHomebrew(); + } }, true)); } }}) From 986ffdcd9cff2d726834065638ae86cef9d7a822 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 18:04:19 +0000 Subject: [PATCH 11/25] remove option to set archive bit in filebrowser removed as likely no one needs this feature, and an cause problems for users that do not know what they're doing --- sphaira/source/ui/menus/filebrowser.cpp | 37 ------------------------- 1 file changed, 37 deletions(-) diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index 900dc2c..b6c694f 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -624,43 +624,6 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 } })); } - - if (HasTypeInSelectedEntries(FsDirEntryType_Dir)) { - options->Add(std::make_shared("Set Archive Bit"_i18n, [this](){ - if (!m_selected_count) { - AddCurrentFileToSelection(SelectedType::None); - } else { - AddSelectedEntries(SelectedType::None); - } - - App::Push(std::make_shared( - "Warning! Setting the archive bit cannot be undone!"_i18n, - "No"_i18n, "Yes"_i18n, 1, [this](auto op_index) { - if (op_index && *op_index == 1) { - bool re_sort{}; - for (const auto&p : m_selected_files) { - const auto file_path = GetNewPath(m_selected_path, p.name); - if (p.IsDir()) { - fs::FsNativeSd fs; - if (R_SUCCEEDED(fsFsSetConcatenationFileAttribute(&fs.m_fs, file_path))) { - log_write("updated timestamp\n"); - re_sort |= true; - } else { - log_write("failed to set concatenation file attribute\n"); - } - } - } - - if (re_sort) { - Scan(m_path); - } - } - } - )); - - ResetSelection(); - }, true)); - } } })); }}) From 4a058d3caf94fe78cf4bd64b209556008ef7d38a Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 18:49:40 +0000 Subject: [PATCH 12/25] disable install by default, enabled via advanced menu. disable web browser if applet. --- sphaira/include/app.hpp | 4 ++ sphaira/source/app.cpp | 12 ++++++ sphaira/source/ui/menus/filebrowser.cpp | 2 +- sphaira/source/ui/menus/homebrew.cpp | 28 +++++++------- sphaira/source/ui/menus/main_menu.cpp | 49 +++++++++++++++++++------ 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/sphaira/include/app.hpp b/sphaira/include/app.hpp index 8a8c654..df15b97 100644 --- a/sphaira/include/app.hpp +++ b/sphaira/include/app.hpp @@ -63,6 +63,7 @@ class App { static auto GetNxlinkEnable() -> bool; static auto GetLogEnable() -> bool; static auto GetReplaceHbmenuEnable() -> bool; + static auto GetInstallEnable() -> bool; static auto GetInstallSdEnable() -> bool; static auto GetInstallPrompt() -> bool; static auto GetThemeShuffleEnable() -> bool; @@ -72,7 +73,9 @@ class App { static void SetNxlinkEnable(bool enable); static void SetLogEnable(bool enable); static void SetReplaceHbmenuEnable(bool enable); + static void SetInstallEnable(bool enable); static void SetInstallSdEnable(bool enable); + static void SetInstallPrompt(bool enable); static void SetThemeShuffleEnable(bool enable); static void SetThemeMusicEnable(bool enable); static void SetLanguage(long index); @@ -139,6 +142,7 @@ class App { option::OptionBool m_nxlink_enabled{INI_SECTION, "nxlink_enabled", true}; option::OptionBool m_log_enabled{INI_SECTION, "log_enabled", false}; option::OptionBool m_replace_hbmenu{INI_SECTION, "replace_hbmenu", false}; + option::OptionBool m_install{INI_SECTION, "install", false}; option::OptionBool m_install_sd{INI_SECTION, "install_sd", true}; option::OptionLong m_install_prompt{INI_SECTION, "install_prompt", true}; option::OptionBool m_theme_shuffle{INI_SECTION, "theme_shuffle", false}; diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 65c2b02..578de27 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -363,6 +363,10 @@ auto App::GetReplaceHbmenuEnable() -> bool { return g_app->m_replace_hbmenu.Get(); } +auto App::GetInstallEnable() -> bool { + return g_app->m_install.Get(); +} + auto App::GetInstallSdEnable() -> bool { return g_app->m_install_sd.Get(); } @@ -409,10 +413,18 @@ void App::SetReplaceHbmenuEnable(bool enable) { g_app->m_replace_hbmenu.Set(enable); } +void App::SetInstallEnable(bool enable) { + g_app->m_install.Set(enable); +} + void App::SetInstallSdEnable(bool enable) { g_app->m_install_sd.Set(enable); } +void App::SetInstallPrompt(bool enable) { + g_app->m_install_prompt.Set(enable); +} + void App::SetThemeShuffleEnable(bool enable) { g_app->m_theme_shuffle.Set(enable); } diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index b6c694f..004e4d0 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -608,7 +608,7 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 } if (m_entries_current.size()) { - if (HasTypeInSelectedEntries(FsDirEntryType_File) && !m_selected_count && (GetEntry().GetExtension() == "nro" || !FindFileAssocFor().empty())) { + if (App::GetInstallEnable() && HasTypeInSelectedEntries(FsDirEntryType_File) && !m_selected_count && (GetEntry().GetExtension() == "nro" || !FindFileAssocFor().empty())) { options->Add(std::make_shared("Install Forwarder"_i18n, [this](){; if (App::GetInstallPrompt()) { App::Push(std::make_shared( diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index e7e90fb..0fb5e10 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -126,20 +126,22 @@ Menu::Menu() : MenuBase{"Homebrew"_i18n} { )); }, true)); - options->Add(std::make_shared("Install Forwarder"_i18n, [this](){ - if (App::GetInstallPrompt()) { - App::Push(std::make_shared( - "WARNING: Installing forwarders will lead to a ban!"_i18n, - "Back"_i18n, "Install"_i18n, 0, [this](auto op_index){ - if (op_index && *op_index) { - InstallHomebrew(); + if (App::GetInstallEnable()) { + options->Add(std::make_shared("Install Forwarder"_i18n, [this](){ + if (App::GetInstallPrompt()) { + App::Push(std::make_shared( + "WARNING: Installing forwarders will lead to a ban!"_i18n, + "Back"_i18n, "Install"_i18n, 0, [this](auto op_index){ + if (op_index && *op_index) { + InstallHomebrew(); + } } - } - )); - } else { - InstallHomebrew(); - } - }, true)); + )); + } else { + InstallHomebrew(); + } + }, true)); + } } }}) ); diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 98dba55..1e1192b 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -204,7 +204,6 @@ MainMenu::MainMenu() { SidebarEntryArray::Items language_items; language_items.push_back("Auto"_i18n); - language_items.push_back("English"_i18n); language_items.push_back("Japanese"_i18n); language_items.push_back("French"_i18n); @@ -266,17 +265,10 @@ MainMenu::MainMenu() { } })); - options->Add(std::make_shared("Language"_i18n, language_items, [this, language_items](std::size_t& index_out){ + options->Add(std::make_shared("Language"_i18n, language_items, [this](std::size_t& index_out){ App::SetLanguage(index_out); }, (std::size_t)App::GetLanguage())); - options->Add(std::make_shared("Logging"_i18n, App::GetLogEnable(), [this](bool& enable){ - App::SetLogEnable(enable); - }, "Enabled"_i18n, "Disabled"_i18n)); - options->Add(std::make_shared("Replace hbmenu on exit"_i18n, App::GetReplaceHbmenuEnable(), [this](bool& enable){ - App::SetReplaceHbmenuEnable(enable); - }, "Enabled"_i18n, "Disabled"_i18n)); - options->Add(std::make_shared("Misc"_i18n, [this](){ auto options = std::make_shared("Misc Options"_i18n, Sidebar::Side::LEFT); ON_SCOPE_EXIT(App::Push(options)); @@ -284,12 +276,45 @@ MainMenu::MainMenu() { options->Add(std::make_shared("Themezer"_i18n, [](){ App::Push(std::make_shared()); })); + options->Add(std::make_shared("Irs"_i18n, [](){ App::Push(std::make_shared()); })); - options->Add(std::make_shared("Web"_i18n, [](){ - WebShow("https://lite.duckduckgo.com/lite"); - })); + + if (App::IsApplication()) { + options->Add(std::make_shared("Web"_i18n, [](){ + WebShow("https://lite.duckduckgo.com/lite"); + })); + } + })); + + options->Add(std::make_shared("Advanced"_i18n, [this](){ + auto options = std::make_shared("Advanced Options"_i18n, Sidebar::Side::LEFT); + ON_SCOPE_EXIT(App::Push(options)); + + SidebarEntryArray::Items install_items; + install_items.push_back("System memory"_i18n); + install_items.push_back("microSD card"_i18n); + + options->Add(std::make_shared("Logging"_i18n, App::GetLogEnable(), [this](bool& enable){ + App::SetLogEnable(enable); + }, "Enabled"_i18n, "Disabled"_i18n)); + + options->Add(std::make_shared("Replace hbmenu on exit"_i18n, App::GetReplaceHbmenuEnable(), [this](bool& enable){ + App::SetReplaceHbmenuEnable(enable); + }, "Enabled"_i18n, "Disabled"_i18n)); + + options->Add(std::make_shared("Install forwarders"_i18n, App::GetInstallEnable(), [this](bool& enable){ + App::SetInstallEnable(enable); + }, "Enabled"_i18n, "Disabled"_i18n)); + + options->Add(std::make_shared("Install location"_i18n, install_items, [this](std::size_t& index_out){ + App::SetInstallSdEnable(index_out); + }, (std::size_t)App::GetInstallSdEnable())); + + options->Add(std::make_shared("Show install warning"_i18n, App::GetInstallPrompt(), [this](bool& enable){ + App::SetInstallPrompt(enable); + }, "Enabled"_i18n, "Disabled"_i18n)); })); }}) ); From 10f079e88121cd9c2668a868cd90847c0a2083e9 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:44:43 +0000 Subject: [PATCH 13/25] make progress popup a little nicer, store json timeout is now 1h, initial work on storing update changelog also removed the ability to cancel an update whilst unzipping the files, as this would result in a corrupted sphaira.nro install, which we don't want. --- sphaira/source/ui/menus/appstore.cpp | 6 +++--- sphaira/source/ui/menus/main_menu.cpp | 12 ++++++++---- sphaira/source/ui/option_box.cpp | 4 ++-- sphaira/source/ui/progress_box.cpp | 13 ++++++++++--- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/sphaira/source/ui/menus/appstore.cpp b/sphaira/source/ui/menus/appstore.cpp index eaf0627..5b15f55 100644 --- a/sphaira/source/ui/menus/appstore.cpp +++ b/sphaira/source/ui/menus/appstore.cpp @@ -472,7 +472,7 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> bool { } if (strncasecmp(md5_str, entry.md5.data(), entry.md5.length())) { - log_write("bad md5: %.*s vs %.*s\n", 32, md5_str, 32, entry.md5); + log_write("bad md5: %.*s vs %.*s\n", 32, md5_str, 32, entry.md5.c_str()); return false; } } @@ -1084,12 +1084,12 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"AppStore"_i18n} if (!time_stamp.is_valid) { download_file = true; } else { - // check the date, if older than 1day, then fetch new file + // check the date, if older than 1hour, then fetch new file // this relaxes the spam to their server, don't want to fetch repo // every time the user opens the app! const auto time_file = time_stamp.created; const auto time_cur = current_time; - const auto day = 60 * 60 * 24; + const auto day = 60 * 60; if (time_file > time_cur || time_cur - time_file >= day) { log_write("repo.json expired, downloading new! time_file: %zu time_cur: %zu\n", time_file, time_cur); download_file = true; diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 1e1192b..13fa8d3 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -117,10 +117,6 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v std::vector buf(chunk_size); u64 offset{}; while (offset < info.uncompressed_size) { - if (pbox->ShouldExit()) { - return false; - } - const auto bytes_read = unzReadCurrentFile(zfile, buf.data(), buf.size()); if (bytes_read <= 0) { // log_write("failed to read zip file: %s\n", inzip.c_str()); @@ -171,6 +167,12 @@ MainMenu::MainMenu() { return true; } + auto body_key = yyjson_obj_get(root, "body"); + R_UNLESS(body_key, false); + + const auto body = yyjson_get_str(body_key); + R_UNLESS(body, false); + auto assets = yyjson_obj_get(root, "assets"); R_UNLESS(assets, false); @@ -185,8 +187,10 @@ MainMenu::MainMenu() { m_update_version = version; m_update_url = url; + m_update_description = body; m_update_state = UpdateState::Update; log_write("found url: %s\n", url); + log_write("found body: %s\n", body); App::Notify("Update avaliable: "_i18n + m_update_version); return true; diff --git a/sphaira/source/ui/option_box.cpp b/sphaira/source/ui/option_box.cpp index 10463d3..3517fd7 100644 --- a/sphaira/source/ui/option_box.cpp +++ b/sphaira/source/ui/option_box.cpp @@ -51,8 +51,8 @@ OptionBox::OptionBox(const std::string& message, const Option& a, const Option& m_pos.w = 770.f; m_pos.h = 295.f; - m_pos.x = (1280.f / 2.f) - (m_pos.w / 2.f); - m_pos.y = (720.f / 2.f) - (m_pos.h / 2.f); + m_pos.x = (SCREEN_WIDTH / 2.f) - (m_pos.w / 2.f); + m_pos.y = (SCREEN_HEIGHT / 2.f) - (m_pos.h / 2.f); auto box = m_pos; box.w /= 2.f; diff --git a/sphaira/source/ui/progress_box.cpp b/sphaira/source/ui/progress_box.cpp index e7f624a..819e795 100644 --- a/sphaira/source/ui/progress_box.cpp +++ b/sphaira/source/ui/progress_box.cpp @@ -31,6 +31,12 @@ ProgressBox::ProgressBox(const std::string& title, ProgressBoxCallback callback, m_pos.h = 430.f; m_pos.x = 255; m_pos.y = 145; + 145 + 430; // 575, 200, 420 + + m_pos.w = 770.f; + m_pos.h = 295.f; + m_pos.x = (SCREEN_WIDTH / 2.f) - (m_pos.w / 2.f); + m_pos.y = (SCREEN_HEIGHT / 2.f) - (m_pos.h / 2.f); m_done = done; m_title = title; @@ -81,8 +87,9 @@ auto ProgressBox::Draw(NVGcontext* vg, Theme* theme) -> void { // The pop up shape. // const Vec4 box = { 255, 145, 770, 430 }; - const Vec4 prog_bar = { 400, 470, 480, 12 }; const auto center_x = m_pos.x + m_pos.w/2; + const auto end_y = m_pos.y + m_pos.h; + const Vec4 prog_bar = { 400, end_y - 80, 480, 12 }; // shapes. if (offset && size) { @@ -93,12 +100,12 @@ auto ProgressBox::Draw(NVGcontext* vg, Theme* theme) -> void { gfx::drawTextArgs(vg, prog_bar.x + prog_bar.w + 10, prog_bar.y, 20, NVG_ALIGN_LEFT | NVG_ALIGN_TOP, gfx::Colour::WHITE, "%u%%", percentage); } - gfx::drawTextArgs(vg, center_x, 200, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::WHITE, title.c_str()); + gfx::drawTextArgs(vg, center_x, m_pos.y + 60, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::WHITE, title.c_str()); // gfx::drawTextArgs(vg, center_x, 260, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::SILVER, "Please do not remove the gamecard or"); // gfx::drawTextArgs(vg, center_x, 295, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::SILVER, "power off the system whilst installing."); // gfx::drawTextArgs(vg, center_x, 360, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::WHITE, "%.2f MiB/s", 24.0); if (!transfer.empty()) { - gfx::drawTextArgs(vg, center_x, 420, 20, NVG_ALIGN_CENTER, gfx::Colour::WHITE, "%s", transfer.c_str()); + gfx::drawTextArgs(vg, center_x, prog_bar.y - 15 - 20 * 1.5, 20, NVG_ALIGN_CENTER, gfx::Colour::WHITE, "%s", transfer.c_str()); } } From e0040b625eb96925c74c256f9774bd6772d18368 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 20:11:22 +0000 Subject: [PATCH 14/25] remove unused strings from translations --- assets/romfs/i18n/de.json | 7 ++++--- assets/romfs/i18n/en.json | 9 +++++---- assets/romfs/i18n/es.json | 7 ++++--- assets/romfs/i18n/fr.json | 7 ++++--- assets/romfs/i18n/it.json | 7 ++++--- assets/romfs/i18n/ja.json | 9 +++++---- assets/romfs/i18n/ko.json | 9 +++++---- assets/romfs/i18n/nl.json | 7 ++++--- assets/romfs/i18n/pt.json | 7 ++++--- assets/romfs/i18n/ru.json | 7 ++++--- assets/romfs/i18n/se.json | 5 +++-- assets/romfs/i18n/zh.json | 7 ++++--- 12 files changed, 50 insertions(+), 38 deletions(-) diff --git a/assets/romfs/i18n/de.json b/assets/romfs/i18n/de.json index 02cc5b9..462e90a 100644 --- a/assets/romfs/i18n/de.json +++ b/assets/romfs/i18n/de.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Applet-Modus]", "No Internet": "Kein Internet", - "Fs": "Fs", - "App": "App", + "Files": "", + "Apps": "", + "Store": "", "Menu": "Menu", "Options": "Optionen", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "Mit dem Löschvorgang fortfahren?", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/en.json b/assets/romfs/i18n/en.json index e0dc5ba..9233502 100644 --- a/assets/romfs/i18n/en.json +++ b/assets/romfs/i18n/en.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Applet Mode]", "No Internet": "No Internet", - "Fs": "Fs", - "App": "App", + "Files": "Files", + "Apps": "Apps", + "Store": "Store", "Menu": "Menu", "Options": "Options", "OK": "OK", @@ -74,7 +75,7 @@ "Replace hbmenu on exit": "Replace hbmenu on exit", "Misc": "Misc", "Misc Options": "Misc Options", - "Web": "Web", + "Web": "Web", "FileBrowser": "FileBrowser", "%zd files": "%zd files", @@ -205,4 +206,4 @@ "Completely remove ": "Completely remove ", "Are you sure you want to delete ": "Are you sure you want to delete ", "Are you sure you wish to cancel?": "Are you sure you wish to cancel?" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/es.json b/assets/romfs/i18n/es.json index 213c51a..b6f6d6e 100644 --- a/assets/romfs/i18n/es.json +++ b/assets/romfs/i18n/es.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Modo subprograma]", "No Internet": "sin internet", - "Fs": "fs", - "App": "Aplicación", + "Files": "", + "Apps": "", + "Store": "", "Menu": "Menú", "Options": "Opciones", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "¿Estás seguro de que quieres eliminar? ", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/fr.json b/assets/romfs/i18n/fr.json index 4e4e594..1b808cd 100644 --- a/assets/romfs/i18n/fr.json +++ b/assets/romfs/i18n/fr.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Mode Applet]", "No Internet": "Pas d'Internet", - "Fs": "Fs", - "App": "App.", + "Files": "", + "Apps": "", + "Store": "", "Menu": "Menu", "Options": "Options", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "Êtes-vous sûr de vouloir supprimer ", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/it.json b/assets/romfs/i18n/it.json index 97c5421..f45462c 100644 --- a/assets/romfs/i18n/it.json +++ b/assets/romfs/i18n/it.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Modalità applet]", "No Internet": "Niente Internet", - "Fs": "Fs", - "App": "App", + "Files": "", + "Apps": "", + "Store": "", "Menu": "Menu", "Options": "Opzioni", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "Sei sicuro di voler eliminare? ", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/ja.json b/assets/romfs/i18n/ja.json index c401dcd..e9dec57 100644 --- a/assets/romfs/i18n/ja.json +++ b/assets/romfs/i18n/ja.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Appletモード]", "No Internet": "インターネットなし", - "Fs": "ファイル", - "App": "アプリ", + "Files": "", + "Apps": "", + "Store": "", "Menu": "メニュー", "Options": "設定", "OK": "確認", @@ -74,7 +75,7 @@ "Replace hbmenu on exit": "終了時に hbmenu を置き換える", "Misc": "その他", "Misc Options": "その他", - "Web": "ウェブブラウザ", + "Web": "ウェブブラウザ", "FileBrowser": "ファイルブラウザ", "%zd files": "%zd個のファイル", @@ -205,4 +206,4 @@ "Completely remove ": "除去しますか ", "Are you sure you want to delete ": "消去してもよろしいですか ", "Are you sure you wish to cancel?": "本当に取り消しますか?" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/ko.json b/assets/romfs/i18n/ko.json index 416cb76..bd53c9f 100644 --- a/assets/romfs/i18n/ko.json +++ b/assets/romfs/i18n/ko.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[애플릿 모드]", "No Internet": "네트워크 연결 없음", - "Fs": "파일 탐색기", - "App": "앱", + "Files": "", + "Apps": "", + "Store": "", "Menu": "메뉴", "Options": "설정", "OK": "확인", @@ -74,7 +75,7 @@ "Replace hbmenu on exit": "hbmenu를 교체", "Misc": "기타", "Misc Options": "기타", - "Web": "웹 브라우저", + "Web": "웹 브라우저", "FileBrowser": "파일 탐색기", "%zd files": "%zd개의 파일", @@ -205,4 +206,4 @@ "Completely remove ": "제거하시겠습니까 ", "Are you sure you want to delete ": "sdmc:", "Are you sure you wish to cancel?": "정말 취소하시겠습니까?" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/nl.json b/assets/romfs/i18n/nl.json index 2fb541d..0539ecb 100644 --- a/assets/romfs/i18n/nl.json +++ b/assets/romfs/i18n/nl.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Applet-modus]", "No Internet": "Geen internet", - "Fs": "Fs", - "App": "App", + "Files": "", + "Apps": "", + "Store": "", "Menu": "Menu", "Options": "Opties", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "Weet u zeker dat u wilt verwijderen ", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/pt.json b/assets/romfs/i18n/pt.json index 22d3548..f60a88d 100644 --- a/assets/romfs/i18n/pt.json +++ b/assets/romfs/i18n/pt.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Modo Applet]", "No Internet": "Sem Internet", - "Fs": "Fs", - "App": "Aplicativo", + "Files": "", + "Apps": "", + "Store": "", "Menu": "Menu", "Options": "Opções", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "Excluir ", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/ru.json b/assets/romfs/i18n/ru.json index 34cdd7a..63204d9 100644 --- a/assets/romfs/i18n/ru.json +++ b/assets/romfs/i18n/ru.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[Режим апплета]", "No Internet": "Нет Интернета", - "Fs": "Фс", - "App": "Приложение", + "Files": "", + "Apps": "", + "Store": "", "Menu": "Меню", "Options": "Параметры темы", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "Вы уверены, что хотите удалить ", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} diff --git a/assets/romfs/i18n/se.json b/assets/romfs/i18n/se.json index 9f32065..5280a97 100644 --- a/assets/romfs/i18n/se.json +++ b/assets/romfs/i18n/se.json @@ -19,8 +19,9 @@ "WARNING: Installing forwarders will lead to a ban!" : "VARNING: Att installera forwarders leder till en avstängning!", "Back" : "Tillbaka", "Install" : "Installera", - "Fs" : "Fs", - "App" : "App", + "Files": "", + "Apps": "", + "Store": "", "Menu" : "Meny", "Homebrew" : "Homebrew", "FileBrowser" : "Filbläddrare", diff --git a/assets/romfs/i18n/zh.json b/assets/romfs/i18n/zh.json index 3dfdd31..e72bd67 100644 --- a/assets/romfs/i18n/zh.json +++ b/assets/romfs/i18n/zh.json @@ -1,8 +1,9 @@ { "[Applet Mode]": "[小程序模式]", "No Internet": "网络未连接", - "Fs": "文件系统", - "App": "插件", + "Files": "", + "Apps": "", + "Store": "", "Menu": "菜单", "Options": "选项", "OK": "", @@ -205,4 +206,4 @@ "Completely remove ": "", "Are you sure you want to delete ": "您确定要删除吗 ", "Are you sure you wish to cancel?": "" -} \ No newline at end of file +} From 483b2b3ce0e8bf980a7da64da04043ec6263ae91 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 20:36:59 +0000 Subject: [PATCH 15/25] add option to restart sphaira upon installing an update --- sphaira/include/app.hpp | 4 +--- sphaira/source/app.cpp | 5 +++++ sphaira/source/ui/menus/main_menu.cpp | 10 +++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/sphaira/include/app.hpp b/sphaira/include/app.hpp index df15b97..4566021 100644 --- a/sphaira/include/app.hpp +++ b/sphaira/include/app.hpp @@ -42,6 +42,7 @@ class App { void Loop(); static void Exit(); + static void ExitRestart(); static auto GetVg() -> NVGcontext*; static void Push(std::shared_ptr); @@ -89,9 +90,6 @@ class App { void Update(); void Poll(); - void DrawBackground(); - void DrawTouch(); - // void DrawElement(float x, float y, float w, float h, ui::ThemeEntryID id); auto LoadElementImage(std::string_view value) -> ElementEntry; auto LoadElementColour(std::string_view value) -> ElementEntry; diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 578de27..9d5c603 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -505,6 +505,11 @@ void App::Exit() { g_app->m_quit = true; } +void App::ExitRestart() { + nro_launch(GetExePath()); + Exit(); +} + void App::Poll() { m_controller.Reset(); diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 13fa8d3..6823738 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -205,7 +205,6 @@ MainMenu::MainMenu() { auto options = std::make_shared("Menu Options"_i18n, "v" APP_VERSION_HASH, Sidebar::Side::LEFT); ON_SCOPE_EXIT(App::Push(options)); - SidebarEntryArray::Items language_items; language_items.push_back("Auto"_i18n); language_items.push_back("English"_i18n); @@ -261,6 +260,15 @@ MainMenu::MainMenu() { }, [this](bool success){ if (success) { m_update_state = UpdateState::None; + App::Notify("Updated to "_i18n + m_update_version); + App::Push(std::make_shared( + "Restart Sphaira?"_i18n, + "Back"_i18n, "Restart"_i18n, 1, [this](auto op_index){ + if (op_index && *op_index) { + App::ExitRestart(); + } + } + )); } else { App::Push(std::make_shared(MAKERESULT(351, 1), "Failed to download update"_i18n)); } From 372399a27de9cc8b736940d9bb4379f7529ef1c0 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 21:18:13 +0000 Subject: [PATCH 16/25] remove more unused strings --- assets/romfs/i18n/de.json | 2 -- assets/romfs/i18n/en.json | 2 -- assets/romfs/i18n/es.json | 3 +-- assets/romfs/i18n/fr.json | 2 -- assets/romfs/i18n/it.json | 2 -- assets/romfs/i18n/ja.json | 2 -- assets/romfs/i18n/ko.json | 2 -- assets/romfs/i18n/nl.json | 2 -- assets/romfs/i18n/pt.json | 2 -- assets/romfs/i18n/ru.json | 2 -- assets/romfs/i18n/se.json | 1 - assets/romfs/i18n/zh.json | 2 -- 12 files changed, 1 insertion(+), 23 deletions(-) diff --git a/assets/romfs/i18n/de.json b/assets/romfs/i18n/de.json index 462e90a..87d5099 100644 --- a/assets/romfs/i18n/de.json +++ b/assets/romfs/i18n/de.json @@ -98,8 +98,6 @@ "Create Folder": "Ordner erstellen", "Set Folder Name": "", "View as text (unfinished)": "Als Text anzeigen (unfertig)", - "Set Archive Bit": "Archivbit setzen", - "Warning! Setting the archive bit cannot be undone!": "", "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", diff --git a/assets/romfs/i18n/en.json b/assets/romfs/i18n/en.json index 9233502..735c4e9 100644 --- a/assets/romfs/i18n/en.json +++ b/assets/romfs/i18n/en.json @@ -98,8 +98,6 @@ "Create Folder": "Create Folder", "Set Folder Name": "Set Folder Name", "View as text (unfinished)": "View as text (unfinished)", - "Set Archive Bit": "Set Archive Bit", - "Warning! Setting the archive bit cannot be undone!": "Warning! Setting the archive bit cannot be undone!", "Empty...": "Empty...", "Open with DayBreak?": "Open with DayBreak?", "Launch option for: ": "Launch option for: ", diff --git a/assets/romfs/i18n/es.json b/assets/romfs/i18n/es.json index b6f6d6e..91018a6 100644 --- a/assets/romfs/i18n/es.json +++ b/assets/romfs/i18n/es.json @@ -98,8 +98,7 @@ "Create Folder": "Crear carpeta", "Set Folder Name": "", "View as text (unfinished)": "Ver como texto (sin terminar)", - "Set Archive Bit": "Establecer bit de archivo", - "Warning! Setting the archive bit cannot be undone!": "", + "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", diff --git a/assets/romfs/i18n/fr.json b/assets/romfs/i18n/fr.json index 1b808cd..257ae81 100644 --- a/assets/romfs/i18n/fr.json +++ b/assets/romfs/i18n/fr.json @@ -98,8 +98,6 @@ "Create Folder": "Créer un Dossier", "Set Folder Name": "", "View as text (unfinished)": "Afficher sous forme de texte (inachevé)", - "Set Archive Bit": "Définir le Bit d'Archive", - "Warning! Setting the archive bit cannot be undone!": "", "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", diff --git a/assets/romfs/i18n/it.json b/assets/romfs/i18n/it.json index f45462c..2837f4a 100644 --- a/assets/romfs/i18n/it.json +++ b/assets/romfs/i18n/it.json @@ -98,8 +98,6 @@ "Create Folder": "Crea cartella", "Set Folder Name": "", "View as text (unfinished)": "Visualizza come testo (non finito)", - "Set Archive Bit": "Imposta Archive Bit", - "Warning! Setting the archive bit cannot be undone!": "", "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", diff --git a/assets/romfs/i18n/ja.json b/assets/romfs/i18n/ja.json index e9dec57..7469939 100644 --- a/assets/romfs/i18n/ja.json +++ b/assets/romfs/i18n/ja.json @@ -98,8 +98,6 @@ "Create Folder": "フォルダーの作成", "Set Folder Name": "名前を入力", "View as text (unfinished)": "テキストとして表示 (未完成)", - "Set Archive Bit": "アーカイブビットの設定", - "Warning! Setting the archive bit cannot be undone!": "警告: アーカイブビットの設定は取り消せません!", "Empty...": "このフォルダーは空です", "Open with DayBreak?": "DayBreakで開きますか?", "Launch option for: ": "起動設定: ", diff --git a/assets/romfs/i18n/ko.json b/assets/romfs/i18n/ko.json index bd53c9f..4b22a15 100644 --- a/assets/romfs/i18n/ko.json +++ b/assets/romfs/i18n/ko.json @@ -98,8 +98,6 @@ "Create Folder": "새 폴더", "Set Folder Name": "폴더명 입력", "View as text (unfinished)": "텍스트로 보기 (미완성)", - "Set Archive Bit": "아카이브 비트 설정", - "Warning! Setting the archive bit cannot be undone!": "경고: 아카이브 비트 설정은 취소할 수 없습니다!", "Empty...": "비어있습니다...", "Open with DayBreak?": "DayBreak로 여시겠습니까?", "Launch option for: ": "실행 옵션: ", diff --git a/assets/romfs/i18n/nl.json b/assets/romfs/i18n/nl.json index 0539ecb..3655bb3 100644 --- a/assets/romfs/i18n/nl.json +++ b/assets/romfs/i18n/nl.json @@ -98,8 +98,6 @@ "Create Folder": "Map maken", "Set Folder Name": "", "View as text (unfinished)": "Bekijk als tekst (onvoltooid)", - "Set Archive Bit": "Archiefbit instellen", - "Warning! Setting the archive bit cannot be undone!": "", "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", diff --git a/assets/romfs/i18n/pt.json b/assets/romfs/i18n/pt.json index f60a88d..330a5a2 100644 --- a/assets/romfs/i18n/pt.json +++ b/assets/romfs/i18n/pt.json @@ -98,8 +98,6 @@ "Create Folder": "Criar pasta", "Set Folder Name": "", "View as text (unfinished)": "Ver como texto (inacabado)", - "Set Archive Bit": "Definir bit de arquivo", - "Warning! Setting the archive bit cannot be undone!": "", "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", diff --git a/assets/romfs/i18n/ru.json b/assets/romfs/i18n/ru.json index 63204d9..23a589f 100644 --- a/assets/romfs/i18n/ru.json +++ b/assets/romfs/i18n/ru.json @@ -98,8 +98,6 @@ "Create Folder": "Создать папку", "Set Folder Name": "", "View as text (unfinished)": "Посмотреть как текст (незакончено)", - "Set Archive Bit": "Установить Archive Bit", - "Warning! Setting the archive bit cannot be undone!": "", "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", diff --git a/assets/romfs/i18n/se.json b/assets/romfs/i18n/se.json index 5280a97..81ff362 100644 --- a/assets/romfs/i18n/se.json +++ b/assets/romfs/i18n/se.json @@ -47,7 +47,6 @@ "Create Folder" : "Skapa mapp", "View as text" : "Visa som text", "View as text (unfinished)" : "Visa som text (ofärdig)", - "Set Archive Bit" : "Ordna Archive Bit", "AppStore Options" : "AppStore-alternativ", "All" : "Alla", "Games" : "Spel", diff --git a/assets/romfs/i18n/zh.json b/assets/romfs/i18n/zh.json index e72bd67..daa8f28 100644 --- a/assets/romfs/i18n/zh.json +++ b/assets/romfs/i18n/zh.json @@ -98,8 +98,6 @@ "Create Folder": "新建文件夹", "Set Folder Name": "", "View as text (unfinished)": "以文本形式查看(未完善)", - "Set Archive Bit": "设置存档标志", - "Warning! Setting the archive bit cannot be undone!": "", "Empty...": "", "Open with DayBreak?": "", "Launch option for: ": "", From 38640ea6960a432efa56f0376b726636d34ce29d Mon Sep 17 00:00:00 2001 From: shadow2560 <24191064+shadow2560@users.noreply.github.com> Date: Sat, 21 Dec 2024 22:49:01 +0100 Subject: [PATCH 17/25] Update french translation (#35) Signed-off-by: shadow2560 <24191064+shadow2560@users.noreply.github.com> --- assets/romfs/i18n/fr.json | 148 +++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/assets/romfs/i18n/fr.json b/assets/romfs/i18n/fr.json index 257ae81..4f64248 100644 --- a/assets/romfs/i18n/fr.json +++ b/assets/romfs/i18n/fr.json @@ -1,23 +1,23 @@ { "[Applet Mode]": "[Mode Applet]", "No Internet": "Pas d'Internet", - "Files": "", - "Apps": "", - "Store": "", + "Files": "Fichiers", + "Apps": "Applications", + "Store": "Magasin", "Menu": "Menu", "Options": "Options", - "OK": "", + "OK": "OK", "Back": "Retour", - "Select": "", + "Select": "Sélectionner", "Open": "Ouvrir", "Launch": "Exécuter", "Info": "Info.", "Install": "Installer", "Delete": "Supprimer", - "Changelog": "", - "Details": "", - "Update": "", - "Remove": "", + "Changelog": "Changelog", + "Details": "Détails", + "Update": "Mise à jour", + "Remove": "Supprimer", "Download": "Télécharger", "Next Page": "Page Suiv.", "Prev Page": "Page Préc.", @@ -36,8 +36,8 @@ "Downloads": "Téléchargements", "Size": "Taille", "Alphabetical": "Alphabétique", - "Likes": "", - "ID": "", + "Likes": "Favoris", + "ID": "ID", "Decending": "Décroissant", "Descending (down)": "Décroissant", "Desc": "Décroissant", @@ -55,11 +55,11 @@ "Network": "Réseau", "Network Options": "Options Réseau", "Nxlink": "Nxlink", - "Nxlink Connected": "", - "Nxlink Upload": "", - "Nxlink Finished": "", + "Nxlink Connected": "Nxlink Connecté", + "Nxlink Upload": "Nxlink téléversement", + "Nxlink Finished": "Nxlink terminé", "Language": "Langue", - "Auto": "", + "Auto": "Auto", "English": "English", "Japanese": "日本語", "French": "Français", @@ -72,52 +72,52 @@ "Portuguese": "Português", "Russian": "Русский", "Logging": "Journalisation", - "Replace hbmenu on exit": "Remplacer hbmenu en sortie", + "Replace hbmenu on exit": "Remplacer hbmenu quand quitté", "Misc": "Divers", "Misc Options": "Options Diverses", "Web": "Web", - "FileBrowser": "Navigateur de Fichiers", - "%zd files": "%zd files", - "%zd dirs": "%zd dirs", + "FileBrowser": "Explorateur de Fichiers", + "%zd files": "%zd fichiers", + "%zd dirs": "%zd dossiers", "File Options": "Options de Fichier", "Show Hidden": "Afficher Masqués", "Folders First": "Dossiers en Premier", "Hidden Last": "Masqués en Dernier", "Cut": "Couper", "Copy": "Copier", - "Paste": "", - "Paste ": "", - " file(s)?": "", + "Paste": "Coller", + "Paste ": "Coller ", + " file(s)?": " fichier(s)?", "Rename": "Renommer", - "Set New File Name": "", + "Set New File Name": "Nouveau Nom Du Fichier", "Advanced": "Avancé", "Advanced Options": "Options Avancées", "Create File": "Créer un Fichier", - "Set File Name": "", + "Set File Name": "Nommer Le Fichier", "Create Folder": "Créer un Dossier", - "Set Folder Name": "", + "Set Folder Name": "Nommer Le Dossier", "View as text (unfinished)": "Afficher sous forme de texte (inachevé)", - "Empty...": "", - "Open with DayBreak?": "", - "Launch option for: ": "", + "Empty...": "Vide...", + "Open with DayBreak?": "Ouvrir avec DayBreak?", + "Launch option for: ": "Option de lancement pour: ", "Homebrew": "Homebrew", "Homebrew Options": "Options Homebrew", "Hide Sphaira": "Masquer Sphaira", "Install Forwarder": "Installer le Forwarder", "WARNING: Installing forwarders will lead to a ban!": "ATTENTION: L'installation de forwarders entraînera un ban!", - "Installing Forwarder": "", - "Creating Program": "", - "Creating Control": "", - "Creating Meta": "", - "Writing Nca": "", - "Updating ncm databse": "", - "Pushing application record": "", - "Installed!": "", - "Failed to install forwarder": "", + "Installing Forwarder": "Installation Du Forwarder", + "Creating Program": "Création de Program", + "Creating Control": "Création de Control", + "Creating Meta": "Création de Meta", + "Writing Nca": "Ecriture NCA", + "Updating ncm databse": "Mise à jour de ncm databse", + "Pushing application record": "Ajout de l'enregistrement de l'application", + "Installed!": "Installé!", + "Failed to install forwarder": "Echec de l'installation du forwarder", - "AppStore": "", + "AppStore": "AppStore", "Filter: %s | Sort: %s | Order: %s": "Filtre: %s | Tri: %s | Ordre: %s", "AppStore Options": "Options de l'AppStore", "All": "Tous", @@ -127,15 +127,15 @@ "Themes": "Thèmes", "Legacy": "Legacy", "version: %s": "version: %s", - "updated: %s": "updated: %s", - "category: %s": "category: %s", - "extracted: %.2f MiB": "extracted: %.2f MiB", + "updated: %s": "Mis à jour: %s", + "category: %s": "catégorie: %s", + "extracted: %.2f MiB": "Extrait: %.2f MiB", "app_dls: %s": "app_dls: %s", - "More by Author": "", - "Leave Feedback": "", + "More by Author": "Plus de cet Auteur", + "Leave Feedback": "Laisser un avis", "Irs": "Irs", - "Ambient Noise Level: ": "", + "Ambient Noise Level: ": "Niveau De Bruit Ambiant: ", "Controller": "Contrôleur", "Pad ": "Manette ", " (Available)": " (Disponible)", @@ -172,36 +172,36 @@ "Load Default": "Charger par Défaut", "Themezer": "Themezer", - "Themezer Options": "", - "Nsfw": "", - "Page": "", + "Themezer Options": "Options Themezer", + "Nsfw": "Nsfw", + "Page": "Page", "Page %zu / %zu": "Page %zu / %zu", - "Enter Page Number": "", - "Bad Page": "", - "Download theme?": "", + "Enter Page Number": "Entrez Un Numéro De Page", + "Bad Page": "Page inexistante", + "Download theme?": "Télécharger le thème?", - "Installing ": "", - "Uninstalling ": "", - "Deleting ": "", - "Deleting": "", - "Pasting ": "", - "Pasting": "", - "Removing ": "", - "Scanning ": "", - "Creating ": "", - "Copying ": "", - "Downloading ": "", - "Checking MD5": "", - "Loading...": "", - "Loading": "", - "Empty!": "", - "Not Ready...": "", - "Error loading page!": "", - "Update avaliable: ": "", - "Download update: ": "", - "Failed to download update": "", - "Delete Selected files?": "", - "Completely remove ": "", + "Installing ": "Installation ", + "Uninstalling ": "Désinstallation ", + "Deleting ": "Suppression ", + "Deleting": "Suppression", + "Pasting ": "Coller ", + "Pasting": "Coller", + "Removing ": "Suppression ", + "Scanning ": "Scan ", + "Creating ": "Création ", + "Copying ": "Copie ", + "Downloading ": "Téléchargement ", + "Checking MD5": "Vérification MD5", + "Loading...": "Chargement...", + "Loading": "Chargement", + "Empty!": "Vide!", + "Not Ready...": "Pas prêt", + "Error loading page!": "Erreur du chargement de la page!", + "Update avaliable: ": "Mise à jour disponible: ", + "Download update: ": "Télécharger la mise à jour: ", + "Failed to download update": "Echec du téléchargement de la mise à jour", + "Delete Selected files?": "Supprimer les fichiers sélectionnés?", + "Completely remove ": "Supprimer totalement ", "Are you sure you want to delete ": "Êtes-vous sûr de vouloir supprimer ", - "Are you sure you wish to cancel?": "" -} + "Are you sure you wish to cancel?": "Souhaitez-vous vraiment annuler?" +} \ No newline at end of file From 536c169255d619fd1bbddf25ccfe47d5680e1580 Mon Sep 17 00:00:00 2001 From: HenryBaby Date: Sat, 21 Dec 2024 22:49:21 +0100 Subject: [PATCH 18/25] Updated Swedish translation (#36) --- assets/romfs/i18n/se.json | 317 ++++++++++++++++++++++++-------------- 1 file changed, 205 insertions(+), 112 deletions(-) diff --git a/assets/romfs/i18n/se.json b/assets/romfs/i18n/se.json index 81ff362..fefbe49 100644 --- a/assets/romfs/i18n/se.json +++ b/assets/romfs/i18n/se.json @@ -1,114 +1,207 @@ { - "Launch" : "Starta", - "Options" : "Alternativ", - "Homebrew Options" : "Homebrew-alternativ", - "Sort By" : "Sortera efter", - "Sort Options" : "Sorteringsalternativ", - "Updated" : "Uppdaterad", - "Size" : "Storlek", - "Alphabetical" : "Alfabetisk", - "Decending" : "Fallande", - "Ascending" : "Stigande", - "Sort" : "Sortera", - "Order" : "Ordning", - "Info" : "Info", - "Delete" : "Radera", - "Hide Sphaira" : "Dölj Sphaira", - "Are you sure you want to delete " : "Är du säker på att du vill radera ", - "Install Forwarder" : "Installera forwarder", - "WARNING: Installing forwarders will lead to a ban!" : "VARNING: Att installera forwarders leder till en avstängning!", - "Back" : "Tillbaka", - "Install" : "Installera", - "Files": "", - "Apps": "", - "Store": "", - "Menu" : "Meny", - "Homebrew" : "Homebrew", - "FileBrowser" : "Filbläddrare", - "Open" : "Öppna", - "Theme Options" : "Temaalternativ", - "Select Theme" : "Välj tema", - "Shuffle" : "Blanda", - "Music" : "Musik", - "Show Hidden" : "Visa dolda", - "Folders First" : "Mappar först", - "Hidden Last" : "Dolda sist", - "Yes" : "Ja", - "No" : "Nej", - "Network Options" : "Nätverksalternativ", - "Nxlink" : "Nxlink", - "Check for update" : "Sök efter uppdatering", - "File Options" : "Filalternativ", - "Cut" : "Klipp ut", - "Copy" : "Kopiera", - "Rename" : "Byt namn", - "Advanced Options" : "Avancerade alternativ", - "Create File" : "Skapa fil", - "Create Folder" : "Skapa mapp", - "View as text" : "Visa som text", - "View as text (unfinished)" : "Visa som text (ofärdig)", - "AppStore Options" : "AppStore-alternativ", - "All" : "Alla", - "Games" : "Spel", - "Emulators" : "Emulatorer", - "Tools" : "Verktyg", - "Advanced" : "Avancerat", - "Themes" : "Teman", - "Legacy" : "Legacy", - "Misc" : "Övrigt", - "Downloads" : "Nedladdningar", - "Filter" : "Filter", - "Search" : "Sök", - "Menu Options" : "Menyalternativ", - "Header" : "Rubrik", - "Theme" : "Tema", - "Network" : "Nätverk", - "Logging" : "Loggning", - "Enabled" : "Aktiverad", - "Disabled" : "Avaktiverad", - "Replace hbmenu on exit" : "Ersätt hbmenu vid avslut", - "Misc Options" : "Övriga alternativ", - "Themezer" : "Themezer", - "Irs" : "Irs", - "Web" : "Webb", - "Download" : "Ladda ner", - "Next Page" : "Nästa sida", - "Prev Page" : "Föregående sida", - "Pad " : "Handkontroll ", - " (Unconnected)" : " (Ej ansluten)", - "HandHeld" : "Handhållen", - " (Available)" : " (Tillgänglig)", - "0 (Sideways)" : "0 (Sido)", - "90 (Flat)" : "90 (Platt)", - "180 (-Sideways)" : "180 (-Sido)", - "270 (Upside down)" : "270 (Upp och ner)", - "Grey" : "Grå", - "Ironbow" : "Ironbow", - "Green" : "Grön", - "Red" : "Röd", - "Blue" : "Blå", - "All leds" : "Alla lysdioder", - "Bright group" : "Ljusstark grupp", - "Dim group" : "Dämpad grupp", - "None" : "Ingen", - "Normal image" : "Normal bild", - "Negative image" : "Negativ bild", - "320x240" : "320x240", - "160x120" : "160x120", - "80x60" : "80x60", - "40x30" : "40x30", - "20x15" : "20x15", - "Controller" : "Kontroll", - "Rotation" : "Rotation", - "Colour" : "Färg", - "Light Target" : "Ljusmål", - "Gain" : "Förstärkning", - "Negative Image" : "Negativ bild", - "Format" : "Format", - "Trimming Format" : "Trimformat", - "External Light Filter" : "Extern ljusfilter", - "Load Default" : "Ladda standard", - "No Internet" : "Ingen internetanslutning", - "[Applet Mode]" : "[Applet-läge]", - "Language": "Språk" + "[Applet Mode]": "[Applet-läge]", + "No Internet": "Ingen internetanslutning", + "Files": "Filer", + "Apps": "Appar", + "Store": "Butik", + "Menu": "Meny", + "Options": "Alternativ", + "OK": "OK", + "Back": "Tillbaka", + "Select": "Välj", + "Open": "Öppna", + "Launch": "Starta", + "Info": "Info", + "Install": "Installera", + "Delete": "Radera", + "Changelog": "Ändringslogg", + "Details": "Detaljer", + "Update": "Uppdatera", + "Remove": "Ta bort", + "Download": "Ladda ner", + "Next Page": "Nästa sida", + "Prev Page": "Föregående sida", + "Yes": "Ja", + "No": "Nej", + "Enabled": "Aktiverad", + "Disabled": "Avaktiverad", + + "Sort By": "Sortera efter", + "Sort Options": "Sorteringsalternativ", + "Filter": "Filter", + "Sort": "Sortera", + "Order": "Ordning", + "Search": "Sök", + "Updated": "Uppdaterad", + "Downloads": "Nedladdningar", + "Size": "Storlek", + "Alphabetical": "Alfabetisk", + "Likes": "Gillar", + "ID": "ID", + "Decending": "Fallande", + "Descending (down)": "Fallande (nedåt)", + "Desc": "Fallande", + "Ascending": "Stigande", + "Ascending (Up)": "Stigande (uppåt)", + "Asc": "Stigande", + + "Menu Options": "Menyalternativ", + "Header": "Rubrik", + "Theme": "Tema", + "Theme Options": "Temaalternativ", + "Select Theme": "Välj tema", + "Shuffle": "Blanda", + "Music": "Musik", + "Network": "Nätverk", + "Network Options": "Nätverksalternativ", + "Nxlink": "Nxlink", + "Nxlink Connected": "Nxlink ansluten", + "Nxlink Upload": "Nxlink uppladdning", + "Nxlink Finished": "Nxlink klar", + "Language": "Språk", + "Auto": "Auto", + "English": "Engelska", + "Japanese": "Japanska", + "French": "Franska", + "German": "Tyska", + "Italian": "Italienska", + "Spanish": "Spanska", + "Chinese": "Kinesiska", + "Korean": "Koreanska", + "Dutch": "Holländska", + "Portuguese": "Portugisiska", + "Russian": "Ryska", + "Logging": "Loggning", + "Replace hbmenu on exit": "Ersätt hbmenu vid avslut", + "Misc": "Övrigt", + "Misc Options": "Övriga alternativ", + "Web": "Webb", + + "FileBrowser": "Filbläddrare", + "%zd files": "%zd filer", + "%zd dirs": "%zd kataloger", + "File Options": "Filalternativ", + "Show Hidden": "Visa dolda", + "Folders First": "Mappar först", + "Hidden Last": "Dolda sist", + "Cut": "Klipp ut", + "Copy": "Kopiera", + "Paste": "Klistra in", + "Paste ": "Klistra in ", + " file(s)?": " fil(er)?", + "Rename": "Byt namn", + "Set New File Name": "Ange nytt filnamn", + "Advanced": "Avancerat", + "Advanced Options": "Avancerade alternativ", + "Create File": "Skapa fil", + "Set File Name": "Ange filnamn", + "Create Folder": "Skapa mapp", + "Set Folder Name": "Ange mappnamn", + "View as text (unfinished)": "Visa som text (ofärdig)", + "Empty...": "Tom...", + "Open with DayBreak?": "Öppna med DayBreak?", + "Launch option for: ": "Startalternativ för: ", + + "Homebrew": "Homebrew", + "Homebrew Options": "Homebrew-alternativ", + "Hide Sphaira": "Dölj Sphaira", + "Install Forwarder": "Installera forwarder", + "WARNING: Installing forwarders will lead to a ban!": "VARNING: Att installera forwarders leder till en avstängning!", + "Installing Forwarder": "Installerar forwarder", + "Creating Program": "Skapar program", + "Creating Control": "Skapar kontroll", + "Creating Meta": "Skapar meta", + "Writing Nca": "Skriver Nca", + "Updating ncm databse": "Uppdaterar ncm-databas", + "Pushing application record": "Lägger till applikationspost", + "Installed!": "Installerad!", + "Failed to install forwarder": "Misslyckades med att installera forwarder", + + "AppStore": "AppStore", + "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sortering: %s | Ordning: %s", + "AppStore Options": "AppStore-alternativ", + "All": "Alla", + "Games": "Spel", + "Emulators": "Emulatorer", + "Tools": "Verktyg", + "Themes": "Teman", + "Legacy": "Legacy", + "version: %s": "version: %s", + "updated: %s": "uppdaterad: %s", + "category: %s": "kategori: %s", + "extracted: %.2f MiB": "extraherad: %.2f MiB", + "app_dls: %s": "app_nedladdningar: %s", + "More by Author": "Mer från författaren", + "Leave Feedback": "Lämna feedback", + + "Irs": "Irs", + "Ambient Noise Level: ": "Omgivningsljudnivå: ", + "Controller": "Kontroll", + "Pad ": "Handkontroll ", + " (Available)": " (Tillgänglig)", + " (Unconnected)": " (Ej ansluten)", + "HandHeld": "Handhållen", + "Rotation": "Rotation", + "0 (Sideways)": "0 (Sido)", + "90 (Flat)": "90 (Platt)", + "180 (-Sideways)": "180 (-Sido)", + "270 (Upside down)": "270 (Upp och ner)", + "Colour": "Färg", + "Grey": "Grå", + "Ironbow": "Ironbow", + "Green": "Grön", + "Red": "Röd", + "Blue": "Blå", + "Light Target": "Ljusmål", + "All leds": "Alla lysdioder", + "Bright group": "Ljusstark grupp", + "Dim group": "Dämpad grupp", + "None": "Ingen", + "Gain": "Förstärkning", + "Negative Image": "Negativ bild", + "Normal image": "Normal bild", + "Negative image": "Negativ bild", + "Format": "Format", + "320x240": "320×240", + "160x120": "160×120", + "80x60": "80×60", + "40x30": "40×30", + "20x15": "20×15", + "Trimming Format": "Trimformat", + "External Light Filter": "Extern ljusfilter", + "Load Default": "Ladda standardinställningar", + + "Themezer": "Themezer", + "Themezer Options": "Themezer-alternativ", + "Nsfw": "Nsfw", + "Page": "Sida", + "Page %zu / %zu": "Sida %zu / %zu", + "Enter Page Number": "Ange sidnummer", + "Bad Page": "Ogiltig sida", + "Download theme?": "Ladda ner tema?", + + "Installing ": "Installerar ", + "Uninstalling ": "Avinstallerar ", + "Deleting ": "Raderar ", + "Deleting": "Raderar", + "Pasting ": "Klistrar in ", + "Pasting": "Klistrar in", + "Removing ": "Tar bort ", + "Scanning ": "Skannar ", + "Creating ": "Skapar ", + "Copying ": "Kopierar ", + "Downloading ": "Laddar ner ", + "Checking MD5": "Kontrollerar MD5", + "Loading...": "Laddar...", + "Loading": "Laddar", + "Empty!": "Tomt!", + "Not Ready...": "Ej redo...", + "Error loading page!": "Fel vid laddning av sida!", + "Update avaliable: ": "Uppdatering tillgänglig: ", + "Download update: ": "Ladda ner uppdatering: ", + "Failed to download update": "Misslyckades med att ladda ner uppdatering", + "Delete Selected files?": "Radera valda filer?", + "Completely remove ": "Ta bort helt ", + "Are you sure you want to delete ": "Är du säker på att du vill radera ", + "Are you sure you wish to cancel?": "Är du säker på att du vill avbryta?" } From 17b622833a5a3a69720250cf3550c9c70743877b Mon Sep 17 00:00:00 2001 From: cucholix Date: Mon, 23 Dec 2024 01:55:38 -0300 Subject: [PATCH 19/25] Update es.json (#38) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced some lower case chars to match English style. Replaced some words like Homebrew, AppStore, IRS, etc… that doesn’t have direct meaning in Spanish, literal translation sound awkward so it’s better leave them in English. Filled out missing translations. --- assets/romfs/i18n/es.json | 210 +++++++++++++++++++------------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/assets/romfs/i18n/es.json b/assets/romfs/i18n/es.json index 91018a6..3697187 100644 --- a/assets/romfs/i18n/es.json +++ b/assets/romfs/i18n/es.json @@ -1,23 +1,23 @@ { - "[Applet Mode]": "[Modo subprograma]", - "No Internet": "sin internet", - "Files": "", - "Apps": "", - "Store": "", + "[Applet Mode]": "[Modo Applet]", + "No Internet": "Sin Internet", + "Files": "Archivos", + "Apps": "Apps", + "Store": "Tienda", "Menu": "Menú", "Options": "Opciones", - "OK": "", + "OK": "OK", "Back": "Atrás", - "Select": "", + "Select": "Seleccionar", "Open": "Abierto", - "Launch": "Lanzamiento", + "Launch": "Ejecutar", "Info": "Información", "Install": "Instalar", "Delete": "Borrar", - "Changelog": "", - "Details": "", - "Update": "", - "Remove": "", + "Changelog": "Log de Cambios", + "Details": "Detalles", + "Update": "Actualizar", + "Remove": "Borrar", "Download": "Descargar", "Next Page": "Página siguiente", "Prev Page": "Página anterior", @@ -36,30 +36,30 @@ "Downloads": "Descargas", "Size": "Tamaño", "Alphabetical": "Alfabético", - "Likes": "", - "ID": "", + "Likes": "Me Gusta", + "ID": "ID", "Decending": "Descendente", - "Descending (down)": "Descendente", + "Descending (down)": "Descendente (abajo)", "Desc": "Descendente", "Ascending": "Ascendente", - "Ascending (Up)": "Ascendente", + "Ascending (Up)": "Ascendente (arriba)", "Asc": "Ascendente", - "Menu Options": "Opciones de menú", + "Menu Options": "Opciones de Menú", "Header": "Encabezamiento", "Theme": "Tema", - "Theme Options": "Opciones de tema", - "Select Theme": "Seleccionar tema", + "Theme Options": "Opciones de Tema", + "Select Theme": "Seleccionar Tema", "Shuffle": "Barajar", "Music": "Música", "Network": "Red", - "Network Options": "Opciones de red", + "Network Options": "Opciones de Red", "Nxlink": "Nxlink", - "Nxlink Connected": "", - "Nxlink Upload": "", - "Nxlink Finished": "", + "Nxlink Connected": "Nxlink Conectado", + "Nxlink Upload": "Nxlink Subida", + "Nxlink Finished": "Nxlink Finalizado", "Language": "Idioma", - "Auto": "", + "Auto": "Automático", "English": "English", "Japanese": "日本語", "French": "Français", @@ -77,50 +77,50 @@ "Misc Options": "Opciones varias", "Web": "Web", - "FileBrowser": "Explorador de archivos", + "FileBrowser": "Explorador de Archivos", "%zd files": "%zd files", "%zd dirs": "%zd dirs", - "File Options": "Opciones de tema", - "Show Hidden": "Mostrar oculto", + "File Options": "Opciones de Tema", + "Show Hidden": "Mostrar Oculto", "Folders First": "Carpetas primero", "Hidden Last": "Oculto último", - "Cut": "Cortar", + "Cut": "Cortar ", "Copy": "Copiar", - "Paste": "", - "Paste ": "", - " file(s)?": "", - "Rename": "Rebautizar", - "Set New File Name": "", + "Paste": "Pegar", + "Paste ": "Pegar ", + " file(s)?": " ¿archivo(s)?", + "Rename": "Renombrar", + "Set New File Name": "Establecer Nuevo Nombre de Archivo", "Advanced": "Avanzado", - "Advanced Options": "Crear archivo", + "Advanced Options": "Opciones Avanzadas", "Create File": "Crear archivo", - "Set File Name": "", + "Set File Name": "Establecer Nombre de Archivo", "Create Folder": "Crear carpeta", - "Set Folder Name": "", + "Set Folder Name": "Establecer Nombre de Carpeta", "View as text (unfinished)": "Ver como texto (sin terminar)", - "Empty...": "", - "Open with DayBreak?": "", - "Launch option for: ": "", + "Empty...": "Vacío...", + "Open with DayBreak?": "Abrir con DayBreak", + "Launch option for: ": "Opción de ejecución para: ", - "Homebrew": "cerveza casera", - "Homebrew Options": "Opciones de elaboración casera", + "Homebrew": "Honebrew", + "Homebrew Options": "Opciones de Homebrew", "Hide Sphaira": "Ocultar Sphaira", - "Install Forwarder": "Instalar reenviador", - "WARNING: Installing forwarders will lead to a ban!": "ADVERTENCIA: ¡La instalación de reenviadores dará lugar a una prohibición!", - "Installing Forwarder": "", - "Creating Program": "", - "Creating Control": "", - "Creating Meta": "", - "Writing Nca": "", - "Updating ncm databse": "", + "Install Forwarder": "Instalar Forwarder", + "WARNING: Installing forwarders will lead to a ban!": "ADVERTENCIA: ¡La instalación de fordwarders podría producir un baneo de la consola!", + "Installing Forwarder": "Instalando Forwarder", + "Creating Program": "Creando Program", + "Creating Control": "Creando Control", + "Creating Meta": "Creando Meta", + "Writing Nca": "Creando NCA", + "Updating ncm databse": "Actualizando base de datos ncm ", "Pushing application record": "", - "Installed!": "", - "Failed to install forwarder": "", + "Installed!": "¡Instalado!", + "Failed to install forwarder": "Fallo al instalar forwarder", - "AppStore": "", + "AppStore": "AppStore", "Filter: %s | Sort: %s | Order: %s": "Filtrar: %s | Clasificar: %s | Orden: %s", - "AppStore Options": "Opciones de la tienda de aplicaciones", + "AppStore Options": "Opciones de la AppStore", "All": "Todo", "Games": "Juegos", "Emulators": "Emuladores", @@ -132,77 +132,77 @@ "category: %s": "category: %s", "extracted: %.2f MiB": "extracted: %.2f MiB", "app_dls: %s": "app_dls: %s", - "More by Author": "", - "Leave Feedback": "", + "More by Author": "Mostrar mas del Autor", + "Leave Feedback": "Dejar Mensaje", - "Irs": "irs", - "Ambient Noise Level: ": "", - "Controller": "Controlador", + "Irs": "IRS", + "Ambient Noise Level: ": "Nivel de Ruido", + "Controller": "Control", "Pad ": "Almohadilla ", " (Available)": " (Disponible)", " (Unconnected)": " (Desconectado)", "HandHeld": "Portátil", "Rotation": "Rotación", - "0 (Sideways)": "0 (de lado)", - "90 (Flat)": "90 (plano)", - "180 (-Sideways)": "180 (-de lado)", - "270 (Upside down)": "270 (al revés)", + "0 (Sideways)": "0 (De Lado)", + "90 (Flat)": "90 (Plano)", + "180 (-Sideways)": "180 (-De Lado)", + "270 (Upside down)": "270 (Al Revés)", "Colour": "Color", "Grey": "Gris", - "Ironbow": "arco de hierro", + "Ironbow": "Paleta Térmica", "Green": "Verde", "Red": "Rojo", "Blue": "Azul", - "Light Target": "Objetivo de luz", - "All leds": "todos los leds", - "Bright group": "grupo brillante", - "Dim group": "grupo tenue", + "Light Target": "Objetivo de Luz", + "All leds": "Todos los leds", + "Bright group": "Grupo brillante", + "Dim group": "Grupo tenue", "None": "Ninguno", - "Gain": "Ganar", - "Negative Image": "Imagen negativa", - "Normal image": "imagen normal", - "Negative image": "Imagen negativa", + "Gain": "Ganancia", + "Negative Image": "Imagen Negativa", + "Normal image": "Imagen Normal", + "Negative image": "Imagen Negativa", "Format": "Formato", "320x240": "320×240", "160x120": "160×120", "80x60": "80×60", "40x30": "40×30", "20x15": "20×15", - "Trimming Format": "Formato de recorte", - "External Light Filter": "Filtro de luz externo", - "Load Default": "Cargar predeterminado", + "Trimming Format": "Formato de Recorte", + "External Light Filter": "Filtro de Luz Externa", + "Load Default": "Cargar Predeterminado", - "Themezer": "Temazer", - "Themezer Options": "", - "Nsfw": "", - "Page": "", + "Themezer": "Themezer", + "Themezer Options": "Opciones de Themezer", + "Nsfw": "NSFW", + "Page": "Página", "Page %zu / %zu": "Page %zu / %zu", - "Enter Page Number": "", - "Bad Page": "", - "Download theme?": "", + "Enter Page Number": "Ingresar Número de Página", + "Bad Page": "Página Errónea", + "Download theme?": "¿Descargar Tema?", - "Installing ": "", - "Uninstalling ": "", - "Deleting ": "", - "Deleting": "", - "Pasting ": "", - "Pasting": "", - "Removing ": "", - "Scanning ": "", - "Creating ": "", - "Copying ": "", - "Downloading ": "", - "Checking MD5": "", - "Loading...": "", - "Loading": "", - "Empty!": "", - "Not Ready...": "", - "Error loading page!": "", - "Update avaliable: ": "", - "Download update: ": "", - "Failed to download update": "", - "Delete Selected files?": "", - "Completely remove ": "", - "Are you sure you want to delete ": "¿Estás seguro de que quieres eliminar? ", - "Are you sure you wish to cancel?": "" + "Installing ": "Instalando ", + "Uninstalling ": "Desinstalando ", + "Deleting ": "Borrando ", + "Deleting": "Borrando", + "Pasting ": "Pegando ", + "Pasting": "Pegando", + "Removing ": "Removiendo ", + "Scanning ": "Escaneando ", + "Creating ": "Creando ", + "Copying ": "Copiando ", + "Downloading ": "Descargando ", + "Checking MD5": "Chqueando MD5", + "Loading...": "Cargando...", + "Loading": "Cargando", + "Empty!": "¡Vacío!", + "Not Ready...": "No Listo Aún...", + "Error loading page!": "¡Error cargando la página!", + "Update avaliable: ": "Actualización disponible: ", + "Download update: ": "Descargar actualización: ", + "Failed to download update": "Fallo al descargar actualización", + "Delete Selected files?": "¿Eliminar archivos Seleccionados?", + "Completely remove ": "Eliminar completamente", + "Are you sure you want to delete ": "¿Estás seguro que quieres eliminar? ", + "Are you sure you wish to cancel?": "¿Estás seguro que deseas cancelar?" } From 276ee36bfe1ab39b8220a24c997230745c1c02e6 Mon Sep 17 00:00:00 2001 From: do-kiss <56790799@qq.com> Date: Mon, 23 Dec 2024 12:56:16 +0800 Subject: [PATCH 20/25] Chinese translation update (#42) * Update zh.json --- assets/romfs/i18n/zh.json | 174 ++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 82 deletions(-) diff --git a/assets/romfs/i18n/zh.json b/assets/romfs/i18n/zh.json index daa8f28..e863e3d 100644 --- a/assets/romfs/i18n/zh.json +++ b/assets/romfs/i18n/zh.json @@ -1,23 +1,23 @@ { "[Applet Mode]": "[小程序模式]", "No Internet": "网络未连接", - "Files": "", - "Apps": "", - "Store": "", + "Files": "文件", + "Apps": "应用", + "Store": "商店", "Menu": "菜单", "Options": "选项", - "OK": "", + "OK": "确定", "Back": "返回", - "Select": "", + "Select": "选择", "Open": "打开", "Launch": "启动", "Info": "信息", "Install": "安装", "Delete": "删除", - "Changelog": "", - "Details": "", - "Update": "", - "Remove": "", + "Changelog": "更新日志", + "Details": "详情", + "Update": "更新", + "Remove": "删除", "Download": "下载", "Next Page": "下一页", "Prev Page": "上一页", @@ -34,10 +34,10 @@ "Search": "搜索", "Updated": "最近使用", "Downloads": "下载", - "Size": "大小", + "Size": "按大小", "Alphabetical": "按字母顺序", - "Likes": "", - "ID": "", + "Likes": "点赞量", + "ID": "ID", "Decending": "降序", "Descending (down)": "降序", "Desc": "降序", @@ -55,11 +55,11 @@ "Network": "网络", "Network Options": "网络选项", "Nxlink": "Nxlink", - "Nxlink Connected": "", - "Nxlink Upload": "", - "Nxlink Finished": "", + "Nxlink Connected": "Nxlink 已连接", + "Nxlink Upload": "Nxlink 上传中", + "Nxlink Finished": "Nxlink 已结束", "Language": "语言", - "Auto": "", + "Auto": "自动", "English": "English", "Japanese": "日本語", "French": "Français", @@ -78,70 +78,70 @@ "Web": "网页浏览器", "FileBrowser": "文件浏览", - "%zd files": "%zd files", - "%zd dirs": "%zd dirs", + "%zd files": "%zd 个文件", + "%zd dirs": "%zd 个文件夹", "File Options": "文件选项", "Show Hidden": "显示隐藏项目", "Folders First": "文件夹靠前", "Hidden Last": "隐藏项目置后", "Cut": "剪切", "Copy": "复制", - "Paste": "", - "Paste ": "", - " file(s)?": "", + "Paste": "粘贴", + "Paste ": "粘贴 ", + " file(s)?": "个文件(夹)?", "Rename": "重命名", - "Set New File Name": "", + "Set New File Name": "输入新命名", "Advanced": "高级", "Advanced Options": "高级选项", "Create File": "新建文件", - "Set File Name": "", + "Set File Name": "输入文件名", "Create Folder": "新建文件夹", - "Set Folder Name": "", + "Set Folder Name": "输入文件夹名", "View as text (unfinished)": "以文本形式查看(未完善)", - "Empty...": "", - "Open with DayBreak?": "", - "Launch option for: ": "", - - "Homebrew": "插件列表", - "Homebrew Options": "插件选项", - "Hide Sphaira": "在插件列表中隐藏Sphaira", + "Empty...": "空...", + "Open with DayBreak?": "使用DayBreak打开?", + "Launch option for: ": "启动选项:", + + "Homebrew": "应用列表", + "Homebrew Options": "应用选项", + "Hide Sphaira": "在应用列表中隐藏Sphaira", "Install Forwarder": "安装前端应用", "WARNING: Installing forwarders will lead to a ban!": "警告:安装前端应用可能导致ban机!", - "Installing Forwarder": "", - "Creating Program": "", - "Creating Control": "", - "Creating Meta": "", - "Writing Nca": "", - "Updating ncm databse": "", - "Pushing application record": "", - "Installed!": "", - "Failed to install forwarder": "", + "Installing Forwarder": "正在生成前端应用", + "Creating Program": "正在创建程序", + "Creating Control": "正在创建控制器", + "Creating Meta": "正在创建元数据", + "Writing Nca": "正在写入Nca", + "Updating ncm databse": "正在更新ncm数据库", + "Pushing application record": "正在推送应用记录", + "Installed!": "安装完成!", + "Failed to install forwarder": "前端应用安装失败", - "AppStore": "插件商店", + "AppStore": "应用商店", "Filter: %s | Sort: %s | Order: %s": "筛选: %s | 排序: %s | 顺序: %s", - "AppStore Options": "插件商店选项", + "AppStore Options": "应用商店选项", "All": "全部", "Games": "游戏", "Emulators": "模拟器", "Tools": "工具", "Themes": "主题", "Legacy": "可更新", - "version: %s": "version: %s", - "updated: %s": "updated: %s", - "category: %s": "category: %s", - "extracted: %.2f MiB": "extracted: %.2f MiB", - "app_dls: %s": "app_dls: %s", - "More by Author": "", - "Leave Feedback": "", + "version: %s": "版本: %s", + "updated: %s": "更新时间: %s", + "category: %s": "分类: %s", + "extracted: %.2f MiB": "应用大小: %.2f MiB", + "app_dls: %s": "下载量: %s", + "More by Author": "作者更多作品", + "Leave Feedback": "留言反馈", "Irs": "红外成像", - "Ambient Noise Level: ": "", + "Ambient Noise Level: ": "环境噪声等级:", "Controller": "控制器", "Pad ": "手柄 ", " (Available)": " (可用的)", " (Unconnected)": " (未连接)", - "HandHeld": "", - "Rotation": "", + "HandHeld": "掌机模式", + "Rotation": "旋转", "0 (Sideways)": "0度", "90 (Flat)": "90度", "180 (-Sideways)": "180度", @@ -172,36 +172,46 @@ "Load Default": "加载默认值", "Themezer": "在线主题", - "Themezer Options": "", - "Nsfw": "", - "Page": "", - "Page %zu / %zu": "Page %zu / %zu", - "Enter Page Number": "", - "Bad Page": "", - "Download theme?": "", + "Themezer Options": "在线主题选项", + "Nsfw": "公共场合不宜的主题", + "Page": "页面", + "Page %zu / %zu": "页面 %zu / %zu", + "Enter Page Number": "输入跳转的页码", + "Bad Page": "错误的页面", + "Download theme?": "下载该主题?", - "Installing ": "", - "Uninstalling ": "", - "Deleting ": "", - "Deleting": "", - "Pasting ": "", - "Pasting": "", - "Removing ": "", - "Scanning ": "", - "Creating ": "", - "Copying ": "", - "Downloading ": "", - "Checking MD5": "", - "Loading...": "", - "Loading": "", - "Empty!": "", - "Not Ready...": "", - "Error loading page!": "", - "Update avaliable: ": "", - "Download update: ": "", - "Failed to download update": "", - "Delete Selected files?": "", - "Completely remove ": "", + "Installing ": "正在安装 ", + "Uninstalling ": "正在卸载 ", + "Deleting ": "正在删除 ", + "Deleting": "正在删除", + "Pasting ": "正在粘贴 ", + "Pasting": "正在粘贴", + "Removing ": "正在移除 ", + "Scanning ": "正在扫描 ", + "Creating ": "正在创建 ", + "Copying ": "正在复制 ", + "Downloading ": "正在下载 ", + "Checking MD5": "正在校验 MD5", + "Loading...": "加载中...", + "Loading": "加载中", + "Empty!": "空!", + "Not Ready...": "尚未准备好...", + "Error loading page!": "页面加载失败!", + "Update avaliable: ": "有可用更新!", + "Download update: ": "下载更新:", + "Failed to download update": "更新下载失败", + "Delete Selected files?": "删除选中的文件?", + "Completely remove ": "彻底删除 ", "Are you sure you want to delete ": "您确定要删除吗 ", - "Are you sure you wish to cancel?": "" + "Are you sure you wish to cancel?": "您确定要取消吗?", + "Install forwarders": "允许安装前端应用", + "Install location": "安装位置", + "Show install warning": "显示安装警告", + "System memory": "主机内存", + "microSD card": "SD卡", + "Updated (Star)": "最近更新(星标优先)", + "Alphabetical (Star)": "按字母顺序(星标优先)", + "Size (Star)": "按大小(星标优先)", + "Star": "星标", + "Unstar": "取消星标" } From 3df676df0f432112aa14fbeae26943c91690e829 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Tue, 24 Dec 2024 08:55:29 +0000 Subject: [PATCH 21/25] New strings added and update ko, ja, se(https://github.com/ITotalJustice/sphaira/pull/36), es(https://github.com/ITotalJustice/sphaira/pull/38), zh(https://github.com/ITotalJustice/sphaira/pull/42), fr(https://github.com/ITotalJustice/sphaira/pull/45) translations. (#44) Co-authored-by: Yorunokyujitsu --- assets/romfs/i18n/de.json | 27 ++++++++++++++-- assets/romfs/i18n/en.json | 27 ++++++++++++++-- assets/romfs/i18n/es.json | 28 +++++++++++++++-- assets/romfs/i18n/fr.json | 25 ++++++++++++++- assets/romfs/i18n/it.json | 27 ++++++++++++++-- assets/romfs/i18n/ja.json | 33 +++++++++++++++++--- assets/romfs/i18n/ko.json | 41 +++++++++++++++++++------ assets/romfs/i18n/nl.json | 27 ++++++++++++++-- assets/romfs/i18n/pt.json | 27 ++++++++++++++-- assets/romfs/i18n/ru.json | 27 ++++++++++++++-- assets/romfs/i18n/se.json | 27 ++++++++++++++-- assets/romfs/i18n/zh.json | 35 ++++++++++++++------- sphaira/source/app.cpp | 4 +-- sphaira/source/ui/error_box.cpp | 5 +-- sphaira/source/ui/menus/filebrowser.cpp | 4 +-- sphaira/source/ui/menus/homebrew.cpp | 2 +- 16 files changed, 316 insertions(+), 50 deletions(-) diff --git a/assets/romfs/i18n/de.json b/assets/romfs/i18n/de.json index 87d5099..d6cfcea 100644 --- a/assets/romfs/i18n/de.json +++ b/assets/romfs/i18n/de.json @@ -14,6 +14,7 @@ "Info": "Info", "Install": "Installieren", "Delete": "Löschen", + "Restart": "", "Changelog": "", "Details": "", "Update": "", @@ -21,6 +22,10 @@ "Download": "Herunterladen", "Next Page": "Nächste Seite", "Prev Page": "Vorherige Seite", + "Unstar": "", + "Star": "", + "System memory": "", + "microSD card": "", "Yes": "Ja", "No": "Nein", "Enabled": "Aktiviert", @@ -33,9 +38,12 @@ "Order": "Befehl", "Search": "Suchen", "Updated": "Aktualisiert", + "Updated (Star)": "", "Downloads": "Downloads", "Size": "Größe", + "Size (Star)": "", "Alphabetical": "Alphabetisch", + "Alphabetical (Star)": "", "Likes": "", "ID": "", "Decending": "Absteigend", @@ -58,6 +66,8 @@ "Nxlink Connected": "", "Nxlink Upload": "", "Nxlink Finished": "", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Sprache", "Auto": "", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Logging", "Replace hbmenu on exit": "Ersetzen Sie hbmenu beim Beenden", "Misc": "Sonstiges", "Misc Options": "Verschiedene Optionen", "Web": "Web", + "Install forwarders": "", + "Install location": "", + "Show install warning": "", "FileBrowser": "DateiBrowser", "%zd files": "%zd files", @@ -100,7 +114,9 @@ "View as text (unfinished)": "Als Text anzeigen (unfertig)", "Empty...": "", "Open with DayBreak?": "", + "Launch ": "", "Launch option for: ": "", + "Select launcher for: ": "", "Homebrew": "Homebrew", "Homebrew Options": "Homebrew-Optionen", @@ -116,6 +132,8 @@ "Pushing application record": "", "Installed!": "", "Failed to install forwarder": "", + "Unstarred ": "", + "Starred ": "", "AppStore": "", "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sortieren: %s | Befehl: %s", @@ -139,6 +157,7 @@ "Controller": "Controller", "Pad ": "Unterlage ", " (Available)": " (Verfügbar)", + " (Unsupported)": "", " (Unconnected)": " (Nicht verbunden)", "HandHeld": "Handheld", "Rotation": "Drehung", @@ -190,6 +209,7 @@ "Scanning ": "", "Creating ": "", "Copying ": "", + "Trying to load ": "", "Downloading ": "", "Checking MD5": "", "Loading...": "", @@ -199,9 +219,12 @@ "Error loading page!": "", "Update avaliable: ": "", "Download update: ": "", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "", "Delete Selected files?": "", "Completely remove ": "", "Are you sure you want to delete ": "Mit dem Löschvorgang fortfahren?", - "Are you sure you wish to cancel?": "" -} + "Are you sure you wish to cancel?": "", + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/en.json b/assets/romfs/i18n/en.json index 735c4e9..750f316 100644 --- a/assets/romfs/i18n/en.json +++ b/assets/romfs/i18n/en.json @@ -14,6 +14,7 @@ "Info": "Info", "Install": "Install", "Delete": "Delete", + "Restart": "Restart", "Changelog": "Changelog", "Details": "Details", "Update": "Update", @@ -21,6 +22,10 @@ "Download": "Download", "Next Page": "Next Page", "Prev Page": "Prev Page", + "Unstar": "Unstar", + "Star": "Star", + "System memory": "System memory", + "microSD card": "microSD card", "Yes": "Yes", "No": "No", "Enabled": "Enabled", @@ -33,9 +38,12 @@ "Order": "Order", "Search": "Search", "Updated": "Updated", + "Updated (Star)": "Updated (Star)", "Downloads": "Downloads", "Size": "Size", + "Size (Star)": "Size (Star)", "Alphabetical": "Alphabetical", + "Alphabetical (Star)": "Alphabetical (Star)", "Likes": "Likes", "ID": "ID", "Decending": "Decending", @@ -58,6 +66,8 @@ "Nxlink Connected": "Nxlink Connected", "Nxlink Upload": "Nxlink Upload", "Nxlink Finished": "Nxlink Finished", + "Switch-Handheld!": "Switch-Handheld!", + "Switch-Docked!": "Switch-Docked!", "Language": "Language", "Auto": "Auto", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Logging", "Replace hbmenu on exit": "Replace hbmenu on exit", "Misc": "Misc", "Misc Options": "Misc Options", "Web": "Web", + "Install forwarders": "Install forwarders", + "Install location": "Install location", + "Show install warning": "Show install warning", "FileBrowser": "FileBrowser", "%zd files": "%zd files", @@ -100,7 +114,9 @@ "View as text (unfinished)": "View as text (unfinished)", "Empty...": "Empty...", "Open with DayBreak?": "Open with DayBreak?", + "Launch ": "Launch ", "Launch option for: ": "Launch option for: ", + "Select launcher for: ": "Select launcher for: ", "Homebrew": "Homebrew", "Homebrew Options": "Homebrew Options", @@ -116,6 +132,8 @@ "Pushing application record": "Pushing application record", "Installed!": "Installed!", "Failed to install forwarder": "Failed to install forwarder", + "Unstarred ": "Unstarred ", + "Starred ": "Starred ", "AppStore": "AppStore", "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sort: %s | Order: %s", @@ -139,6 +157,7 @@ "Controller": "Controller", "Pad ": "Pad ", " (Available)": " (Available)", + " (Unsupported)": " (Unsupported)", " (Unconnected)": " (Unconnected)", "HandHeld": "HandHeld", "Rotation": "Rotation", @@ -190,6 +209,7 @@ "Scanning ": "Scanning ", "Creating ": "Creating ", "Copying ": "Copying ", + "Trying to load ": "Trying to load ", "Downloading ": "Downloading ", "Checking MD5": "Checking MD5", "Loading...": "Loading...", @@ -199,9 +219,12 @@ "Error loading page!": "Error loading page!", "Update avaliable: ": "Update avaliable: ", "Download update: ": "Download update: ", + "Updated to ": "Updated to ", + "Restart Sphaira?": "Restart Sphaira?", "Failed to download update": "Failed to download update", "Delete Selected files?": "Delete Selected files?", "Completely remove ": "Completely remove ", "Are you sure you want to delete ": "Are you sure you want to delete ", - "Are you sure you wish to cancel?": "Are you sure you wish to cancel?" -} + "Are you sure you wish to cancel?": "Are you sure you wish to cancel?", + "If this message appears repeatedly, please open an issue.": "If this message appears repeatedly, please open an issue." +} \ No newline at end of file diff --git a/assets/romfs/i18n/es.json b/assets/romfs/i18n/es.json index 3697187..f4ee11a 100644 --- a/assets/romfs/i18n/es.json +++ b/assets/romfs/i18n/es.json @@ -14,6 +14,7 @@ "Info": "Información", "Install": "Instalar", "Delete": "Borrar", + "Restart": "", "Changelog": "Log de Cambios", "Details": "Detalles", "Update": "Actualizar", @@ -21,6 +22,10 @@ "Download": "Descargar", "Next Page": "Página siguiente", "Prev Page": "Página anterior", + "Unstar": "", + "Star": "", + "System memory": "", + "microSD card": "", "Yes": "Sí", "No": "No", "Enabled": "Activado", @@ -33,9 +38,12 @@ "Order": "Orden", "Search": "Buscar", "Updated": "Actualizado", + "Updated (Star)": "Actualizado (Star)", "Downloads": "Descargas", "Size": "Tamaño", + "Size (Star)": "Tamaño (Star)", "Alphabetical": "Alfabético", + "Alphabetical (Star)": "Alfabético (Star)", "Likes": "Me Gusta", "ID": "ID", "Decending": "Descendente", @@ -58,6 +66,8 @@ "Nxlink Connected": "Nxlink Conectado", "Nxlink Upload": "Nxlink Subida", "Nxlink Finished": "Nxlink Finalizado", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Idioma", "Auto": "Automático", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Explotación florestal", "Replace hbmenu on exit": "Reemplazar hbmenu al salir", "Misc": "Varios", "Misc Options": "Opciones varias", "Web": "Web", + "Install forwarders": "", + "Install location": "", + "Show install warning": "", "FileBrowser": "Explorador de Archivos", "%zd files": "%zd files", @@ -98,10 +112,11 @@ "Create Folder": "Crear carpeta", "Set Folder Name": "Establecer Nombre de Carpeta", "View as text (unfinished)": "Ver como texto (sin terminar)", - "Empty...": "Vacío...", "Open with DayBreak?": "Abrir con DayBreak", + "Launch ": "", "Launch option for: ": "Opción de ejecución para: ", + "Select launcher for: ": "", "Homebrew": "Honebrew", "Homebrew Options": "Opciones de Homebrew", @@ -117,6 +132,8 @@ "Pushing application record": "", "Installed!": "¡Instalado!", "Failed to install forwarder": "Fallo al instalar forwarder", + "Unstarred ": "", + "Starred ": "", "AppStore": "AppStore", "Filter: %s | Sort: %s | Order: %s": "Filtrar: %s | Clasificar: %s | Orden: %s", @@ -140,6 +157,7 @@ "Controller": "Control", "Pad ": "Almohadilla ", " (Available)": " (Disponible)", + " (Unsupported)": "", " (Unconnected)": " (Desconectado)", "HandHeld": "Portátil", "Rotation": "Rotación", @@ -191,6 +209,7 @@ "Scanning ": "Escaneando ", "Creating ": "Creando ", "Copying ": "Copiando ", + "Trying to load ": "", "Downloading ": "Descargando ", "Checking MD5": "Chqueando MD5", "Loading...": "Cargando...", @@ -200,9 +219,12 @@ "Error loading page!": "¡Error cargando la página!", "Update avaliable: ": "Actualización disponible: ", "Download update: ": "Descargar actualización: ", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "Fallo al descargar actualización", "Delete Selected files?": "¿Eliminar archivos Seleccionados?", "Completely remove ": "Eliminar completamente", "Are you sure you want to delete ": "¿Estás seguro que quieres eliminar? ", - "Are you sure you wish to cancel?": "¿Estás seguro que deseas cancelar?" -} + "Are you sure you wish to cancel?": "¿Estás seguro que deseas cancelar?", + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/fr.json b/assets/romfs/i18n/fr.json index 4f64248..e5204a4 100644 --- a/assets/romfs/i18n/fr.json +++ b/assets/romfs/i18n/fr.json @@ -14,6 +14,7 @@ "Info": "Info.", "Install": "Installer", "Delete": "Supprimer", + "Restart": "", "Changelog": "Changelog", "Details": "Détails", "Update": "Mise à jour", @@ -21,6 +22,10 @@ "Download": "Télécharger", "Next Page": "Page Suiv.", "Prev Page": "Page Préc.", + "Unstar": "Retirer des favories", + "Star": "Ajouter aux favories", + "System memory": "Mémoire système", + "microSD card": "microSD card", "Yes": "Oui", "No": "Non", "Enabled": "Activé(e)", @@ -33,9 +38,12 @@ "Order": "Ordre", "Search": "Recherche", "Updated": "Mis à jour", + "Updated (Star)": "", "Downloads": "Téléchargements", "Size": "Taille", + "Size (Star)": "", "Alphabetical": "Alphabétique", + "Alphabetical (Star)": "", "Likes": "Favoris", "ID": "ID", "Decending": "Décroissant", @@ -58,6 +66,8 @@ "Nxlink Connected": "Nxlink Connecté", "Nxlink Upload": "Nxlink téléversement", "Nxlink Finished": "Nxlink terminé", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Langue", "Auto": "Auto", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Journalisation", "Replace hbmenu on exit": "Remplacer hbmenu quand quitté", "Misc": "Divers", "Misc Options": "Options Diverses", "Web": "Web", + "Install forwarders": "Installer les Forwarders", + "Install location": "Emplacement d'installation", + "Show install warning": "Afficher l'avertissement d'installation", "FileBrowser": "Explorateur de Fichiers", "%zd files": "%zd fichiers", @@ -100,7 +114,9 @@ "View as text (unfinished)": "Afficher sous forme de texte (inachevé)", "Empty...": "Vide...", "Open with DayBreak?": "Ouvrir avec DayBreak?", + "Launch ": "", "Launch option for: ": "Option de lancement pour: ", + "Select launcher for: ": "", "Homebrew": "Homebrew", "Homebrew Options": "Options Homebrew", @@ -116,6 +132,8 @@ "Pushing application record": "Ajout de l'enregistrement de l'application", "Installed!": "Installé!", "Failed to install forwarder": "Echec de l'installation du forwarder", + "Unstarred ": "Retiré des favories ", + "Starred ": "Ajouté aux favories ", "AppStore": "AppStore", "Filter: %s | Sort: %s | Order: %s": "Filtre: %s | Tri: %s | Ordre: %s", @@ -139,6 +157,7 @@ "Controller": "Contrôleur", "Pad ": "Manette ", " (Available)": " (Disponible)", + " (Unsupported)": "", " (Unconnected)": " (Non connectée)", "HandHeld": "Portable", "Rotation": "Rotation", @@ -190,6 +209,7 @@ "Scanning ": "Scan ", "Creating ": "Création ", "Copying ": "Copie ", + "Trying to load ": "", "Downloading ": "Téléchargement ", "Checking MD5": "Vérification MD5", "Loading...": "Chargement...", @@ -199,9 +219,12 @@ "Error loading page!": "Erreur du chargement de la page!", "Update avaliable: ": "Mise à jour disponible: ", "Download update: ": "Télécharger la mise à jour: ", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "Echec du téléchargement de la mise à jour", "Delete Selected files?": "Supprimer les fichiers sélectionnés?", "Completely remove ": "Supprimer totalement ", "Are you sure you want to delete ": "Êtes-vous sûr de vouloir supprimer ", - "Are you sure you wish to cancel?": "Souhaitez-vous vraiment annuler?" + "Are you sure you wish to cancel?": "Souhaitez-vous vraiment annuler?", + "If this message appears repeatedly, please open an issue.": "" } \ No newline at end of file diff --git a/assets/romfs/i18n/it.json b/assets/romfs/i18n/it.json index 2837f4a..a1d7ab4 100644 --- a/assets/romfs/i18n/it.json +++ b/assets/romfs/i18n/it.json @@ -14,6 +14,7 @@ "Info": "Informazioni", "Install": "Installa", "Delete": "Elimina", + "Restart": "", "Changelog": "", "Details": "", "Update": "", @@ -21,6 +22,10 @@ "Download": "Download", "Next Page": "Pagina successiva", "Prev Page": "Pagina precedente", + "Unstar": "", + "Star": "", + "System memory": "", + "microSD card": "", "Yes": "Sì", "No": "No", "Enabled": "Abilitato", @@ -33,9 +38,12 @@ "Order": "Ordina", "Search": "Ricerca", "Updated": "Aggiornato", + "Updated (Star)": "", "Downloads": "Download", "Size": "Misurare", + "Size (Star)": "", "Alphabetical": "Alfabetico", + "Alphabetical (Star)": "", "Likes": "", "ID": "", "Decending": "Decrescente", @@ -58,6 +66,8 @@ "Nxlink Connected": "", "Nxlink Upload": "", "Nxlink Finished": "", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Lingua", "Auto": "", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Logging", "Replace hbmenu on exit": "Sostituisci hbmenu all'uscita", "Misc": "Varie", "Misc Options": "Opzioni varie", "Web": "Rete", + "Install forwarders": "", + "Install location": "", + "Show install warning": "", "FileBrowser": "FileBrowser", "%zd files": "%zd files", @@ -100,7 +114,9 @@ "View as text (unfinished)": "Visualizza come testo (non finito)", "Empty...": "", "Open with DayBreak?": "", + "Launch ": "", "Launch option for: ": "", + "Select launcher for: ": "", "Homebrew": "Homebrew", "Homebrew Options": "Opzioni Homebrew", @@ -116,6 +132,8 @@ "Pushing application record": "", "Installed!": "", "Failed to install forwarder": "", + "Unstarred ": "", + "Starred ": "", "AppStore": "", "Filter: %s | Sort: %s | Order: %s": "Filtro: %s | Riordina: %s | Ordina: %s", @@ -139,6 +157,7 @@ "Controller": "Controller", "Pad ": "Pad ", " (Available)": " (Disponibile)", + " (Unsupported)": "", " (Unconnected)": " (Non connesso)", "HandHeld": "HandHeld", "Rotation": "Rotazione", @@ -190,6 +209,7 @@ "Scanning ": "", "Creating ": "", "Copying ": "", + "Trying to load ": "", "Downloading ": "", "Checking MD5": "", "Loading...": "", @@ -199,9 +219,12 @@ "Error loading page!": "", "Update avaliable: ": "", "Download update: ": "", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "", "Delete Selected files?": "", "Completely remove ": "", "Are you sure you want to delete ": "Sei sicuro di voler eliminare? ", - "Are you sure you wish to cancel?": "" -} + "Are you sure you wish to cancel?": "", + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/ja.json b/assets/romfs/i18n/ja.json index 7469939..2595636 100644 --- a/assets/romfs/i18n/ja.json +++ b/assets/romfs/i18n/ja.json @@ -1,9 +1,9 @@ { "[Applet Mode]": "[Appletモード]", "No Internet": "インターネットなし", - "Files": "", - "Apps": "", - "Store": "", + "Files": "ファイル", + "Apps": "アプリ", + "Store": "AppStore", "Menu": "メニュー", "Options": "設定", "OK": "確認", @@ -14,6 +14,7 @@ "Info": "情報", "Install": "インストール", "Delete": "削除", + "Restart": "再起動", "Changelog": "リリースノート", "Details": "詳細", "Update": "アップデート", @@ -21,6 +22,10 @@ "Download": "ダウンロード", "Next Page": "次のページ", "Prev Page": "前のページ", + "Unstar": "お気に入り解除", + "Star": "お気に入り", + "System memory": "システムメモリ", + "microSD card": "SDメモリーカード", "Yes": "はい", "No": "いいえ", "Enabled": "", @@ -33,9 +38,12 @@ "Order": "順番", "Search": "検索", "Updated": "アップデート順", + "Updated (Star)": "アップデート順(お気に入り)", "Downloads": "ダウンロード順", "Size": "ファイルサイズ", + "Size (Star)": "ファイルサイズ(お気に入り)", "Alphabetical": "アルファベット順", + "Alphabetical (Star)": "アルファベット順(お気に入り)", "Likes": "いいね順", "ID": "デベロッパー順", "Decending": "降順", @@ -58,6 +66,8 @@ "Nxlink Connected": "Nxlink 接続", "Nxlink Upload": "Nxlink アップロード", "Nxlink Finished": "Nxlink 終了", + "Switch-Handheld!": "ハンドヘルド!", + "Switch-Docked!": "ドック接続!", "Language": "言語", "Auto": "自動", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "ログの取得", "Replace hbmenu on exit": "終了時に hbmenu を置き換える", "Misc": "その他", "Misc Options": "その他", "Web": "ウェブブラウザ", + "Install forwarders": "Forwarderのインストール機能", + "Install location": "インストール経路", + "Show install warning": "警告文を示す", "FileBrowser": "ファイルブラウザ", "%zd files": "%zd個のファイル", @@ -100,7 +114,9 @@ "View as text (unfinished)": "テキストとして表示 (未完成)", "Empty...": "このフォルダーは空です", "Open with DayBreak?": "DayBreakで開きますか?", + "Launch ": "起動しますか", "Launch option for: ": "起動設定: ", + "Select launcher for: ": "起動ランチャーを選ぶ: ", "Homebrew": "Homebrew", "Homebrew Options": "Homebrew設定", @@ -116,6 +132,8 @@ "Pushing application record": "アプリの記録をプッシュ中", "Installed!": "インストール完了", "Failed to install forwarder": "Forwarderのインストール失敗", + "Unstarred ": "お気に入り解除: ", + "Starred ": "お気に入りに登録: ", "AppStore": "AppStore", "Filter: %s | Sort: %s | Order: %s": "フィルター: %s | 並べ替え: %s | 順番: %s", @@ -139,6 +157,7 @@ "Controller": "コントローラー", "Pad ": "Joy-Con ", " (Available)": " (利用可能)", + " (Unsupported)": " (未対応)", " (Unconnected)": " (未接続)", "HandHeld": "ハンドヘルド", "Rotation": "回転", @@ -190,6 +209,7 @@ "Scanning ": "スキャン中 ", "Creating ": "作成中 ", "Copying ": "コピー中 ", + "Trying to load ": "サムネイルを取得中 ", "Downloading ": "ダウンロード中 ", "Checking MD5": "MD5を確認中 ", "Loading...": "ロード中", @@ -199,9 +219,12 @@ "Error loading page!": "ページのロードエラー", "Update avaliable: ": "アップデート可能: ", "Download update: ": "アップデートをダウンロード: ", + "Updated to ": "アップデート: ", + "Restart Sphaira?": "Sphairaを再起動しますか?", "Failed to download update": "アップデートのダウンロード失敗", "Delete Selected files?": "本当に削除しますか?", "Completely remove ": "除去しますか ", "Are you sure you want to delete ": "消去してもよろしいですか ", - "Are you sure you wish to cancel?": "本当に取り消しますか?" -} + "Are you sure you wish to cancel?": "本当に取り消しますか?", + "If this message appears repeatedly, please open an issue.": "このメッセージが繰り返し表示される場合は、問題を開いてください。" +} \ No newline at end of file diff --git a/assets/romfs/i18n/ko.json b/assets/romfs/i18n/ko.json index 4b22a15..cfd2581 100644 --- a/assets/romfs/i18n/ko.json +++ b/assets/romfs/i18n/ko.json @@ -1,9 +1,9 @@ { "[Applet Mode]": "[애플릿 모드]", "No Internet": "네트워크 연결 없음", - "Files": "", - "Apps": "", - "Store": "", + "Files": "파일 탐색기", + "Apps": "홈브류", + "Store": "앱스토어", "Menu": "메뉴", "Options": "설정", "OK": "확인", @@ -14,6 +14,7 @@ "Info": "정보", "Install": "설치", "Delete": "삭제", + "Restart": "재시작", "Changelog": "변경 내역", "Details": "상세", "Update": "업데이트", @@ -21,6 +22,10 @@ "Download": "다운로드", "Next Page": "다음 페이지", "Prev Page": "이전 페이지", + "Unstar": "즐겨찾기 해제", + "Star": "즐겨찾기", + "System memory": "낸드 저장소", + "microSD card": "SD 카드", "Yes": "예", "No": "아니요", "Enabled": "", @@ -33,9 +38,12 @@ "Order": "정렬", "Search": "검색", "Updated": "업데이트순", + "Updated (Star)": "업데이트순 (즐겨찾기)", "Downloads": "다운로드순", "Size": "크기순", + "Size (Star)": "크기순 (즐겨찾기)", "Alphabetical": "알파벳순", + "Alphabetical (Star)": "알파벳순 (즐겨찾기)", "Likes": "좋아요순", "ID": "작성자순", "Decending": "내림차순", @@ -58,6 +66,8 @@ "Nxlink Connected": "Nxlink 연결됨", "Nxlink Upload": "Nxlink 업로드", "Nxlink Finished": "Nxlink 종료됨", + "Switch-Handheld!": "휴대모드로 전환되었습니다!", + "Switch-Docked!": "독 모드로 전환되었습니다!", "Language": "언어", "Auto": "자동", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "로깅", - "Replace hbmenu on exit": "hbmenu를 교체", + "Replace hbmenu on exit": "hbmenu  sphaira 교체", "Misc": "기타", "Misc Options": "기타", "Web": "웹 브라우저", + "Install forwarders": "바로가기 설치 기능", + "Install location": "설치 경로", + "Show install warning": "바로가기 설치 경고문 표시", "FileBrowser": "파일 탐색기", "%zd files": "%zd개의 파일", @@ -100,13 +114,15 @@ "View as text (unfinished)": "텍스트로 보기 (미완성)", "Empty...": "비어있습니다...", "Open with DayBreak?": "DayBreak로 여시겠습니까?", - "Launch option for: ": "실행 옵션: ", + "Launch ": "실행하시겠습니까 ", + "Launch option for: ": "실행 설정: ", + "Select launcher for: ": "실행 런처: ", "Homebrew": "홈브류", "Homebrew Options": "홈브류 설정", "Hide Sphaira": "Sphaira 숨기기", "Install Forwarder": "바로가기 설치", - "WARNING: Installing forwarders will lead to a ban!": "주의: 바로가기 설치시 BAN 위험이 있습니다!", + "WARNING: Installing forwarders will lead to a ban!": "주의: 시스낸드에서 바로가기 설치시 BAN 위험이 있습니다!", "Installing Forwarder": "바로가기 설치중...", "Creating Program": "프로그램 작성중...", "Creating Control": "컨트롤 작성중...", @@ -116,6 +132,8 @@ "Pushing application record": "응용 프로그램 기록 푸시중...", "Installed!": "설치 완료!", "Failed to install forwarder": "바로가기 설치 실패", + "Unstarred ": "즐겨찾기 해제: ", + "Starred ": "즐겨찾기 적용: ", "AppStore": "앱스토어", "Filter: %s | Sort: %s | Order: %s": "필터: %s | 분류: %s | 정렬: %s", @@ -139,6 +157,7 @@ "Controller": "컨트롤러", "Pad ": "조이콘 ", " (Available)": " (사용 가능)", + " (Unsupported)": " (지원 안됨)", " (Unconnected)": " (연결 없음)", "HandHeld": "- 본체 연결", "Rotation": "화면 회전", @@ -190,6 +209,7 @@ "Scanning ": "스캔중... ", "Creating ": "작성중... ", "Copying ": "복사중... ", + "Trying to load ": "썸네일 받아오는 중... ", "Downloading ": "다운로드중... ", "Checking MD5": "MD5 확인중... ", "Loading...": "로딩중...", @@ -199,9 +219,12 @@ "Error loading page!": "페이지 로딩 오류!", "Update avaliable: ": "업데이트 가능: ", "Download update: ": "업데이트 다운로드: ", + "Updated to ": "업데이트: ", + "Restart Sphaira?": "Sphaira를 재시작 하시겠습니까?", "Failed to download update": "업데이트 다운로드 실패!", "Delete Selected files?": "정말 삭제하시겠습니까?", "Completely remove ": "제거하시겠습니까 ", - "Are you sure you want to delete ": "sdmc:", - "Are you sure you wish to cancel?": "정말 취소하시겠습니까?" -} + "Are you sure you want to delete ": "정말 삭제하시겠습니까 ", + "Are you sure you wish to cancel?": "정말 취소하시겠습니까?", + "If this message appears repeatedly, please open an issue.": "해당 메시지가 반복해서 나타나는 경우, 이슈를 열어주세요." +} \ No newline at end of file diff --git a/assets/romfs/i18n/nl.json b/assets/romfs/i18n/nl.json index 3655bb3..a1eaf9e 100644 --- a/assets/romfs/i18n/nl.json +++ b/assets/romfs/i18n/nl.json @@ -14,6 +14,7 @@ "Info": "Info", "Install": "Installeren", "Delete": "Verwijderen", + "Restart": "", "Changelog": "", "Details": "", "Update": "", @@ -21,6 +22,10 @@ "Download": "Downloaden", "Next Page": "Volgende pagina", "Prev Page": "Vorige pagina", + "Unstar": "", + "Star": "", + "System memory": "", + "microSD card": "", "Yes": "Ja", "No": "Nee", "Enabled": "Ingeschakeld", @@ -33,9 +38,12 @@ "Order": "Volgorde", "Search": "Zoekopdracht", "Updated": "Bijgewerkt", + "Updated (Star)": "", "Downloads": "Downloads", "Size": "Maat", + "Size (Star)": "", "Alphabetical": "Alfabetisch", + "Alphabetical (Star)": "", "Likes": "", "ID": "", "Decending": "Aflopend", @@ -58,6 +66,8 @@ "Nxlink Connected": "", "Nxlink Upload": "", "Nxlink Finished": "", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Taal", "Auto": "", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Loggen", "Replace hbmenu on exit": "Vervang hbmenu bij afsluiten", "Misc": "Diversen", "Misc Options": "Diverse opties", "Web": "Web", + "Install forwarders": "", + "Install location": "", + "Show install warning": "", "FileBrowser": "Bestandsbrowser", "%zd files": "%zd files", @@ -100,7 +114,9 @@ "View as text (unfinished)": "Bekijk als tekst (onvoltooid)", "Empty...": "", "Open with DayBreak?": "", + "Launch ": "", "Launch option for: ": "", + "Select launcher for: ": "", "Homebrew": "Zelf brouwen", "Homebrew Options": "Homebrew-opties", @@ -116,6 +132,8 @@ "Pushing application record": "", "Installed!": "", "Failed to install forwarder": "", + "Unstarred ": "", + "Starred ": "", "AppStore": "", "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Soort: %s | Volgorde: %s", @@ -139,6 +157,7 @@ "Controller": "Controleur", "Pad ": "Pad ", " (Available)": " (Beschikbaar)", + " (Unsupported)": "", " (Unconnected)": " (Niet verbonden)", "HandHeld": "Handbediende", "Rotation": "Rotatie", @@ -190,6 +209,7 @@ "Scanning ": "", "Creating ": "", "Copying ": "", + "Trying to load ": "", "Downloading ": "", "Checking MD5": "", "Loading...": "", @@ -199,9 +219,12 @@ "Error loading page!": "", "Update avaliable: ": "", "Download update: ": "", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "", "Delete Selected files?": "", "Completely remove ": "", "Are you sure you want to delete ": "Weet u zeker dat u wilt verwijderen ", - "Are you sure you wish to cancel?": "" -} + "Are you sure you wish to cancel?": "", + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/pt.json b/assets/romfs/i18n/pt.json index 330a5a2..fab8e98 100644 --- a/assets/romfs/i18n/pt.json +++ b/assets/romfs/i18n/pt.json @@ -14,6 +14,7 @@ "Info": "Informações", "Install": "Instalar", "Delete": "Excluir", + "Restart": "", "Changelog": "", "Details": "", "Update": "", @@ -21,6 +22,10 @@ "Download": "Download", "Next Page": "Próxima página", "Prev Page": "Página anterior", + "Unstar": "", + "Star": "", + "System memory": "", + "microSD card": "", "Yes": "Sim", "No": "Não", "Enabled": "Habilitado", @@ -33,9 +38,12 @@ "Order": "Ordem", "Search": "Procurar", "Updated": "Atualizado", + "Updated (Star)": "", "Downloads": "Downloads", "Size": "Tamanho", + "Size (Star)": "", "Alphabetical": "Alfabético", + "Alphabetical (Star)": "", "Likes": "", "ID": "", "Decending": "Decrescente", @@ -58,6 +66,8 @@ "Nxlink Connected": "", "Nxlink Upload": "", "Nxlink Finished": "", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Idioma", "Auto": "", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Logging", "Replace hbmenu on exit": "Substitua hbmenu ao sair", "Misc": "Diversos", "Misc Options": "Opções diversas", "Web": "Rede", + "Install forwarders": "", + "Install location": "", + "Show install warning": "", "FileBrowser": "Navegador de arquivos", "%zd files": "%zd files", @@ -100,7 +114,9 @@ "View as text (unfinished)": "Ver como texto (inacabado)", "Empty...": "", "Open with DayBreak?": "", + "Launch ": "", "Launch option for: ": "", + "Select launcher for: ": "", "Homebrew": "Homebrew", "Homebrew Options": "Opções do Homebrew", @@ -116,6 +132,8 @@ "Pushing application record": "", "Installed!": "", "Failed to install forwarder": "", + "Unstarred ": "", + "Starred ": "", "AppStore": "", "Filter: %s | Sort: %s | Order: %s": "Filtro: %s | Organizar: %s | Ordem: %s", @@ -139,6 +157,7 @@ "Controller": "Controle", "Pad ": "Pad ", " (Available)": " (Disponível)", + " (Unsupported)": "", " (Unconnected)": " (Desconectado)", "HandHeld": "Portátil", "Rotation": "Rotação", @@ -190,6 +209,7 @@ "Scanning ": "", "Creating ": "", "Copying ": "", + "Trying to load ": "", "Downloading ": "", "Checking MD5": "", "Loading...": "", @@ -199,9 +219,12 @@ "Error loading page!": "", "Update avaliable: ": "", "Download update: ": "", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "", "Delete Selected files?": "", "Completely remove ": "", "Are you sure you want to delete ": "Excluir ", - "Are you sure you wish to cancel?": "" -} + "Are you sure you wish to cancel?": "", + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/ru.json b/assets/romfs/i18n/ru.json index 23a589f..de6fa07 100644 --- a/assets/romfs/i18n/ru.json +++ b/assets/romfs/i18n/ru.json @@ -14,6 +14,7 @@ "Info": "Информация", "Install": "Установить", "Delete": "Удалить", + "Restart": "", "Changelog": "", "Details": "", "Update": "", @@ -21,6 +22,10 @@ "Download": "Скачать", "Next Page": "Следующая страница", "Prev Page": "Предыдущая страница", + "Unstar": "", + "Star": "", + "System memory": "", + "microSD card": "", "Yes": "Да", "No": "Нет", "Enabled": "Включено", @@ -33,9 +38,12 @@ "Order": "Порядок", "Search": "Поиск", "Updated": "Обновлено", + "Updated (Star)": "", "Downloads": "Загрузки", "Size": "Размер", + "Size (Star)": "", "Alphabetical": "По наименованию", + "Alphabetical (Star)": "", "Likes": "", "ID": "", "Decending": "По убыванию", @@ -58,6 +66,8 @@ "Nxlink Connected": "", "Nxlink Upload": "", "Nxlink Finished": "", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Язык", "Auto": "", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "Журналирование", "Replace hbmenu on exit": "Заменить hbmenu при выходе", "Misc": "Прочее", "Misc Options": "Прочие параметры", "Web": "Интернет", + "Install forwarders": "", + "Install location": "", + "Show install warning": "", "FileBrowser": "Файловый менеджер", "%zd files": "%zd files", @@ -100,7 +114,9 @@ "View as text (unfinished)": "Посмотреть как текст (незакончено)", "Empty...": "", "Open with DayBreak?": "", + "Launch ": "", "Launch option for: ": "", + "Select launcher for: ": "", "Homebrew": "Homebrew", "Homebrew Options": "Параметры Homebrew", @@ -116,6 +132,8 @@ "Pushing application record": "", "Installed!": "", "Failed to install forwarder": "", + "Unstarred ": "", + "Starred ": "", "AppStore": "", "Filter: %s | Sort: %s | Order: %s": "Фильтр: %s | Сортировать: %s | Порядок: %s", @@ -139,6 +157,7 @@ "Controller": "Контроллер", "Pad ": "Pad ", " (Available)": " (Доступно)", + " (Unsupported)": "", " (Unconnected)": " (Не подключено)", "HandHeld": "Портативный", "Rotation": "Вращение", @@ -190,6 +209,7 @@ "Scanning ": "", "Creating ": "", "Copying ": "", + "Trying to load ": "", "Downloading ": "", "Checking MD5": "", "Loading...": "", @@ -199,9 +219,12 @@ "Error loading page!": "", "Update avaliable: ": "", "Download update: ": "", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "", "Delete Selected files?": "", "Completely remove ": "", "Are you sure you want to delete ": "Вы уверены, что хотите удалить ", - "Are you sure you wish to cancel?": "" -} + "Are you sure you wish to cancel?": "", + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/se.json b/assets/romfs/i18n/se.json index fefbe49..1733cf6 100644 --- a/assets/romfs/i18n/se.json +++ b/assets/romfs/i18n/se.json @@ -14,6 +14,7 @@ "Info": "Info", "Install": "Installera", "Delete": "Radera", + "Restart": "", "Changelog": "Ändringslogg", "Details": "Detaljer", "Update": "Uppdatera", @@ -21,6 +22,10 @@ "Download": "Ladda ner", "Next Page": "Nästa sida", "Prev Page": "Föregående sida", + "Unstar": "", + "Star": "", + "System memory": "", + "microSD card": "", "Yes": "Ja", "No": "Nej", "Enabled": "Aktiverad", @@ -33,9 +38,12 @@ "Order": "Ordning", "Search": "Sök", "Updated": "Uppdaterad", + "Updated (Star)": "", "Downloads": "Nedladdningar", "Size": "Storlek", + "Size (Star)": "", "Alphabetical": "Alfabetisk", + "Alphabetical (Star)": "", "Likes": "Gillar", "ID": "ID", "Decending": "Fallande", @@ -58,6 +66,8 @@ "Nxlink Connected": "Nxlink ansluten", "Nxlink Upload": "Nxlink uppladdning", "Nxlink Finished": "Nxlink klar", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "Språk", "Auto": "Auto", "English": "Engelska", @@ -71,11 +81,15 @@ "Dutch": "Holländska", "Portuguese": "Portugisiska", "Russian": "Ryska", + "Swedish": "Svenska", "Logging": "Loggning", "Replace hbmenu on exit": "Ersätt hbmenu vid avslut", "Misc": "Övrigt", "Misc Options": "Övriga alternativ", "Web": "Webb", + "Install forwarders": "", + "Install location": "", + "Show install warning": "", "FileBrowser": "Filbläddrare", "%zd files": "%zd filer", @@ -100,7 +114,9 @@ "View as text (unfinished)": "Visa som text (ofärdig)", "Empty...": "Tom...", "Open with DayBreak?": "Öppna med DayBreak?", + "Launch ": "", "Launch option for: ": "Startalternativ för: ", + "Select launcher for: ": "", "Homebrew": "Homebrew", "Homebrew Options": "Homebrew-alternativ", @@ -116,6 +132,8 @@ "Pushing application record": "Lägger till applikationspost", "Installed!": "Installerad!", "Failed to install forwarder": "Misslyckades med att installera forwarder", + "Unstarred ": "", + "Starred ": "", "AppStore": "AppStore", "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sortering: %s | Ordning: %s", @@ -139,6 +157,7 @@ "Controller": "Kontroll", "Pad ": "Handkontroll ", " (Available)": " (Tillgänglig)", + " (Unsupported)": "", " (Unconnected)": " (Ej ansluten)", "HandHeld": "Handhållen", "Rotation": "Rotation", @@ -190,6 +209,7 @@ "Scanning ": "Skannar ", "Creating ": "Skapar ", "Copying ": "Kopierar ", + "Trying to load ": "", "Downloading ": "Laddar ner ", "Checking MD5": "Kontrollerar MD5", "Loading...": "Laddar...", @@ -199,9 +219,12 @@ "Error loading page!": "Fel vid laddning av sida!", "Update avaliable: ": "Uppdatering tillgänglig: ", "Download update: ": "Ladda ner uppdatering: ", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "Misslyckades med att ladda ner uppdatering", "Delete Selected files?": "Radera valda filer?", "Completely remove ": "Ta bort helt ", "Are you sure you want to delete ": "Är du säker på att du vill radera ", - "Are you sure you wish to cancel?": "Är du säker på att du vill avbryta?" -} + "Are you sure you wish to cancel?": "Är du säker på att du vill avbryta?", + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/assets/romfs/i18n/zh.json b/assets/romfs/i18n/zh.json index e863e3d..0475861 100644 --- a/assets/romfs/i18n/zh.json +++ b/assets/romfs/i18n/zh.json @@ -14,6 +14,7 @@ "Info": "信息", "Install": "安装", "Delete": "删除", + "Restart": "", "Changelog": "更新日志", "Details": "详情", "Update": "更新", @@ -21,6 +22,10 @@ "Download": "下载", "Next Page": "下一页", "Prev Page": "上一页", + "Unstar": "取消星标", + "Star": "星标", + "System memory": "主机内存", + "microSD card": "SD卡", "Yes": "是", "No": "否", "Enabled": "启用", @@ -33,9 +38,12 @@ "Order": "顺序", "Search": "搜索", "Updated": "最近使用", + "Updated (Star)": "最近更新(星标优先)", "Downloads": "下载", "Size": "按大小", + "Size (Star)": "按大小(星标优先)", "Alphabetical": "按字母顺序", + "Alphabetical (Star)": "按字母顺序(星标优先)", "Likes": "点赞量", "ID": "ID", "Decending": "降序", @@ -58,6 +66,8 @@ "Nxlink Connected": "Nxlink 已连接", "Nxlink Upload": "Nxlink 上传中", "Nxlink Finished": "Nxlink 已结束", + "Switch-Handheld!": "", + "Switch-Docked!": "", "Language": "语言", "Auto": "自动", "English": "English", @@ -71,11 +81,15 @@ "Dutch": "Dutch", "Portuguese": "Português", "Russian": "Русский", + "Swedish": "Svenska", "Logging": "日志", "Replace hbmenu on exit": "退出后用Sphaira替换hbmenu", "Misc": "杂项", "Misc Options": "杂项设置", "Web": "网页浏览器", + "Install forwarders": "允许安装前端应用", + "Install location": "安装位置", + "Show install warning": "显示安装警告", "FileBrowser": "文件浏览", "%zd files": "%zd 个文件", @@ -100,7 +114,9 @@ "View as text (unfinished)": "以文本形式查看(未完善)", "Empty...": "空...", "Open with DayBreak?": "使用DayBreak打开?", + "Launch ": "", "Launch option for: ": "启动选项:", + "Select launcher for: ": "", "Homebrew": "应用列表", "Homebrew Options": "应用选项", @@ -116,6 +132,8 @@ "Pushing application record": "正在推送应用记录", "Installed!": "安装完成!", "Failed to install forwarder": "前端应用安装失败", + "Unstarred ": "", + "Starred ": "", "AppStore": "应用商店", "Filter: %s | Sort: %s | Order: %s": "筛选: %s | 排序: %s | 顺序: %s", @@ -139,6 +157,7 @@ "Controller": "控制器", "Pad ": "手柄 ", " (Available)": " (可用的)", + " (Unsupported)": "", " (Unconnected)": " (未连接)", "HandHeld": "掌机模式", "Rotation": "旋转", @@ -190,6 +209,7 @@ "Scanning ": "正在扫描 ", "Creating ": "正在创建 ", "Copying ": "正在复制 ", + "Trying to load ": "", "Downloading ": "正在下载 ", "Checking MD5": "正在校验 MD5", "Loading...": "加载中...", @@ -199,19 +219,12 @@ "Error loading page!": "页面加载失败!", "Update avaliable: ": "有可用更新!", "Download update: ": "下载更新:", + "Updated to ": "", + "Restart Sphaira?": "", "Failed to download update": "更新下载失败", "Delete Selected files?": "删除选中的文件?", "Completely remove ": "彻底删除 ", "Are you sure you want to delete ": "您确定要删除吗 ", "Are you sure you wish to cancel?": "您确定要取消吗?", - "Install forwarders": "允许安装前端应用", - "Install location": "安装位置", - "Show install warning": "显示安装警告", - "System memory": "主机内存", - "microSD card": "SD卡", - "Updated (Star)": "最近更新(星标优先)", - "Alphabetical (Star)": "按字母顺序(星标优先)", - "Size (Star)": "按大小(星标优先)", - "Star": "星标", - "Unstar": "取消星标" -} + "If this message appears repeatedly, please open an issue.": "" +} \ No newline at end of file diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 9d5c603..33d3c9b 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -107,12 +107,12 @@ void on_applet_operation_mode(App* app) { switch (appletGetOperationMode()) { case AppletOperationMode_Handheld: log_write("[APPLET] AppletOperationMode_Handheld\n"); - App::Notify("Switch-Handheld!"); + App::Notify("Switch-Handheld!"_i18n); break; case AppletOperationMode_Console: log_write("[APPLET] AppletOperationMode_Console\n"); - App::Notify("Switch-Docked!"); + App::Notify("Switch-Docked!"_i18n); break; } } diff --git a/sphaira/source/ui/error_box.cpp b/sphaira/source/ui/error_box.cpp index e88c907..5fa9b92 100644 --- a/sphaira/source/ui/error_box.cpp +++ b/sphaira/source/ui/error_box.cpp @@ -1,6 +1,7 @@ #include "ui/error_box.hpp" #include "ui/nvg_util.hpp" #include "app.hpp" +#include "i18n.hpp" namespace sphaira::ui { namespace { @@ -1147,10 +1148,10 @@ auto ErrorBox::Draw(NVGcontext* vg, Theme* theme) -> void { gfx::drawTextArgs(vg, center_x, 180, 63, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::RED, "\uE140"); gfx::drawTextArgs(vg, center_x, 270, 25, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "Error code: 0x%X Module: %s Description: %s", m_code, m_module_str.c_str(), m_description_str.c_str()); gfx::drawTextArgs(vg, center_x, 325, 23, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, theme->elements[ThemeEntryID_TEXT].colour, "%s", m_message.c_str()); - gfx::drawTextArgs(vg, center_x, 380, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::SILVER, "If this message appears repeatedly, please open an issue."); + gfx::drawTextArgs(vg, center_x, 380, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::SILVER, "If this message appears repeatedly, please open an issue."_i18n.c_str()); gfx::drawTextArgs(vg, center_x, 415, 20, NVG_ALIGN_CENTER | NVG_ALIGN_TOP, gfx::Colour::SILVER, "https://github.com/ITotalJustice/sphaira/issues"); gfx::drawRectOutline(vg, 4.f, theme->elements[ThemeEntryID_SELECTED_OVERLAY].colour, box, theme->elements[ThemeEntryID_SELECTED].colour); - gfx::drawTextArgs(vg, center_x, box.y + box.h/2, 23, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::WHITE, "OK"); + gfx::drawTextArgs(vg, center_x, box.y + box.h/2, 23, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE, gfx::Colour::WHITE, "OK"_i18n.c_str()); } } // namespace sphaira::ui diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index 004e4d0..9417b8d 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -215,7 +215,7 @@ auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension, log_write("starting image convert on: %s\n", ra_thumbnail_path.c_str()); // try and find icon locally if (!pbox->ShouldExit()) { - pbox->NewTransfer("Trying to load " + ra_thumbnail_path); + pbox->NewTransfer("Trying to load "_i18n + ra_thumbnail_path); std::vector image_file; if (R_SUCCEEDED(fs::FsNativeSd().read_entire_file(ra_thumbnail_path.c_str(), image_file))) { return image_file; @@ -839,7 +839,7 @@ void Menu::InstallForwarder() { items.emplace_back(p.name); } - const auto title = std::string{"Select launcher for: "} + GetEntry().name; + const auto title = std::string{"Select launcher for: "_i18n} + GetEntry().name; App::Push(std::make_shared( title, items, [this, assoc_list](auto op_index){ if (op_index) { diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index 0fb5e10..7f2a14a 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -112,7 +112,7 @@ Menu::Menu() : MenuBase{"Homebrew"_i18n} { #endif options->Add(std::make_shared("Delete"_i18n, [this](){ - const auto buf = "Are you sure you want to delete " + m_entries[m_index].path.toString(); + const auto buf = "Are you sure you want to delete "_i18n + m_entries[m_index].path.toString() + "?"; App::Push(std::make_shared( buf, "Back"_i18n, "Delete"_i18n, 1, [this](auto op_index){ From a2c9b63dfd80dc9e0c0e8a76b59da15844ed209a Mon Sep 17 00:00:00 2001 From: shadow2560 <24191064+shadow2560@users.noreply.github.com> Date: Tue, 24 Dec 2024 23:21:54 +0100 Subject: [PATCH 22/25] Some fixes and update french language (#46) * Fix starred homebrew list logging, fix hbmenu identification when backing up it and logging it correctly, update french language. Signed-off-by: shadow2560 <24191064+shadow2560@users.noreply.github.com> --- assets/romfs/i18n/fr.json | 42 ++++++++++++++++++++++++++++ sphaira/source/app.cpp | 4 +-- sphaira/source/ui/menus/homebrew.cpp | 2 +- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/assets/romfs/i18n/fr.json b/assets/romfs/i18n/fr.json index e5204a4..3af3da1 100644 --- a/assets/romfs/i18n/fr.json +++ b/assets/romfs/i18n/fr.json @@ -14,7 +14,11 @@ "Info": "Info.", "Install": "Installer", "Delete": "Supprimer", +<<<<<<< HEAD + "Restart": "Redémarrer", +======= "Restart": "", +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Changelog": "Changelog", "Details": "Détails", "Update": "Mise à jour", @@ -38,6 +42,15 @@ "Order": "Ordre", "Search": "Recherche", "Updated": "Mis à jour", +<<<<<<< HEAD + "Updated (Star)": "Mis à jour (Favories)", + "Downloads": "Téléchargements", + "Size": "Taille", + "Size (Star)": "Taille (Favories)", + "Alphabetical": "Alphabétique", + "Alphabetical (Star)": "Alphabétique (Favories)", + "Likes": "Likes", +======= "Updated (Star)": "", "Downloads": "Téléchargements", "Size": "Taille", @@ -45,6 +58,7 @@ "Alphabetical": "Alphabétique", "Alphabetical (Star)": "", "Likes": "Favoris", +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "ID": "ID", "Decending": "Décroissant", "Descending (down)": "Décroissant", @@ -66,8 +80,13 @@ "Nxlink Connected": "Nxlink Connecté", "Nxlink Upload": "Nxlink téléversement", "Nxlink Finished": "Nxlink terminé", +<<<<<<< HEAD + "Switch-Handheld!": "Switch-Portable", + "Switch-Docked!": "Switch-Dockée", +======= "Switch-Handheld!": "", "Switch-Docked!": "", +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Language": "Langue", "Auto": "Auto", "English": "English", @@ -114,9 +133,15 @@ "View as text (unfinished)": "Afficher sous forme de texte (inachevé)", "Empty...": "Vide...", "Open with DayBreak?": "Ouvrir avec DayBreak?", +<<<<<<< HEAD + "Launch ": "Lancer ", + "Launch option for: ": "Option de lancement pour: ", + "Select launcher for: ": "Sélectionner le lanceur pour: ", +======= "Launch ": "", "Launch option for: ": "Option de lancement pour: ", "Select launcher for: ": "", +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Homebrew": "Homebrew", "Homebrew Options": "Options Homebrew", @@ -157,7 +182,11 @@ "Controller": "Contrôleur", "Pad ": "Manette ", " (Available)": " (Disponible)", +<<<<<<< HEAD + " (Unsupported)": "Non supporté", +======= " (Unsupported)": "", +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 " (Unconnected)": " (Non connectée)", "HandHeld": "Portable", "Rotation": "Rotation", @@ -209,7 +238,11 @@ "Scanning ": "Scan ", "Creating ": "Création ", "Copying ": "Copie ", +<<<<<<< HEAD + "Trying to load ": "Tente de charger ", +======= "Trying to load ": "", +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Downloading ": "Téléchargement ", "Checking MD5": "Vérification MD5", "Loading...": "Chargement...", @@ -219,12 +252,21 @@ "Error loading page!": "Erreur du chargement de la page!", "Update avaliable: ": "Mise à jour disponible: ", "Download update: ": "Télécharger la mise à jour: ", +<<<<<<< HEAD + "Updated to ": "Mis à jour vers ", + "Restart Sphaira?": "Redémarrer Sphaira?", +======= "Updated to ": "", "Restart Sphaira?": "", +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Failed to download update": "Echec du téléchargement de la mise à jour", "Delete Selected files?": "Supprimer les fichiers sélectionnés?", "Completely remove ": "Supprimer totalement ", "Are you sure you want to delete ": "Êtes-vous sûr de vouloir supprimer ", "Are you sure you wish to cancel?": "Souhaitez-vous vraiment annuler?", +<<<<<<< HEAD + "If this message appears repeatedly, please open an issue.": "Si ce message apparait en boucle veuillez ouvrir une issue." +======= "If this message appears repeatedly, please open an issue.": "" +>>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 } \ No newline at end of file diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 33d3c9b..5b1ad51 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -1053,9 +1053,9 @@ App::~App() { NacpStruct nacp; fs::FsNativeSd fs; if (R_SUCCEEDED(nro_get_nacp("/hbmenu.nro", nacp)) && std::strcmp(nacp.lang[0].name, "sphaira")) { - log_write("backing up hbmenu\n"); + log_write("backing up hbmenu.nro\n"); if (R_FAILED(fs.copy_entire_file("/switch/hbmenu.nro", "/hbmenu.nro", true))) { - log_write("failed to copy sphaire.nro to hbmenu.nro\n"); + log_write("failed to backup hbmenu.nro\n"); } } else { log_write("not backing up\n"); diff --git a/sphaira/source/ui/menus/homebrew.cpp b/sphaira/source/ui/menus/homebrew.cpp index 7f2a14a..7c1bb64 100644 --- a/sphaira/source/ui/menus/homebrew.cpp +++ b/sphaira/source/ui/menus/homebrew.cpp @@ -317,7 +317,7 @@ void Menu::Sort() { fs::FsPath star_path; for (auto& p : m_entries) { p.has_star = fs.FileExists(GenerateStarPath(p.path)); - if (p.has_star) { + if (p.has_star == true) { log_write("found star: %s\n", p.path.s); } else { log_write("no star: %s\n", p.path.s); From 37890f157dce31870e4b186c8e0449ecb9bd2a5e Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Wed, 25 Dec 2024 22:17:21 +0000 Subject: [PATCH 23/25] add mtp (haze) ftp (ftpsrv), update RA file assoc, nxlink now polls for connection. --- assets/romfs/assoc/2048_libretro_libnx.ini | 4 - .../assoc/DoubleCherryGB_libretro_libnx.ini | 4 + assets/romfs/assoc/ardens_libretro_libnx.ini | 4 + assets/romfs/assoc/arduous_libretro_libnx.ini | 2 +- .../romfs/assoc/atari800_libretro_libnx.ini | 2 +- assets/romfs/assoc/bluemsx_libretro_libnx.ini | 4 +- assets/romfs/assoc/citra_libretro_libnx.ini | 4 - .../assoc/dosbox_pure_libretro_libnx.ini | 4 + .../romfs/assoc/dosbox_svn_libretro_libnx.ini | 2 +- .../assoc/fbalpha2012_cps1_libretro_libnx.ini | 3 - .../assoc/fbalpha2012_cps2_libretro_libnx.ini | 3 - .../assoc/fbalpha2012_libretro_libnx.ini | 3 - .../fbalpha2012_neogeo_libretro_libnx.ini | 3 - assets/romfs/assoc/frodo_libretro_libnx.ini | 2 +- assets/romfs/assoc/fuse_libretro_libnx.ini | 2 +- assets/romfs/assoc/gme_libretro_libnx.ini | 3 - assets/romfs/assoc/gong_libretro_libnx.ini | 3 - assets/romfs/assoc/gpsp_libretro_libnx.ini | 4 + assets/romfs/assoc/handy_libretro_libnx.ini | 2 +- .../romfs/assoc/mame2000_libretro_libnx.ini | 2 +- .../assoc/mednafen_lynx_libretro_libnx.ini | 2 +- .../romfs/assoc/minivmac_libretro_libnx.ini | 3 - assets/romfs/assoc/mrboom_libretro_libnx.ini | 4 + assets/romfs/assoc/mu_libretro_libnx.ini | 3 - assets/romfs/assoc/numero_libretro_libnx.ini | 3 - .../assoc/pcsx_rearmed_libretro_libnx.ini | 2 +- .../romfs/assoc/pocketcdg_libretro_libnx.ini | 3 - assets/romfs/assoc/ppsspp_libretro_libnx.ini | 2 +- assets/romfs/assoc/px68k_libretro_libnx.ini | 2 +- assets/romfs/assoc/quasi88_libretro_libnx.ini | 1 + assets/romfs/assoc/retro8_libretro_libnx.ini | 2 +- ...ibnx.ini => stella2023_libretro_libnx.ini} | 2 +- .../assoc/superbroswar_libretro_libnx.ini | 3 - .../romfs/assoc/vircon32_libretro_libnx.ini | 4 + assets/romfs/assoc/x1_libretro_libnx.ini | 2 +- sphaira/CMakeLists.txt | 47 +++ sphaira/include/app.hpp | 9 +- sphaira/include/defines.hpp | 62 ++-- sphaira/include/evman.hpp | 2 + sphaira/include/ftpsrv_helper.hpp | 33 ++ sphaira/include/ui/menus/filebrowser.hpp | 7 +- sphaira/source/app.cpp | 81 +++++ sphaira/source/download.cpp | 2 +- sphaira/source/fs.cpp | 6 +- sphaira/source/ftpsrv_helper.cpp | 335 ++++++++++++++++++ sphaira/source/main.cpp | 3 + sphaira/source/nxlink.cpp | 90 ++--- sphaira/source/ui/menus/appstore.cpp | 2 +- sphaira/source/ui/menus/filebrowser.cpp | 237 ++++++------- sphaira/source/ui/menus/main_menu.cpp | 12 +- sphaira/source/ui/menus/themezer.cpp | 2 +- sphaira/source/ui/notification.cpp | 3 + 52 files changed, 742 insertions(+), 289 deletions(-) delete mode 100644 assets/romfs/assoc/2048_libretro_libnx.ini create mode 100644 assets/romfs/assoc/DoubleCherryGB_libretro_libnx.ini create mode 100644 assets/romfs/assoc/ardens_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/citra_libretro_libnx.ini create mode 100644 assets/romfs/assoc/dosbox_pure_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/fbalpha2012_cps1_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/fbalpha2012_cps2_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/fbalpha2012_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/fbalpha2012_neogeo_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/gme_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/gong_libretro_libnx.ini create mode 100644 assets/romfs/assoc/gpsp_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/minivmac_libretro_libnx.ini create mode 100644 assets/romfs/assoc/mrboom_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/mu_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/numero_libretro_libnx.ini delete mode 100644 assets/romfs/assoc/pocketcdg_libretro_libnx.ini rename assets/romfs/assoc/{stella_libretro_libnx.ini => stella2023_libretro_libnx.ini} (53%) delete mode 100644 assets/romfs/assoc/superbroswar_libretro_libnx.ini create mode 100644 assets/romfs/assoc/vircon32_libretro_libnx.ini create mode 100644 sphaira/include/ftpsrv_helper.hpp create mode 100644 sphaira/source/ftpsrv_helper.cpp diff --git a/assets/romfs/assoc/2048_libretro_libnx.ini b/assets/romfs/assoc/2048_libretro_libnx.ini deleted file mode 100644 index 8900e63..0000000 --- a/assets/romfs/assoc/2048_libretro_libnx.ini +++ /dev/null @@ -1,4 +0,0 @@ -[config] -path=/retroarch/cores/2048_libretro_libnx.nro -supported_extensions= -database=2048 diff --git a/assets/romfs/assoc/DoubleCherryGB_libretro_libnx.ini b/assets/romfs/assoc/DoubleCherryGB_libretro_libnx.ini new file mode 100644 index 0000000..7efa37a --- /dev/null +++ b/assets/romfs/assoc/DoubleCherryGB_libretro_libnx.ini @@ -0,0 +1,4 @@ +[config] +path=/retroarch/cores/DoubleCherryGB_libretro_libnx.nro +supported_extensions=cgb|dmg|gb|gbc|sgb +database=Nintendo - Game Boy|Nintendo - Game Boy Color diff --git a/assets/romfs/assoc/ardens_libretro_libnx.ini b/assets/romfs/assoc/ardens_libretro_libnx.ini new file mode 100644 index 0000000..fec2702 --- /dev/null +++ b/assets/romfs/assoc/ardens_libretro_libnx.ini @@ -0,0 +1,4 @@ +[config] +path=/retroarch/cores/ardens_libretro_libnx.nro +supported_extensions=hex|arduboy +database=Arduboy Inc - Arduboy diff --git a/assets/romfs/assoc/arduous_libretro_libnx.ini b/assets/romfs/assoc/arduous_libretro_libnx.ini index 7c81ce7..981a1b0 100644 --- a/assets/romfs/assoc/arduous_libretro_libnx.ini +++ b/assets/romfs/assoc/arduous_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/arduous_libretro_libnx.nro supported_extensions=hex -database=Arduboy +database=Arduboy Inc - Arduboy diff --git a/assets/romfs/assoc/atari800_libretro_libnx.ini b/assets/romfs/assoc/atari800_libretro_libnx.ini index ad36238..c722b81 100644 --- a/assets/romfs/assoc/atari800_libretro_libnx.ini +++ b/assets/romfs/assoc/atari800_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/atari800_libretro_libnx.nro -supported_extensions=xfd|atr|cdm|cas|bin|a52|zip|atx|car|rom|com|xex +supported_extensions=xfd|atr|dcm|cas|bin|a52|zip|atx|car|rom|com|xex|m3u database=Atari - 5200|Atari - 8-bit diff --git a/assets/romfs/assoc/bluemsx_libretro_libnx.ini b/assets/romfs/assoc/bluemsx_libretro_libnx.ini index 1b040a7..079eec5 100644 --- a/assets/romfs/assoc/bluemsx_libretro_libnx.ini +++ b/assets/romfs/assoc/bluemsx_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/bluemsx_libretro_libnx.nro -supported_extensions=rom|ri|mx1|mx2|col|dsk|cas|sg|sc|sf|m3u -database=Microsoft - MSX|Microsoft - MSX2|Coleco - ColecoVision|Sega - SG-1000 +supported_extensions=rom|ri|mx1|mx2|dsk|col|sg|sc|sf|cas|m3u +database=Microsoft - MSX|Microsoft - MSX2|Coleco - ColecoVision|Sega - SG-1000|Spectravideo - SVI-318 - SVI-328 diff --git a/assets/romfs/assoc/citra_libretro_libnx.ini b/assets/romfs/assoc/citra_libretro_libnx.ini deleted file mode 100644 index 8597ddd..0000000 --- a/assets/romfs/assoc/citra_libretro_libnx.ini +++ /dev/null @@ -1,4 +0,0 @@ -[config] -path=/retroarch/cores/citra_libretro_libnx.nro -supported_extensions=3ds|3dsx|elf|axf|cci|cxi|app -database=Nintendo - Nintendo 3DS diff --git a/assets/romfs/assoc/dosbox_pure_libretro_libnx.ini b/assets/romfs/assoc/dosbox_pure_libretro_libnx.ini new file mode 100644 index 0000000..cdcfe73 --- /dev/null +++ b/assets/romfs/assoc/dosbox_pure_libretro_libnx.ini @@ -0,0 +1,4 @@ +[config] +path=/retroarch/cores/dosbox_pure_libretro_libnx.nro +supported_extensions=zip|dosz|exe|com|bat|iso|chd|cue|ins|img|ima|vhd|jrc|tc|m3u|m3u8|conf|/ +database=DOS diff --git a/assets/romfs/assoc/dosbox_svn_libretro_libnx.ini b/assets/romfs/assoc/dosbox_svn_libretro_libnx.ini index 6801fa2..f075a6e 100644 --- a/assets/romfs/assoc/dosbox_svn_libretro_libnx.ini +++ b/assets/romfs/assoc/dosbox_svn_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/dosbox_svn_libretro_libnx.nro -supported_extensions=exe|com|bat|conf|cue|iso +supported_extensions=exe|com|bat|conf|cue|iso|img|/ database=DOS diff --git a/assets/romfs/assoc/fbalpha2012_cps1_libretro_libnx.ini b/assets/romfs/assoc/fbalpha2012_cps1_libretro_libnx.ini deleted file mode 100644 index 9a34990..0000000 --- a/assets/romfs/assoc/fbalpha2012_cps1_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/fbalpha2012_cps1_libretro_libnx.nro -supported_extensions=zip diff --git a/assets/romfs/assoc/fbalpha2012_cps2_libretro_libnx.ini b/assets/romfs/assoc/fbalpha2012_cps2_libretro_libnx.ini deleted file mode 100644 index 767310d..0000000 --- a/assets/romfs/assoc/fbalpha2012_cps2_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/fbalpha2012_cps2_libretro_libnx.nro -supported_extensions=zip diff --git a/assets/romfs/assoc/fbalpha2012_libretro_libnx.ini b/assets/romfs/assoc/fbalpha2012_libretro_libnx.ini deleted file mode 100644 index 7ab3910..0000000 --- a/assets/romfs/assoc/fbalpha2012_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/fbalpha2012_libretro_libnx.nro -supported_extensions=iso|zip|7z diff --git a/assets/romfs/assoc/fbalpha2012_neogeo_libretro_libnx.ini b/assets/romfs/assoc/fbalpha2012_neogeo_libretro_libnx.ini deleted file mode 100644 index b56c759..0000000 --- a/assets/romfs/assoc/fbalpha2012_neogeo_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/fbalpha2012_neogeo_libretro_libnx.nro -supported_extensions=zip diff --git a/assets/romfs/assoc/frodo_libretro_libnx.ini b/assets/romfs/assoc/frodo_libretro_libnx.ini index 73b574e..d949664 100644 --- a/assets/romfs/assoc/frodo_libretro_libnx.ini +++ b/assets/romfs/assoc/frodo_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/frodo_libretro_libnx.nro -supported_extensions=d64|t64|x64|p00|lnx|zip +supported_extensions=d64|t64|x64|p00|lnx|lyx|zip database=Commodore - 64 diff --git a/assets/romfs/assoc/fuse_libretro_libnx.ini b/assets/romfs/assoc/fuse_libretro_libnx.ini index 778fd29..874e3fe 100644 --- a/assets/romfs/assoc/fuse_libretro_libnx.ini +++ b/assets/romfs/assoc/fuse_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/fuse_libretro_libnx.nro -supported_extensions=tzx|tap|z80|rzx|scl|trd|dsk|zip +supported_extensions=tzx|tap|z80|rzx|scl|trd|dsk|dck|sna|szx|zip database=Sinclair - ZX Spectrum +3|Sinclair - ZX Spectrum diff --git a/assets/romfs/assoc/gme_libretro_libnx.ini b/assets/romfs/assoc/gme_libretro_libnx.ini deleted file mode 100644 index 980c3f2..0000000 --- a/assets/romfs/assoc/gme_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/gme_libretro_libnx.nro -supported_extensions=ay|gbs|gym|hes|kss|nsf|nsfe|sap|spc|vgm|vgz|zip diff --git a/assets/romfs/assoc/gong_libretro_libnx.ini b/assets/romfs/assoc/gong_libretro_libnx.ini deleted file mode 100644 index e767c0c..0000000 --- a/assets/romfs/assoc/gong_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/gong_libretro_libnx.nro -supported_extensions= diff --git a/assets/romfs/assoc/gpsp_libretro_libnx.ini b/assets/romfs/assoc/gpsp_libretro_libnx.ini new file mode 100644 index 0000000..881124b --- /dev/null +++ b/assets/romfs/assoc/gpsp_libretro_libnx.ini @@ -0,0 +1,4 @@ +[config] +path=/retroarch/cores/gpsp_libretro_libnx.nro +supported_extensions=gba|bin +database=Nintendo - Game Boy Advance diff --git a/assets/romfs/assoc/handy_libretro_libnx.ini b/assets/romfs/assoc/handy_libretro_libnx.ini index af97bd8..a221626 100644 --- a/assets/romfs/assoc/handy_libretro_libnx.ini +++ b/assets/romfs/assoc/handy_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/handy_libretro_libnx.nro -supported_extensions=lnx|o +supported_extensions=lnx|lyx|o database=Atari - Lynx diff --git a/assets/romfs/assoc/mame2000_libretro_libnx.ini b/assets/romfs/assoc/mame2000_libretro_libnx.ini index 3de6c5d..a58ec96 100644 --- a/assets/romfs/assoc/mame2000_libretro_libnx.ini +++ b/assets/romfs/assoc/mame2000_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/mame2000_libretro_libnx.nro -supported_extensions=zip|7z|chd +supported_extensions=zip|7z database=MAME 2000 diff --git a/assets/romfs/assoc/mednafen_lynx_libretro_libnx.ini b/assets/romfs/assoc/mednafen_lynx_libretro_libnx.ini index 8dd9abc..67d999d 100644 --- a/assets/romfs/assoc/mednafen_lynx_libretro_libnx.ini +++ b/assets/romfs/assoc/mednafen_lynx_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/mednafen_lynx_libretro_libnx.nro -supported_extensions=lnx|o +supported_extensions=lnx|lyx|o database=Atari - Lynx diff --git a/assets/romfs/assoc/minivmac_libretro_libnx.ini b/assets/romfs/assoc/minivmac_libretro_libnx.ini deleted file mode 100644 index f047720..0000000 --- a/assets/romfs/assoc/minivmac_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/minivmac_libretro_libnx.nro -supported_extensions=dsk|img|zip|hvf|cmd diff --git a/assets/romfs/assoc/mrboom_libretro_libnx.ini b/assets/romfs/assoc/mrboom_libretro_libnx.ini new file mode 100644 index 0000000..66b7c1c --- /dev/null +++ b/assets/romfs/assoc/mrboom_libretro_libnx.ini @@ -0,0 +1,4 @@ +[config] +path=/retroarch/cores/mrboom_libretro_libnx.nro +supported_extensions=desktop +database=MrBoom diff --git a/assets/romfs/assoc/mu_libretro_libnx.ini b/assets/romfs/assoc/mu_libretro_libnx.ini deleted file mode 100644 index 61ee02b..0000000 --- a/assets/romfs/assoc/mu_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/mu_libretro_libnx.nro -supported_extensions=prc|pqa|img|pdb|zip diff --git a/assets/romfs/assoc/numero_libretro_libnx.ini b/assets/romfs/assoc/numero_libretro_libnx.ini deleted file mode 100644 index 8dc5772..0000000 --- a/assets/romfs/assoc/numero_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/numero_libretro_libnx.nro -supported_extensions=8xp|8xk|8xg diff --git a/assets/romfs/assoc/pcsx_rearmed_libretro_libnx.ini b/assets/romfs/assoc/pcsx_rearmed_libretro_libnx.ini index 9861603..3c8f2e4 100644 --- a/assets/romfs/assoc/pcsx_rearmed_libretro_libnx.ini +++ b/assets/romfs/assoc/pcsx_rearmed_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/pcsx_rearmed_libretro_libnx.nro -supported_extensions=bin|cue|img|mdf|pbp|toc|cbn|m3u|ccd|chd +supported_extensions=bin|cue|img|mdf|pbp|toc|cbn|m3u|ccd|chd|iso|exe database=Sony - PlayStation diff --git a/assets/romfs/assoc/pocketcdg_libretro_libnx.ini b/assets/romfs/assoc/pocketcdg_libretro_libnx.ini deleted file mode 100644 index a2a4144..0000000 --- a/assets/romfs/assoc/pocketcdg_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/pocketcdg_libretro_libnx.nro -supported_extensions=cdg diff --git a/assets/romfs/assoc/ppsspp_libretro_libnx.ini b/assets/romfs/assoc/ppsspp_libretro_libnx.ini index 90538e2..fcad92f 100644 --- a/assets/romfs/assoc/ppsspp_libretro_libnx.ini +++ b/assets/romfs/assoc/ppsspp_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/ppsspp_libretro_libnx.nro -supported_extensions=elf|iso|cso|prx|pbp +supported_extensions=elf|iso|cso|prx|pbp|chd database=Sony - PlayStation Portable diff --git a/assets/romfs/assoc/px68k_libretro_libnx.ini b/assets/romfs/assoc/px68k_libretro_libnx.ini index a83b5d7..de1c4b3 100644 --- a/assets/romfs/assoc/px68k_libretro_libnx.ini +++ b/assets/romfs/assoc/px68k_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/px68k_libretro_libnx.nro -supported_extensions=dim|zip|img|d88|88d|hdm|dup|2hd|xdf|hdf|cmd|m3u +supported_extensions=dim|img|d88|88d|hdm|dup|2hd|xdf|hdf|cmd|m3u database=Sharp - X68000 diff --git a/assets/romfs/assoc/quasi88_libretro_libnx.ini b/assets/romfs/assoc/quasi88_libretro_libnx.ini index 2323e69..d2bcae4 100644 --- a/assets/romfs/assoc/quasi88_libretro_libnx.ini +++ b/assets/romfs/assoc/quasi88_libretro_libnx.ini @@ -1,3 +1,4 @@ [config] path=/retroarch/cores/quasi88_libretro_libnx.nro supported_extensions=d88|u88|m3u +database=NEC - PC-8001 - PC-8801 diff --git a/assets/romfs/assoc/retro8_libretro_libnx.ini b/assets/romfs/assoc/retro8_libretro_libnx.ini index cd834b7..f47c185 100644 --- a/assets/romfs/assoc/retro8_libretro_libnx.ini +++ b/assets/romfs/assoc/retro8_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/retro8_libretro_libnx.nro supported_extensions=p8|png -database=PICO8 +database=PICO-8 diff --git a/assets/romfs/assoc/stella_libretro_libnx.ini b/assets/romfs/assoc/stella2023_libretro_libnx.ini similarity index 53% rename from assets/romfs/assoc/stella_libretro_libnx.ini rename to assets/romfs/assoc/stella2023_libretro_libnx.ini index 79602a1..2ceb89d 100644 --- a/assets/romfs/assoc/stella_libretro_libnx.ini +++ b/assets/romfs/assoc/stella2023_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] -path=/retroarch/cores/stella_libretro_libnx.nro +path=/retroarch/cores/stella2023_libretro_libnx.nro supported_extensions=a26|bin database=Atari - 2600 diff --git a/assets/romfs/assoc/superbroswar_libretro_libnx.ini b/assets/romfs/assoc/superbroswar_libretro_libnx.ini deleted file mode 100644 index 143236e..0000000 --- a/assets/romfs/assoc/superbroswar_libretro_libnx.ini +++ /dev/null @@ -1,3 +0,0 @@ -[config] -path=/retroarch/cores/superbroswar_libretro_libnx.nro -supported_extensions=game diff --git a/assets/romfs/assoc/vircon32_libretro_libnx.ini b/assets/romfs/assoc/vircon32_libretro_libnx.ini new file mode 100644 index 0000000..53cbd4e --- /dev/null +++ b/assets/romfs/assoc/vircon32_libretro_libnx.ini @@ -0,0 +1,4 @@ +[config] +path=/retroarch/cores/vircon32_libretro_libnx.nro +supported_extensions=v32|V32 +database=Vircon32 diff --git a/assets/romfs/assoc/x1_libretro_libnx.ini b/assets/romfs/assoc/x1_libretro_libnx.ini index 4e2d015..df45e0b 100644 --- a/assets/romfs/assoc/x1_libretro_libnx.ini +++ b/assets/romfs/assoc/x1_libretro_libnx.ini @@ -1,4 +1,4 @@ [config] path=/retroarch/cores/x1_libretro_libnx.nro supported_extensions=dx1|zip|2d|2hd|tfd|d88|88d|hdm|xdf|dup|tap|cmd -database=Sharp X1 +database=Sharp - X1 diff --git a/sphaira/CMakeLists.txt b/sphaira/CMakeLists.txt index b10566b..6d78e42 100644 --- a/sphaira/CMakeLists.txt +++ b/sphaira/CMakeLists.txt @@ -72,6 +72,7 @@ add_executable(sphaira source/swkbd.cpp source/web.cpp source/i18n.cpp + source/ftpsrv_helper.cpp ) target_compile_definitions(sphaira PRIVATE @@ -82,6 +83,16 @@ target_compile_definitions(sphaira PRIVATE include(FetchContent) set(FETCHCONTENT_QUIET FALSE) +FetchContent_Declare(ftpsrv + GIT_REPOSITORY https://github.com/ITotalJustice/ftpsrv.git + GIT_TAG 8d5a14e +) + +FetchContent_Declare(libhaze + GIT_REPOSITORY https://github.com/ITotalJustice/libhaze.git + GIT_TAG 3244b9e +) + FetchContent_Declare(libpulsar GIT_REPOSITORY https://github.com/ITotalJustice/switch-libpulsar.git GIT_TAG d729be3 @@ -135,7 +146,16 @@ set(YYJSON_DISABLE_NON_STANDARD ON) set(YYJSON_DISABLE_UTF8_VALIDATION ON) set(YYJSON_DISABLE_UNALIGNED_MEMORY_ACCESS OFF) +set(FTPSRV_LIB_BUILD TRUE) +set(FTPSRV_LIB_SOCK_UNISTD TRUE) +set(FTPSRV_LIB_VFS_CUSTOM ${CMAKE_CURRENT_SOURCE_DIR}/include/ftpsrv_helper.hpp) +set(FTPSRV_LIB_PATH_SIZE 0x301) +set(FTPSRV_LIB_SESSIONS 32) +set(FTPSRV_LIB_BUF_SIZE 1024*64) + FetchContent_MakeAvailable( + ftpsrv + libhaze libpulsar nanovg stb @@ -143,6 +163,31 @@ FetchContent_MakeAvailable( yyjson ) +# todo: upstream cmake +add_library(libhaze + ${libhaze_SOURCE_DIR}/source/async_usb_server.cpp + ${libhaze_SOURCE_DIR}/source/device_properties.cpp + ${libhaze_SOURCE_DIR}/source/event_reactor.cpp + ${libhaze_SOURCE_DIR}/source/haze.cpp + ${libhaze_SOURCE_DIR}/source/ptp_object_database.cpp + ${libhaze_SOURCE_DIR}/source/ptp_object_heap.cpp + ${libhaze_SOURCE_DIR}/source/ptp_responder_android_operations.cpp + ${libhaze_SOURCE_DIR}/source/ptp_responder_mtp_operations.cpp + ${libhaze_SOURCE_DIR}/source/ptp_responder_ptp_operations.cpp + ${libhaze_SOURCE_DIR}/source/ptp_responder.cpp + ${libhaze_SOURCE_DIR}/source/usb_session.cpp +) +target_include_directories(libhaze PUBLIC ${libhaze_SOURCE_DIR}/include) +set_target_properties(libhaze PROPERTIES + C_STANDARD 11 + C_EXTENSIONS ON + CXX_STANDARD 20 + CXX_EXTENSIONS ON + # force optimisations in debug mode as otherwise vapor errors + # due to force_inline attribute failing... + COMPILE_OPTIONS "$<$:-Os>" +) + # todo: upstream cmake add_library(libpulsar ${libpulsar_SOURCE_DIR}/src/archive/archive_file.c @@ -195,6 +240,8 @@ set_target_properties(sphaira PROPERTIES ) target_link_libraries(sphaira PRIVATE + ftpsrv + libhaze libpulsar minIni-sphaira nanovg diff --git a/sphaira/include/app.hpp b/sphaira/include/app.hpp index 4566021..690a945 100644 --- a/sphaira/include/app.hpp +++ b/sphaira/include/app.hpp @@ -46,11 +46,12 @@ class App { static auto GetVg() -> NVGcontext*; static void Push(std::shared_ptr); - // this is thread safe (todo: make it thread safe) + // this is thread safe static void Notify(std::string text, ui::NotifEntry::Side side = ui::NotifEntry::Side::RIGHT); static void Notify(ui::NotifEntry entry); static void NotifyPop(ui::NotifEntry::Side side = ui::NotifEntry::Side::RIGHT); static void NotifyClear(ui::NotifEntry::Side side = ui::NotifEntry::Side::RIGHT); + static void NotifyFlashLed(); static auto GetThemeMetaList() -> std::span; static void SetTheme(u64 theme_index); @@ -61,6 +62,8 @@ class App { // returns true if we are hbmenu. static auto IsHbmenu() -> bool; + static auto GetMtpEnable() -> bool; + static auto GetFtpEnable() -> bool; static auto GetNxlinkEnable() -> bool; static auto GetLogEnable() -> bool; static auto GetReplaceHbmenuEnable() -> bool; @@ -71,6 +74,8 @@ class App { static auto GetThemeMusicEnable() -> bool; static auto GetLanguage() -> long; + static void SetMtpEnable(bool enable); + static void SetFtpEnable(bool enable); static void SetNxlinkEnable(bool enable); static void SetLogEnable(bool enable); static void SetReplaceHbmenuEnable(bool enable); @@ -138,6 +143,8 @@ class App { bool m_quit{}; option::OptionBool m_nxlink_enabled{INI_SECTION, "nxlink_enabled", true}; + option::OptionBool m_mtp_enabled{INI_SECTION, "mtp_enabled", false}; + option::OptionBool m_ftp_enabled{INI_SECTION, "ftp_enabled", false}; option::OptionBool m_log_enabled{INI_SECTION, "log_enabled", false}; option::OptionBool m_replace_hbmenu{INI_SECTION, "replace_hbmenu", false}; option::OptionBool m_install{INI_SECTION, "install", false}; diff --git a/sphaira/include/defines.hpp b/sphaira/include/defines.hpp index c9da42c..b1c9bd5 100644 --- a/sphaira/include/defines.hpp +++ b/sphaira/include/defines.hpp @@ -224,18 +224,18 @@ enum SvcError { }; enum FsError { - FsError_ResultPathNotFound = 0x202, - FsError_ResultPathAlreadyExists = 0x402, - FsError_ResultTargetLocked = 0xE02, + FsError_PathNotFound = 0x202, + FsError_PathAlreadyExists = 0x402, + FsError_TargetLocked = 0xE02, FsError_UsableSpaceNotEnoughMmcCalibration = 0x4602, FsError_UsableSpaceNotEnoughMmcSafe = 0x4802, FsError_UsableSpaceNotEnoughMmcUser = 0x4A02, FsError_UsableSpaceNotEnoughMmcSystem = 0x4C02, - FsError_ResultUsableSpaceNotEnoughSdCard = 0x4E02, - FsError_ResultUnsupportedSdkVersion = 0x6402, - FsError_ResultMountNameAlreadyExists = 0x7802, - FsError_ResultPartitionNotFound = 0x7D202, - FsError_ResultTargetNotFound = 0x7D402, + FsError_UsableSpaceNotEnoughSdCard = 0x4E02, + FsError_UnsupportedSdkVersion = 0x6402, + FsError_MountNameAlreadyExists = 0x7802, + FsError_PartitionNotFound = 0x7D202, + FsError_TargetNotFound = 0x7D402, FsError_PortSdCardNoDevice = 0xFA202, FsError_GameCardCardNotInserted = 0x13B002, FsError_GameCardCardNotActivated = 0x13B402, @@ -286,9 +286,9 @@ enum FsError { FsError_GameCardFsCheckHandleInGetStatusFailure = 0x171402, FsError_GameCardFsCheckHandleInCreateReadOnlyFailure = 0x172002, FsError_GameCardFsCheckHandleInCreateSecureReadOnlyFailure = 0x172202, - FsError_ResultNotImplemented = 0x177202, - FsError_ResultAlreadyExists = 0x177602, - FsError_ResultOutOfRange = 0x177A02, + FsError_NotImplemented = 0x177202, + FsError_AlreadyExists = 0x177602, + FsError_OutOfRange = 0x177A02, FsError_AllocationMemoryFailedInFatFileSystemA = 0x190202, FsError_AllocationMemoryFailedInFatFileSystemB = 0x190402, FsError_AllocationMemoryFailedInFatFileSystemC = 0x190602, @@ -348,18 +348,18 @@ enum FsError { FsError_FatFsFormatIllegalSectorsC = 0x280C02, FsError_FatFsFormatIllegalSectorsD = 0x280E02, FsError_UnexpectedInMountTableA = 0x296A02, - FsError_ResultTooLongPath = 0x2EE602, - FsError_ResultInvalidCharacter = 0x2EE802, - FsError_ResultInvalidPathFormat = 0x2EEA02, - FsError_ResultDirectoryUnobtainable = 0x2EEC02, - FsError_ResultInvalidOffset = 0x2F5A02, - FsError_ResultInvalidSize = 0x2F5C02, - FsError_ResultNullptrArgument = 0x2F5E02, - FsError_ResultInvalidAlignment = 0x2F6002, - FsError_ResultInvalidMountName = 0x2F6202, - FsError_ResultExtensionSizeTooLarge = 0x2F6402, - FsError_ResultExtensionSizeInvalid = 0x2F6602, - FsError_ResultFileExtensionWithoutOpenModeAllowAppend = 0x307202, + FsError_TooLongPath = 0x2EE602, + FsError_InvalidCharacter = 0x2EE802, + FsError_InvalidPathFormat = 0x2EEA02, + FsError_DirectoryUnobtainable = 0x2EEC02, + FsError_InvalidOffset = 0x2F5A02, + FsError_InvalidSize = 0x2F5C02, + FsError_NullptrArgument = 0x2F5E02, + FsError_InvalidAlignment = 0x2F6002, + FsError_InvalidMountName = 0x2F6202, + FsError_ExtensionSizeTooLarge = 0x2F6402, + FsError_ExtensionSizeInvalid = 0x2F6602, + FsError_FileExtensionWithoutOpenModeAllowAppend = 0x307202, FsError_UnsupportedCommitTarget = 0x313A02, FsError_UnsupportedSetSizeForNotResizableSubStorage = 0x313C02, FsError_UnsupportedSetSizeForResizableSubStorage = 0x313E02, @@ -444,14 +444,14 @@ enum FsError { FsError_UnsupportedCommitProvisionallyForDirectorySaveDataFileSystem = 0x31E002, FsError_UnsupportedWriteForZeroBitmapHashStorageFile = 0x31E202, FsError_UnsupportedSetSizeForZeroBitmapHashStorageFile = 0x31E402, - FsError_ResultNcaExternalKeyUnregisteredDeprecated = 0x326602, - FsError_ResultFileNotClosed = 0x326E02, - FsError_ResultDirectoryNotClosed = 0x327002, - FsError_ResultWriteModeFileNotClosed = 0x327202, - FsError_ResultAllocatorAlreadyRegistered = 0x327402, - FsError_ResultDefaultAllocatorAlreadyUsed = 0x327602, - FsError_ResultAllocatorAlignmentViolation = 0x327A02, - FsError_ResultUserNotExist = 0x328202, + FsError_NcaExternalKeyUnregisteredDeprecated = 0x326602, + FsError_FileNotClosed = 0x326E02, + FsError_DirectoryNotClosed = 0x327002, + FsError_WriteModeFileNotClosed = 0x327202, + FsError_AllocatorAlreadyRegistered = 0x327402, + FsError_DefaultAllocatorAlreadyUsed = 0x327602, + FsError_AllocatorAlignmentViolation = 0x327A02, + FsError_UserNotExist = 0x328202, FsError_FileNotFound = 0x339402, FsError_DirectoryNotFound = 0x339602, FsError_MappingTableFull = 0x346402, diff --git a/sphaira/include/evman.hpp b/sphaira/include/evman.hpp index cba3385..43c4d7b 100644 --- a/sphaira/include/evman.hpp +++ b/sphaira/include/evman.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "download.hpp" namespace sphaira::evman { @@ -23,6 +24,7 @@ struct ExitEventData { using EventData = std::variant< LaunchNroEventData, ExitEventData, + HazeCallbackData, NxlinkCallbackData, DownloadEventData >; diff --git a/sphaira/include/ftpsrv_helper.hpp b/sphaira/include/ftpsrv_helper.hpp new file mode 100644 index 0000000..77871ae --- /dev/null +++ b/sphaira/include/ftpsrv_helper.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +struct FtpVfsFile { + FsFile fd; + s64 off; + s64 buf_off; + s64 buf_size; + bool is_write; + bool is_valid; + u8 buf[1024 * 1024 * 1]; +}; + +struct FtpVfsDir { + FsDir dir; + bool is_valid; +}; + +struct FtpVfsDirEntry { + FsDirectoryEntry buf; +}; + +#ifdef __cplusplus + +namespace sphaira::ftpsrv { + +bool Init(); +void Exit(); + +} // namespace sphaira::ftpsrv + +#endif // __cplusplus diff --git a/sphaira/include/ui/menus/filebrowser.hpp b/sphaira/include/ui/menus/filebrowser.hpp index ce50a6f..750052f 100644 --- a/sphaira/include/ui/menus/filebrowser.hpp +++ b/sphaira/include/ui/menus/filebrowser.hpp @@ -110,19 +110,18 @@ struct Menu final : MenuBase { void LoadAssocEntriesPath(const fs::FsPath& path); void LoadAssocEntries(); auto FindFileAssocFor() -> std::vector; - void OnIndexChange(); auto GetNewPath(const FileEntry& entry) const -> fs::FsPath { return GetNewPath(m_path, entry.name); - }; + } auto GetNewPath(u64 index) const -> fs::FsPath { return GetNewPath(m_path, GetEntry(index).name); - }; + } auto GetNewPathCurrent() const -> fs::FsPath { return GetNewPath(m_index); - }; + } auto GetSelectedEntries() const -> std::vector { if (!m_selected_count) { diff --git a/sphaira/source/app.cpp b/sphaira/source/app.cpp index 5b1ad51..e3ead37 100644 --- a/sphaira/source/app.cpp +++ b/sphaira/source/app.cpp @@ -12,10 +12,12 @@ #include "fs.hpp" #include "defines.hpp" #include "i18n.hpp" +#include "ftpsrv_helper.hpp" #include #include #include +#include #include #include #include @@ -200,7 +202,13 @@ auto GetNroIcon(const std::vector& nro_icon) -> std::vector { return nro_icon; } +void haze_callback(const HazeCallbackData *data) { + App::NotifyFlashLed(); + evman::push(*data, false); +} + void nxlink_callback(const NxlinkCallbackData *data) { + App::NotifyFlashLed(); evman::push(*data, false); } @@ -247,6 +255,9 @@ void App::Loop() { } else if constexpr(std::is_same_v) { log_write("[ExitEventData] got event\n"); m_quit = true; + } else if constexpr(std::is_same_v) { + // log_write("[ExitEventData] got event\n"); + // m_quit = true; } else if constexpr(std::is_same_v) { switch (arg.type) { case NxlinkCallbackType_Connected: @@ -330,6 +341,28 @@ void App::NotifyClear(ui::NotifEntry::Side side) { g_app->m_notif_manager.Clear(side); } +void App::NotifyFlashLed() { + static const HidsysNotificationLedPattern pattern = { + .baseMiniCycleDuration = 0x1, // 12.5ms. + .totalMiniCycles = 0x1, // 1 mini cycle(s). + .totalFullCycles = 0x1, // 1 full run(s). + .startIntensity = 0xF, // 100%. + .miniCycles = {{ + .ledIntensity = 0xF, // 100%. + .transitionSteps = 0xF, // 1 step(s). Total 12.5ms. + .finalStepDuration = 0xF, // Forced 12.5ms. + }} + }; + + s32 total; + HidsysUniquePadId unique_pad_ids[16] = {0}; + if (R_SUCCEEDED(hidsysGetUniquePadIds(unique_pad_ids, 16, &total))) { + for (int i = 0; i < total; i++) { + hidsysSetNotificationLedPattern(&pattern, unique_pad_ids[i]); + } + } +} + auto App::GetThemeMetaList() -> std::span { return g_app->m_theme_meta_entries; } @@ -383,6 +416,14 @@ auto App::GetThemeMusicEnable() -> bool { return g_app->m_theme_music.Get(); } +auto App::GetMtpEnable() -> bool { + return g_app->m_mtp_enabled.Get(); +} + +auto App::GetFtpEnable() -> bool { + return g_app->m_ftp_enabled.Get(); +} + auto App::GetLanguage() -> long { return g_app->m_language.Get(); } @@ -434,6 +475,28 @@ void App::SetThemeMusicEnable(bool enable) { PlaySoundEffect(SoundEffect::SoundEffect_Music); } +void App::SetMtpEnable(bool enable) { + if (App::GetMtpEnable() != enable) { + g_app->m_mtp_enabled.Set(enable); + if (enable) { + hazeInitialize(haze_callback); + } else { + hazeExit(); + } + } +} + +void App::SetFtpEnable(bool enable) { + if (App::GetFtpEnable() != enable) { + g_app->m_ftp_enabled.Set(enable); + if (enable) { + ftpsrv::Init(); + } else { + ftpsrv::Exit(); + } + } +} + void App::SetLanguage(long index) { if (App::GetLanguage() != index) { g_app->m_language.Set(index); @@ -860,6 +923,14 @@ App::App(const char* argv0) { log_write("hello world\n"); } + if (App::GetMtpEnable()) { + hazeInitialize(haze_callback); + } + + if (App::GetFtpEnable()) { + ftpsrv::Init(); + } + if (App::GetNxlinkEnable()) { nxlinkInitialize(nxlink_callback); } @@ -1092,6 +1163,16 @@ App::~App() { } } + if (App::GetMtpEnable()) { + log_write("closing mtp\n"); + hazeExit(); + } + + if (App::GetFtpEnable()) { + log_write("closing ftp\n"); + ftpsrv::Exit(); + } + if (App::GetNxlinkEnable()) { log_write("closing nxlink\n"); nxlinkExit(); diff --git a/sphaira/source/download.cpp b/sphaira/source/download.cpp index 4af0c72..e677989 100644 --- a/sphaira/source/download.cpp +++ b/sphaira/source/download.cpp @@ -298,7 +298,7 @@ auto DownloadInternal(CURL* curl, DataStruct& chunk, ProgressCallback pcallback, fs::CreateDirectoryRecursivelyWithPath(&chunk.fs, tmp_buf); - if (auto rc = fsFsCreateFile(&chunk.fs, tmp_buf, 0, 0); R_FAILED(rc) && rc != FsError_ResultPathAlreadyExists) { + if (auto rc = fsFsCreateFile(&chunk.fs, tmp_buf, 0, 0); R_FAILED(rc) && rc != FsError_PathAlreadyExists) { log_write("failed to create file: %s\n", tmp_buf); return false; } diff --git a/sphaira/source/fs.cpp b/sphaira/source/fs.cpp index 49a62fe..8c2cd47 100644 --- a/sphaira/source/fs.cpp +++ b/sphaira/source/fs.cpp @@ -134,7 +134,7 @@ Result CreateDirectoryRecursively(FsFileSystem* fs, const FsPath& _path, bool ig rc = CreateDirectory(path, ignore_read_only); } - if (R_FAILED(rc) && rc != FsError_ResultPathAlreadyExists) { + if (R_FAILED(rc) && rc != FsError_PathAlreadyExists) { log_write("failed to create folder: %s\n", path); return rc; } @@ -166,7 +166,7 @@ Result CreateDirectoryRecursivelyWithPath(FsFileSystem* fs, const FsPath& _path, rc = CreateDirectory(path, ignore_read_only); } - if (R_FAILED(rc) && rc != FsError_ResultPathAlreadyExists) { + if (R_FAILED(rc) && rc != FsError_PathAlreadyExists) { log_write("failed to create folder recursively: %s\n", path); return rc; } @@ -251,7 +251,7 @@ Result write_entire_file(FsFileSystem* _fs, const FsPath& path, const std::vecto FsNative fs{_fs, false}; R_TRY(fs.GetFsOpenResult()); - if (auto rc = fs.CreateFile(path, in.size(), 0, ignore_read_only); R_FAILED(rc) && rc != FsError_ResultPathAlreadyExists) { + if (auto rc = fs.CreateFile(path, in.size(), 0, ignore_read_only); R_FAILED(rc) && rc != FsError_PathAlreadyExists) { return rc; } diff --git a/sphaira/source/ftpsrv_helper.cpp b/sphaira/source/ftpsrv_helper.cpp new file mode 100644 index 0000000..ef03698 --- /dev/null +++ b/sphaira/source/ftpsrv_helper.cpp @@ -0,0 +1,335 @@ +#include "ftpsrv_helper.hpp" +#include +#include +#include "app.hpp" +#include "fs.hpp" +#include "log.hpp" + +#include +#include +#include +#include +#include + +namespace { + +FtpSrvConfig g_ftpsrv_config = {0}; +volatile bool g_should_exit = false; +bool g_is_running{false}; +Thread g_thread; +std::mutex g_mutex{}; +FsFileSystem* g_fs; + +void ftp_log_callback(enum FTP_API_LOG_TYPE type, const char* msg) { + sphaira::App::NotifyFlashLed(); +} + +void ftp_progress_callback(void) { + sphaira::App::NotifyFlashLed(); +} + +int vfs_fs_set_errno(Result rc) { + switch (rc) { + case FsError_TargetLocked: errno = EBUSY; break; + case FsError_PathNotFound: errno = ENOENT; break; + case FsError_PathAlreadyExists: errno = EEXIST; break; + case FsError_UsableSpaceNotEnoughMmcCalibration: errno = ENOSPC; break; + case FsError_UsableSpaceNotEnoughMmcSafe: errno = ENOSPC; break; + case FsError_UsableSpaceNotEnoughMmcUser: errno = ENOSPC; break; + case FsError_UsableSpaceNotEnoughMmcSystem: errno = ENOSPC; break; + case FsError_UsableSpaceNotEnoughSdCard: errno = ENOSPC; break; + case FsError_OutOfRange: errno = ESPIPE; break; + case FsError_TooLongPath: errno = ENAMETOOLONG; break; + case FsError_UnsupportedWriteForReadOnlyFileSystem: errno = EROFS; break; + default: errno = EIO; break; + } + return -1; +} + +Result flush_buffered_write(struct FtpVfsFile* f) { + Result rc; + if (R_SUCCEEDED(rc = fsFileSetSize(&f->fd, f->off + f->buf_off))) { + rc = fsFileWrite(&f->fd, f->off, f->buf, f->buf_off, FsWriteOption_None); + } + return rc; +} + +void loop(void* arg) { + while (!g_should_exit) { + ftpsrv_init(&g_ftpsrv_config); + while (!g_should_exit) { + if (ftpsrv_loop(100) != FTP_API_LOOP_ERROR_OK) { + svcSleepThread(1e+6); + break; + } + } + ftpsrv_exit(); + } +} + +} // namespace + +namespace sphaira::ftpsrv { + +bool Init() { + std::scoped_lock lock{g_mutex}; + if (g_is_running) { + return false; + } + + g_fs = fsdevGetDeviceFileSystem("sdmc"); + + g_ftpsrv_config.log_callback = ftp_log_callback; + g_ftpsrv_config.progress_callback = ftp_progress_callback; + g_ftpsrv_config.anon = true; + g_ftpsrv_config.timeout = 15; + g_ftpsrv_config.port = 5000; + + Result rc; + if (R_FAILED(rc = threadCreate(&g_thread, loop, nullptr, nullptr, 1024*64, 0x2C, 2))) { + log_write("failed to create nxlink thread: 0x%X\n", rc); + return false; + } + + if (R_FAILED(rc = threadStart(&g_thread))) { + log_write("failed to start nxlink thread: 0x%X\n", rc); + threadClose(&g_thread); + return false; + } + + return g_is_running = true; +} + +void Exit() { + std::scoped_lock lock{g_mutex}; + if (g_is_running) { + g_is_running = false; + } + g_should_exit = true; + threadWaitForExit(&g_thread); + threadClose(&g_thread); +} + +} // namespace sphaira::ftpsrv + +extern "C" { + +#define VFS_NX_BUFFER_IO 1 + +int ftp_vfs_open(struct FtpVfsFile* f, const char* path, enum FtpVfsOpenMode mode) { + u32 open_mode; + if (mode == FtpVfsOpenMode_READ) { + open_mode = FsOpenMode_Read; + f->is_write = false; + } else { + fsFsCreateFile(g_fs, path, 0, 0); + open_mode = FsOpenMode_Write | FsOpenMode_Append; + #if !VFS_NX_BUFFER_IO + open_mode |= FsOpenMode_Append; + #endif + f->is_write = true; + } + + Result rc; + if (R_FAILED(rc = fsFsOpenFile(g_fs, path, open_mode, &f->fd))) { + return vfs_fs_set_errno(rc); + } + + f->off = f->buf_off = f->buf_size = 0; + + if (mode == FtpVfsOpenMode_WRITE) { + if (R_FAILED(rc = fsFileSetSize(&f->fd, 0))) { + goto fail_close; + } + } else if (mode == FtpVfsOpenMode_APPEND) { + if (R_FAILED(rc = fsFileGetSize(&f->fd, &f->off))) { + goto fail_close; + } + } + + f->is_valid = true; + return 0; + +fail_close: + fsFileClose(&f->fd); + return vfs_fs_set_errno(rc); +} + +int ftp_vfs_read(struct FtpVfsFile* f, void* buf, size_t size) { + Result rc; + + #if VFS_NX_BUFFER_IO + if (f->buf_off == f->buf_size) { + u64 bytes_read; + if (R_FAILED(rc = fsFileRead(&f->fd, f->off, f->buf, sizeof(f->buf), FsReadOption_None, &bytes_read))) { + return vfs_fs_set_errno(rc); + } + + f->buf_off = 0; + f->buf_size = bytes_read; + } + + if (!f->buf_size) { + return 0; + } + + size = size < f->buf_size - f->buf_off ? size : f->buf_size - f->buf_off; + memcpy(buf, f->buf + f->buf_off, size); + f->off += size; + f->buf_off += size; + return size; +#else + u64 bytes_read; + if (R_FAILED(rc = fsFileRead(&f->fd, f->off, buf, size, FsReadOption_None, &bytes_read))) { + return vfs_fs_set_errno(rc); + } + f->off += bytes_read; + return bytes_read; +#endif +} + +int ftp_vfs_write(struct FtpVfsFile* f, const void* buf, size_t size) { + Result rc; + +#if VFS_NX_BUFFER_IO + const size_t ret = size; + while (size) { + if (f->buf_off + size > sizeof(f->buf)) { + const u64 sz = sizeof(f->buf) - f->buf_off; + memcpy(f->buf + f->buf_off, buf, sz); + f->buf_off += sz; + + if (R_FAILED(rc = flush_buffered_write(f))) { + return vfs_fs_set_errno(rc); + } + + buf += sz; + size -= sz; + f->off += f->buf_off; + f->buf_off = 0; + } else { + memcpy(f->buf + f->buf_off, buf, size); + f->buf_off += size; + size = 0; + } + } + + return ret; +#else + if (R_FAILED(rc = fsFileWrite(&f->fd, f->off, buf, size, FsWriteOption_None))) { + return vfs_fs_set_errno(rc); + } + f->off += size; + return size; + const size_t ret = size; +#endif +} + +// buf and size is the amount of data sent. +int ftp_vfs_seek(struct FtpVfsFile* f, const void* buf, size_t size, size_t off) { +#if VFS_NX_BUFFER_IO + if (!f->is_write) { + f->buf_off -= f->off - off; + } +#endif + f->off = off; + return 0; +} + +int ftp_vfs_close(struct FtpVfsFile* f) { + if (!ftp_vfs_isfile_open(f)) { + return -1; + } + + if (f->is_write && f->buf_off) { + flush_buffered_write(f); + } + + fsFileClose(&f->fd); + f->is_valid = false; + return 0; +} + +int ftp_vfs_isfile_open(struct FtpVfsFile* f) { + return f->is_valid; +} + +int ftp_vfs_opendir(struct FtpVfsDir* f, const char* path) { + Result rc; + if (R_FAILED(rc = fsFsOpenDirectory(g_fs, path, FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles | FsDirOpenMode_NoFileSize, &f->dir))) { + return vfs_fs_set_errno(rc); + } + f->is_valid = true; + return 0; +} + +const char* ftp_vfs_readdir(struct FtpVfsDir* f, struct FtpVfsDirEntry* entry) { + Result rc; + s64 total_entries; + if (R_FAILED(rc = fsDirRead(&f->dir, &total_entries, 1, &entry->buf))) { + vfs_fs_set_errno(rc); + return NULL; + } + + if (total_entries <= 0) { + return NULL; + } + + return entry->buf.name; +} + +int ftp_vfs_dirlstat(struct FtpVfsDir* f, const struct FtpVfsDirEntry* entry, const char* path, struct stat* st) { + return lstat(path, st); +} + +int ftp_vfs_closedir(struct FtpVfsDir* f) { + if (!ftp_vfs_isdir_open(f)) { + return -1; + } + + fsDirClose(&f->dir); + f->is_valid = false; + return 0; +} + +int ftp_vfs_isdir_open(struct FtpVfsDir* f) { + return f->is_valid; +} + +int ftp_vfs_stat(const char* path, struct stat* st) { + return stat(path, st); +} + +int ftp_vfs_lstat(const char* path, struct stat* st) { + return lstat(path, st); +} + +int ftp_vfs_mkdir(const char* path) { + return mkdir(path, 0777); +} + +int ftp_vfs_unlink(const char* path) { + return unlink(path); +} + +int ftp_vfs_rmdir(const char* path) { + return rmdir(path); +} + +int ftp_vfs_rename(const char* src, const char* dst) { + return rename(src, dst); +} + +int ftp_vfs_readlink(const char* path, char* buf, size_t buflen) { + return -1; +} + +const char* ftp_vfs_getpwuid(const struct stat* st) { + return "unknown"; +} + +const char* ftp_vfs_getgrgid(const struct stat* st) { + return "unknown"; +} + +} // extern "C" diff --git a/sphaira/source/main.cpp b/sphaira/source/main.cpp index 1a5c72e..8bc833a 100644 --- a/sphaira/source/main.cpp +++ b/sphaira/source/main.cpp @@ -61,6 +61,8 @@ void userAppInit(void) { diagAbortWithResult(rc); if (R_FAILED(rc = setInitialize())) diagAbortWithResult(rc); + if (R_FAILED(rc = hidsysInitialize())) + diagAbortWithResult(rc); log_nxlink_init(); } @@ -68,6 +70,7 @@ void userAppInit(void) { void userAppExit(void) { log_nxlink_exit(); + hidsysExit(); setExit(); accountExit(); nifmExit(); diff --git a/sphaira/source/nxlink.cpp b/sphaira/source/nxlink.cpp index 9ca7a8a..40099d4 100644 --- a/sphaira/source/nxlink.cpp +++ b/sphaira/source/nxlink.cpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace { @@ -114,7 +115,7 @@ auto recvall(int sock, void* buf, int size) -> bool { if (errno != EWOULDBLOCK && errno != EAGAIN) { return false; } - svcSleepThread(YieldType_WithoutCoreMigration); + svcSleepThread(1e+6); } else { got += len; left -= len; @@ -132,7 +133,7 @@ auto sendall(Socket sock, const void* buf, int size) -> bool { if (errno != EWOULDBLOCK && errno != EAGAIN) { return false; } - svcSleepThread(YieldType_WithoutCoreMigration); + svcSleepThread(1e+6); } sent += len; left -= len; @@ -171,28 +172,6 @@ auto get_file_data(Socket sock, int max) -> std::vector { return buf; } -#if 0 -auto create_directories(fs::FsNative& fs, const std::string& path) -> Result { - std::size_t pos{}; - - // no sane person creates 20 directories deep - for (int i = 0; i < 20; i++) { - pos = path.find_first_of("/", pos); - if (pos == std::string::npos) { - break; - } - pos++; - - fs::FsPath safe_buf; - std::strcpy(safe_buf, path.substr(0, pos).c_str()); - const auto rc = fs.CreateDirectory(safe_buf); - R_UNLESS(R_SUCCEEDED(rc) || rc == FsError_ResultPathAlreadyExists, rc); - } - - R_SUCCEED(); -} -#endif - void loop(void* args) { log_write("in nxlink thread func\n"); const sockaddr_in servaddr{ @@ -266,21 +245,36 @@ void loop(void* args) { sockaddr_in sa_remote{}; - while (!g_quit) { - svcSleepThread(1e+8); + pollfd pfds[2]; + pfds[0].fd = sock; + pfds[0].events = POLLIN; + pfds[1].fd = sock_udp; + pfds[1].events = POLLIN; - if (poll_network_change()) { + while (!g_quit) { + auto poll_rc = poll(pfds, std::size(pfds), 1000/60); + if (poll_rc < 0) { + break; + } else if (poll_rc == 0) { + continue; + } else if ((pfds[0].revents & (POLLERR|POLLHUP|POLLNVAL)) || (pfds[1].revents & (POLLERR|POLLHUP|POLLNVAL))) { break; } - char recvbuf[256]; - socklen_t from_len = sizeof(sa_remote); - const auto udp_len = recvfrom(sock_udp, recvbuf, sizeof(recvbuf), 0, (sockaddr*)&sa_remote, &from_len); - if (udp_len > 0 && !std::strncmp(recvbuf, UDP_MAGIC_SERVER, std::strlen(UDP_MAGIC_SERVER))) { - // log_write("got udp len: %d - %.*s\n", udp_len, udp_len, recvbuf); - sa_remote.sin_family = AF_INET; - sa_remote.sin_port = htons(NXLINK_CLIENT_PORT); - sendto(sock_udp, UDP_MAGIC_CLIENT, std::strlen(UDP_MAGIC_CLIENT), 0, (sockaddr*)&sa_remote, sizeof(sa_remote)); + if (pfds[1].revents & POLLIN) { + char recvbuf[6]; + socklen_t from_len = sizeof(sa_remote); + auto udp_len = recvfrom(sock_udp, recvbuf, sizeof(recvbuf), 0, (sockaddr*)&sa_remote, &from_len); + if (udp_len == sizeof(recvbuf) && !std::strncmp(recvbuf, UDP_MAGIC_SERVER, std::strlen(UDP_MAGIC_SERVER))) { + // log_write("got udp len: %d - %.*s\n", udp_len, udp_len, recvbuf); + sa_remote.sin_family = AF_INET; + sa_remote.sin_port = htons(NXLINK_CLIENT_PORT); + udp_len = sendto(sock_udp, UDP_MAGIC_CLIENT, std::strlen(UDP_MAGIC_CLIENT), 0, (const sockaddr*)&sa_remote, sizeof(sa_remote)); + if (udp_len != std::strlen(UDP_MAGIC_CLIENT)) { + log_write("nxlink failed to send udp packet\n"); + continue; + } + } } socklen_t accept_len = sizeof(sa_remote); @@ -316,8 +310,9 @@ void loop(void* args) { } // check that we have enough space + fs::FsNativeSd fs; s64 sd_storage_space_free; - if (R_FAILED(fs::FsNativeSd().GetFreeSpace("/", &sd_storage_space_free)) || filesize >= sd_storage_space_free) { + if (R_FAILED(fs.GetFreeSpace("/", &sd_storage_space_free)) || filesize >= sd_storage_space_free) { sendall(connfd, &ERR_SPACE, sizeof(ERR_SPACE)); continue; } @@ -345,16 +340,6 @@ void loop(void* args) { path = name; } - // std::strcat(temp_path, "~"); - - fs::FsNativeSd fs; - - if (R_FAILED(rc = fs.GetFsOpenResult())) { - sendall(connfd, &ERR_FILE, sizeof(ERR_FILE)); - log_write("failed to open fs: 0x%X\n", socketGetLastResult()); - continue; - } - // if (R_FAILED(rc = create_directories(fs, path))) { if (R_FAILED(rc = fs.CreateDirectoryRecursivelyWithPath(path))) { sendall(connfd, &ERR_FILE, sizeof(ERR_FILE)); @@ -364,7 +349,7 @@ void loop(void* args) { // this is the path we will write to const auto temp_path = path + "~"; - if (R_FAILED(rc = fs.CreateFile(temp_path, file_data.size(), 0)) && rc != FsError_ResultPathAlreadyExists) { + if (R_FAILED(rc = fs.CreateFile(temp_path, file_data.size(), 0)) && rc != FsError_PathAlreadyExists) { sendall(connfd, &ERR_FILE, sizeof(ERR_FILE)); log_write("failed to create file: %X\n", rc); continue; @@ -408,7 +393,7 @@ void loop(void* args) { } } - if (R_FAILED(rc = fs.DeleteFile(path)) && rc != FsError_ResultPathNotFound) { + if (R_FAILED(rc = fs.DeleteFile(path)) && rc != FsError_PathNotFound) { log_write("failed to delete %X\n", rc); continue; } @@ -473,13 +458,14 @@ bool nxlinkInitialize(NxlinkCallback callback) { g_callback = callback; g_quit = false; - if (R_FAILED(threadCreate(&g_thread, loop, nullptr, nullptr, 1024*64, 0x2C, 2))) { - log_write("failed to create nxlink thread: 0x%X\n", socketGetLastResult()); + Result rc; + if (R_FAILED(rc = threadCreate(&g_thread, loop, nullptr, nullptr, 1024*64, 0x2C, 2))) { + log_write("failed to create nxlink thread: 0x%X\n", rc); return false; } - if (R_FAILED(threadStart(&g_thread))) { - log_write("failed to start nxlink thread: 0x%X\n", socketGetLastResult()); + if (R_FAILED(rc = threadStart(&g_thread))) { + log_write("failed to start nxlink thread: 0x%X\n", rc); threadClose(&g_thread); return false; } diff --git a/sphaira/source/ui/menus/appstore.cpp b/sphaira/source/ui/menus/appstore.cpp index 5b15f55..c92fe72 100644 --- a/sphaira/source/ui/menus/appstore.cpp +++ b/sphaira/source/ui/menus/appstore.cpp @@ -548,7 +548,7 @@ auto InstallApp(ProgressBox* pbox, const Entry& entry) -> bool { fs.CreateDirectoryRecursivelyWithPath(output, true); Result rc; - if (R_FAILED(rc = fs.CreateFile(output, info.uncompressed_size, 0, true)) && rc != FsError_ResultPathAlreadyExists) { + if (R_FAILED(rc = fs.CreateFile(output, info.uncompressed_size, 0, true)) && rc != FsError_PathAlreadyExists) { log_write("failed to create file: %s 0x%04X\n", output, rc); return false; } diff --git a/sphaira/source/ui/menus/filebrowser.cpp b/sphaira/source/ui/menus/filebrowser.cpp index 9417b8d..b7e93c8 100644 --- a/sphaira/source/ui/menus/filebrowser.cpp +++ b/sphaira/source/ui/menus/filebrowser.cpp @@ -30,7 +30,8 @@ #include #include #include -#include +// #include +#include namespace sphaira::ui::menu::filebrowser { namespace { @@ -61,42 +62,47 @@ constexpr std::string_view IMAGE_EXTENSIONS[] = { "png", "jpg", "jpeg", "bmp", "gif", }; -using PathPair = std::pair; -constexpr PathPair PATHS[]{ - PathPair{"3do", "The 3DO Company - 3DO"}, - PathPair{"atari800", "Atari - 8-bit"}, - PathPair{"atari2600", "Atari - 2600"}, - PathPair{"atari5200", "Atari - 5200"}, - PathPair{"atari7800", "Atari - 7800"}, - PathPair{"atarilynx", "Atari - Lynx"}, - PathPair{"atarijaguar", "Atari - Jaguar"}, - PathPair{"atarijaguarcd", ""}, - PathPair{"n3ds", "Nintendo - Nintendo 3DS"}, - PathPair{"n64", "Nintendo - Nintendo 64"}, - PathPair{"nds", "Nintendo - Nintendo DS"}, - PathPair{"fds", "Nintendo - Famicom Disk System"}, - PathPair{"nes", "Nintendo - Nintendo Entertainment System"}, - PathPair{"pokemini", "Nintendo - Pokemon Mini"}, - PathPair{"gb", "Nintendo - Game Boy"}, - PathPair{"gba", "Nintendo - Game Boy Advance"}, - PathPair{"gbc", "Nintendo - Game Boy Color"}, - PathPair{"virtualboy", "Nintendo - Virtual Boy"}, - PathPair{"gameandwatch", ""}, - PathPair{"sega32x", "Sega - 32X"}, - PathPair{"segacd", "Sega - Mega CD - Sega CD"}, - PathPair{"dreamcast", "Sega - Dreamcast"}, - PathPair{"gamegear", "Sega - Game Gear"}, - PathPair{"genesis", "Sega - Mega Drive - Genesis"}, - PathPair{"mastersystem", "Sega - Master System - Mark III"}, - PathPair{"megadrive", "Sega - Mega Drive - Genesis"}, - PathPair{"saturn", "Sega - Saturn"}, - PathPair{"sg-1000", "Sega - SG-1000"}, - PathPair{"psx", "Sony - PlayStation"}, - PathPair{"psp", "Sony - PlayStation Portable"}, - PathPair{"snes", "Nintendo - Super Nintendo Entertainment System"}, - PathPair{"pico8", "Sega - PICO"}, - PathPair{"wonderswan", "Bandai - WonderSwan"}, - PathPair{"wonderswancolor", "Bandai - WonderSwan Color"}, +struct RomDatabaseEntry { + std::string_view folder; + std::string_view database; +}; + +// using PathPair = std::pair; +constexpr RomDatabaseEntry PATHS[]{ + { "3do", "The 3DO Company - 3DO"}, + { "atari800", "Atari - 8-bit"}, + { "atari2600", "Atari - 2600"}, + { "atari5200", "Atari - 5200"}, + { "atari7800", "Atari - 7800"}, + { "atarilynx", "Atari - Lynx"}, + { "atarijaguar", "Atari - Jaguar"}, + { "atarijaguarcd", ""}, + { "n3ds", "Nintendo - Nintendo 3DS"}, + { "n64", "Nintendo - Nintendo 64"}, + { "nds", "Nintendo - Nintendo DS"}, + { "fds", "Nintendo - Famicom Disk System"}, + { "nes", "Nintendo - Nintendo Entertainment System"}, + { "pokemini", "Nintendo - Pokemon Mini"}, + { "gb", "Nintendo - Game Boy"}, + { "gba", "Nintendo - Game Boy Advance"}, + { "gbc", "Nintendo - Game Boy Color"}, + { "virtualboy", "Nintendo - Virtual Boy"}, + { "gameandwatch", ""}, + { "sega32x", "Sega - 32X"}, + { "segacd", "Sega - Mega CD - Sega CD"}, + { "dreamcast", "Sega - Dreamcast"}, + { "gamegear", "Sega - Game Gear"}, + { "genesis", "Sega - Mega Drive - Genesis"}, + { "mastersystem", "Sega - Master System - Mark III"}, + { "megadrive", "Sega - Mega Drive - Genesis"}, + { "saturn", "Sega - Saturn"}, + { "sg-1000", "Sega - SG-1000"}, + { "psx", "Sony - PlayStation"}, + { "psp", "Sony - PlayStation Portable"}, + { "snes", "Nintendo - Super Nintendo Entertainment System"}, + { "pico8", "Sega - PICO"}, + { "wonderswan", "Bandai - WonderSwan"}, + { "wonderswancolor", "Bandai - WonderSwan Color"}, }; constexpr fs::FsPath DAYBREAK_PATH{"/switch/daybreak.nro"}; @@ -127,47 +133,49 @@ auto IsExtension(std::string_view ext1, std::string_view ext2) -> bool { // tries to find database path using folder name // names are taken from retropie // retroarch database names can also be used -auto GetRomDatabaseFromPath(const std::string& path) -> std::string { +auto GetRomDatabaseFromPath(std::string_view path) -> int { if (path.length() <= 1) { - return {}; + return -1; } // this won't fail :) const auto db_name = path.substr(path.find_last_of('/') + 1); - log_write("new path: %s\n", db_name.c_str()); + // log_write("new path: %s\n", db_name.c_str()); - for (auto& [folder_name, database_name] : PATHS) { + for (int i = 0; i < std::size(PATHS); i++) { + auto& p = PATHS[i]; if (( - folder_name.length() == db_name.length() && !strncasecmp(folder_name.data(), db_name.data(), folder_name.length())) || - (database_name.length() == db_name.length() && !strncasecmp(database_name.data(), db_name.data(), database_name.length()))) { - log_write("found it :) %s\n", std::string{database_name.data(), database_name.length()}.c_str()); - return std::string{database_name.data(), database_name.length()}; + p.folder.length() == db_name.length() && !strncasecmp(p.folder.data(), db_name.data(), p.folder.length())) || + (p.database.length() == db_name.length() && !strncasecmp(p.database.data(), db_name.data(), p.database.length()))) { + log_write("found it :) %.*s\n", p.database.length(), p.database.data()); + return i; } } // if we failed, try again but with the folder about // "/roms/psx/scooby-doo/scooby-doo.bin", this will check psx const auto last_off = path.substr(0, path.find_last_of('/')); - if (const auto off = last_off.find_last_of('/'); off != std::string::npos) { + if (const auto off = last_off.find_last_of('/'); off != std::string_view::npos) { const auto db_name2 = last_off.substr(off + 1); - printf("got db: %s\n", db_name2.c_str()); - for (auto& [folder_name, database_name] : PATHS) { + // printf("got db: %s\n", db_name2.c_str()); + for (int i = 0; i < std::size(PATHS); i++) { + auto& p = PATHS[i]; if (( - folder_name.length() == db_name2.length() && !strcasecmp(folder_name.data(), db_name2.data())) || - (database_name.length() == db_name2.length() && !strcasecmp(database_name.data(), db_name2.data()))) { - log_write("found it :) %s\n", std::string{database_name.data(), database_name.length()}.c_str()); - return std::string{database_name.data(), database_name.length()}; + p.folder.length() == db_name2.length() && !strcasecmp(p.folder.data(), db_name2.data())) || + (p.database.length() == db_name2.length() && !strcasecmp(p.database.data(), db_name2.data()))) { + log_write("found it :) %.*s\n", p.database.length(), p.database.data()); + return i; } } } - return {}; + return -1; } // -auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension, std::string database, const NroEntry& nro) { +auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension, int db_idx, const NroEntry& nro) { // if no db entries, use nro icon - if (database.empty()) { + if (db_idx < 0) { log_write("using nro image\n"); return nro_get_icon(nro.path, nro.icon_size, nro.icon_offset); } @@ -189,7 +197,7 @@ auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension, #define RA_THUMBNAIL_PATH "/retroarch/thumbnails/" #define RA_BOXART_EXT ".png" - const std::string system_name = database;//GetDatabaseFromExt(database, extension); + const auto system_name = std::string{PATHS[db_idx].database.data(), PATHS[db_idx].database.length()};//GetDatabaseFromExt(database, extension); auto system_name_gh = system_name + "/master"; for (auto& c : system_name_gh) { if (c == ' ') { @@ -601,7 +609,7 @@ Menu::Menu(const std::vector& nro_entries) : MenuBase{"FileBrowser"_i1 } }, true)); - if (m_entries_current.size()) { + if (m_entries_current.size() && !m_selected_count && GetEntry().IsFile() && GetEntry().file_size < 1024*64) { options->Add(std::make_shared("View as text (unfinished)"_i18n, [this](){ App::Push(std::make_shared(GetNewPathCurrent())); }, true)); @@ -864,7 +872,7 @@ void Menu::InstallForwarder() { log_write("got filename2: %s\n\n", file_name.c_str()); } - const auto database = GetRomDatabaseFromPath(m_path); + const auto db_idx = GetRomDatabaseFromPath(m_path); OwoConfig config{}; config.nro_path = assoc.path.toString(); @@ -872,7 +880,7 @@ void Menu::InstallForwarder() { config.name = nro.nacp.lang[0].name + std::string{" | "} + file_name; // config.name = file_name; config.nacp = nro.nacp; - config.icon = GetRomIcon(pbox, file_name, extension, database, nro); + config.icon = GetRomIcon(pbox, file_name, extension, db_idx, nro); return R_SUCCEEDED(App::Install(pbox, config)); })); @@ -966,24 +974,24 @@ auto Menu::Scan(const fs::FsPath& new_path, bool is_walk_up) -> Result { auto Menu::FindFileAssocFor() -> std::vector { // only support roms in correctly named folders, sorry! - const auto database_name = GetRomDatabaseFromPath(m_path); + const auto db_idx = GetRomDatabaseFromPath(m_path); const auto& entry = GetEntry(); const auto extension = entry.internal_extension.empty() ? entry.extension : entry.internal_extension; if (extension.empty()) { - log_write("failed to get extension for db: %s path: %s\n", database_name.c_str(), m_path); + // log_write("failed to get extension for db: %s path: %s\n", database_entry.c_str(), m_path); return {}; } - log_write("got extension for db: %s path: %s\n", database_name.c_str(), m_path); + // log_write("got extension for db: %s path: %s\n", database_entry.c_str(), m_path); std::vector out_entries; - if (!database_name.empty()) { + if (db_idx >= 0) { // if database isn't empty, then we are in a valid folder // search for an entry that matches the db and ext for (const auto& assoc : m_assoc_entries) { for (const auto& assoc_db : assoc.database) { - if (assoc_db == database_name) { + if (assoc_db == PATHS[db_idx].folder || assoc_db == PATHS[db_idx].database) { for (const auto& assoc_ext : assoc.ext) { if (assoc_ext == extension) { log_write("found ext: %s assoc_ext: %s assoc.ext: %s\n", assoc.path, assoc_ext.c_str(), extension.c_str()); @@ -1021,76 +1029,60 @@ void Menu::LoadAssocEntriesPath(const fs::FsPath& path) { return; } ON_SCOPE_EXIT(closedir(dir)); + fs::FsNativeSd fs; while (auto d = readdir(dir)) { if (d->d_name[0] == '.') { continue; } - // const std::string name = d->d_name; const auto ext = std::strrchr(d->d_name, '.'); - if (!ext) { - continue; - } - if (strcasecmp(ext, ".ini")) { + if (!ext || strcasecmp(ext, ".ini")) { continue; } const auto full_path = GetNewPath(path, d->d_name); - - fs::FsPath buf{}; - const auto ext_len = 1 + ini_gets("config", "supported_extensions", "", buf, sizeof(buf) - 1, full_path); - if (ext_len <= 1) { - continue; - } - - // log_write("reading ini: %s\n", name.c_str()); - FileAssocEntry assoc{}; - for (int i = 0; i < ext_len; i++) { - for (int j = i; j < ext_len; j++) { - if (buf[j] == '|' || buf[j] == '\0') { - assoc.ext.emplace_back(buf + i, j - i); - i += j - i; - break; + ini_browse([](const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, void *UserData) { + auto assoc = static_cast(UserData); + if (!strcmp(Key, "path")) { + assoc->path = Value; + } else if (!strcmp(Key, "supported_extensions")) { + for (int i = 0; Value[i]; i++) { + for (int j = i; ; j++) { + if (Value[j] == '|' || Value[j] == '\0') { + assoc->ext.emplace_back(Value + i, j - i); + i += j - i; + break; + } + } + } + } else if (!strcmp(Key, "database")) { + for (int i = 0; Value[i]; i++) { + for (int j = i; ; j++) { + if (Value[j] == '|' || Value[j] == '\0') { + assoc->database.emplace_back(Value + i, j - i); + i += j - i; + break; + } + } } } - } + return 1; + }, &assoc, full_path); if (assoc.ext.empty()) { continue; } - // assoc.name = name.substr(0, name.find_last_of('.')); assoc.name.assign(d->d_name, ext - d->d_name); - const auto path_len = ini_gets("config", "path", "", buf, sizeof(buf) - 1, full_path); - if (path_len > 0) { - assoc.path = buf; - } - - const auto database_len = 1 + ini_gets("config", "database", "", buf, sizeof(buf) - 1, full_path); - if (database_len > 1) { - for (int i = 0; i < database_len; i++) { - for (int j = i; j < database_len; j++) { - if (buf[j] == '|' || buf[j] == '\0') { - assoc.database.emplace_back(buf + i, j - i); - i += j - i; - break; - } - } - } - } - - bool file_exists{}; - // if path isn't empty, check if the file exists + bool file_exists{}; if (!assoc.path.empty()) { - file_exists = fs::FsNativeSd().FileExists(assoc.path); + file_exists = fs.FileExists(assoc.path); } else { - log_write("\tpath is empty\n"); - #if 1 const auto nro_name = assoc.name + ".nro"; for (const auto& nro : m_nro_entries) { const auto len = std::strlen(nro.path); @@ -1103,7 +1095,6 @@ void Menu::LoadAssocEntriesPath(const fs::FsPath& path) { break; } } - #endif } // after all of that, the file doesn't exist :( @@ -1135,32 +1126,6 @@ void Menu::LoadAssocEntries() { LoadAssocEntriesPath("/config/sphaira/assoc/"); } -#if 0 -void Menu::OnIndexChange() { - if (!GetEntry().checked_internal_extension && GetEntry().extension == "zip") { - GetEntry().checked_internal_extension = true; - if (auto zfile = unzOpen64(GetNewPathCurrent())) { - ON_SCOPE_EXIT(unzClose(zfile)); - unz_global_info gi{}; - // only check first entry (i think RA does the same) - if (UNZ_OK == unzGetGlobalInfo(zfile, &gi) && gi.number_entry >= 1) { - fs::FsPath filename_inzip{}; - unz_file_info64 file_info{}; - if (UNZ_OK == unzOpenCurrentFile(zfile)) { - ON_SCOPE_EXIT(unzCloseCurrentFile(zfile)); - if (UNZ_OK == unzGetCurrentFileInfo64(zfile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0)) { - if (auto ext = std::strrchr(filename_inzip, '.')) { - GetEntry().internal_name = filename_inzip.toString(); - GetEntry().internal_extension = ext+1; - } - } - } - } - } - } -} -#endif - void Menu::Sort() { // returns true if lhs should be before rhs const auto sort = m_sort.Get(); diff --git a/sphaira/source/ui/menus/main_menu.cpp b/sphaira/source/ui/menus/main_menu.cpp index 6823738..2239571 100644 --- a/sphaira/source/ui/menus/main_menu.cpp +++ b/sphaira/source/ui/menus/main_menu.cpp @@ -91,13 +91,13 @@ auto InstallUpdate(ProgressBox* pbox, const std::string url, const std::string v Result rc; if (file_path[strlen(file_path) -1] == '/') { - if (R_FAILED(rc = fs.CreateDirectoryRecursively(file_path)) && rc != FsError_ResultPathAlreadyExists) { + if (R_FAILED(rc = fs.CreateDirectoryRecursively(file_path)) && rc != FsError_PathAlreadyExists) { log_write("failed to create folder: %s 0x%04X\n", file_path, rc); return false; } } else { Result rc; - if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0)) && rc != FsError_ResultPathAlreadyExists) { + if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0)) && rc != FsError_PathAlreadyExists) { log_write("failed to create file: %s 0x%04X\n", file_path, rc); return false; } @@ -249,6 +249,14 @@ MainMenu::MainMenu() { auto options = std::make_shared("Network Options"_i18n, Sidebar::Side::LEFT); ON_SCOPE_EXIT(App::Push(options)); + options->Add(std::make_shared("Ftp"_i18n, App::GetFtpEnable(), [this](bool& enable){ + App::SetFtpEnable(enable); + }, "Enabled"_i18n, "Disabled"_i18n)); + + options->Add(std::make_shared("Mtp"_i18n, App::GetMtpEnable(), [this](bool& enable){ + App::SetMtpEnable(enable); + }, "Enabled"_i18n, "Disabled"_i18n)); + options->Add(std::make_shared("Nxlink"_i18n, App::GetNxlinkEnable(), [this](bool& enable){ App::SetNxlinkEnable(enable); }, "Enabled"_i18n, "Disabled"_i18n)); diff --git a/sphaira/source/ui/menus/themezer.cpp b/sphaira/source/ui/menus/themezer.cpp index a5abfae..5c51f3b 100644 --- a/sphaira/source/ui/menus/themezer.cpp +++ b/sphaira/source/ui/menus/themezer.cpp @@ -369,7 +369,7 @@ auto InstallTheme(ProgressBox* pbox, const PackListEntry& entry) -> bool { const auto file_path = fs::AppendPath(dir_path, name); Result rc; - if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0)) && rc != FsError_ResultPathAlreadyExists) { + if (R_FAILED(rc = fs.CreateFile(file_path, info.uncompressed_size, 0)) && rc != FsError_PathAlreadyExists) { log_write("failed to create file: %s 0x%04X\n", file_path, rc); return false; } diff --git a/sphaira/source/ui/notification.cpp b/sphaira/source/ui/notification.cpp index 567cf6c..a0b6b20 100644 --- a/sphaira/source/ui/notification.cpp +++ b/sphaira/source/ui/notification.cpp @@ -135,6 +135,9 @@ auto NotifMananger::Clear(NotifEntry::Side side) -> void { } auto NotifMananger::Clear() -> void { + mutexLock(&m_mutex); + ON_SCOPE_EXIT(mutexUnlock(&m_mutex)); + m_entries_left.clear(); m_entries_right.clear(); } From 7c273f30f38222c48dad555dee63ceff856f9999 Mon Sep 17 00:00:00 2001 From: glitched_nx <102478555+glitched-nx@users.noreply.github.com> Date: Wed, 25 Dec 2024 23:20:31 +0100 Subject: [PATCH 24/25] Solve conflicts in de.json, fr.json files - and complete them (#48) --- assets/romfs/i18n/de.json | 274 +++++++++++++++++++------------------- assets/romfs/i18n/fr.json | 48 +------ 2 files changed, 140 insertions(+), 182 deletions(-) diff --git a/assets/romfs/i18n/de.json b/assets/romfs/i18n/de.json index d6cfcea..9d9fbf5 100644 --- a/assets/romfs/i18n/de.json +++ b/assets/romfs/i18n/de.json @@ -1,31 +1,31 @@ { "[Applet Mode]": "[Applet-Modus]", - "No Internet": "Kein Internet", - "Files": "", - "Apps": "", - "Store": "", - "Menu": "Menu", + "No Internet": "Keine Internetverbindung", + "Files": "Dateien", + "Apps": "Apps", + "Store": "Store", + "Menu": "Menü", "Options": "Optionen", - "OK": "", + "OK": "OK", "Back": "Zurück", - "Select": "", + "Select": "Auswählen", "Open": "Öffnen", - "Launch": "Start", + "Launch": "Starten", "Info": "Info", "Install": "Installieren", "Delete": "Löschen", - "Restart": "", - "Changelog": "", - "Details": "", - "Update": "", - "Remove": "", - "Download": "Herunterladen", + "Restart": "Neustart", + "Changelog": "Changelog", + "Details": "Details", + "Update": "Update", + "Remove": "Entfernen", + "Download": "Download", "Next Page": "Nächste Seite", "Prev Page": "Vorherige Seite", - "Unstar": "", - "Star": "", - "System memory": "", - "microSD card": "", + "Unstar": "Favorit entfernen", + "Star": "Favorit", + "System memory": "System-Speicher", + "microSD card": "microSD-Karte", "Yes": "Ja", "No": "Nein", "Enabled": "Aktiviert", @@ -35,41 +35,41 @@ "Sort Options": "Sortieroptionen", "Filter": "Filter", "Sort": "Sortieren", - "Order": "Befehl", + "Order": "Reihenfolge", "Search": "Suchen", "Updated": "Aktualisiert", - "Updated (Star)": "", + "Updated (Star)": "Aktualisiert (Favoriten)", "Downloads": "Downloads", "Size": "Größe", - "Size (Star)": "", + "Size (Star)": "Größe (Favoriten)", "Alphabetical": "Alphabetisch", - "Alphabetical (Star)": "", - "Likes": "", - "ID": "", + "Alphabetical (Star)": "Alphabetisch (Favoriten)", + "Likes": "Likes", + "ID": "ID", "Decending": "Absteigend", "Descending (down)": "Absteigend", - "Desc": "Absteigend", + "Desc": "Abst.", "Ascending": "Aufsteigend", "Ascending (Up)": "Aufsteigend", - "Asc": "Aufsteigend", + "Asc": "Aufst.", - "Menu Options": "Menüoptionen", + "Menu Options": "Menü-Optionen", "Header": "Header", "Theme": "Theme", - "Theme Options": "Themenoptionen", - "Select Theme": "Wählen Sie Theme aus", - "Shuffle": "Shuffle", + "Theme Options": "Theme-Optionen", + "Select Theme": "Theme auswählen", + "Shuffle": "Zufällig", "Music": "Musik", "Network": "Netzwerk", - "Network Options": "Netzwerkoptionen", + "Network Options": "Netzwerk-Optionen", "Nxlink": "Nxlink", - "Nxlink Connected": "", - "Nxlink Upload": "", - "Nxlink Finished": "", - "Switch-Handheld!": "", - "Switch-Docked!": "", + "Nxlink Connected": "Nxlink verbunden", + "Nxlink Upload": "Nxlink Upload", + "Nxlink Finished": "Nxlink abgeschlossen", + "Switch-Handheld!": "Switch-Handheld!", + "Switch-Docked!": "Switch-Dock-Modus!", "Language": "Sprache", - "Auto": "", + "Auto": "Auto", "English": "English", "Japanese": "日本語", "French": "Français", @@ -83,148 +83,148 @@ "Russian": "Русский", "Swedish": "Svenska", "Logging": "Logging", - "Replace hbmenu on exit": "Ersetzen Sie hbmenu beim Beenden", + "Replace hbmenu on exit": "hbmenu beim Beenden ersetzen", "Misc": "Sonstiges", - "Misc Options": "Verschiedene Optionen", + "Misc Options": "Weitere Optionen", "Web": "Web", - "Install forwarders": "", - "Install location": "", - "Show install warning": "", + "Install forwarders": "Forwarder installieren", + "Install location": "Installationsort", + "Show install warning": "Installationswarnung anzeigen", - "FileBrowser": "DateiBrowser", - "%zd files": "%zd files", - "%zd dirs": "%zd dirs", - "File Options": "Dateioptionen", + "FileBrowser": "Datei-Browser", + "%zd files": "%zd Dateien", + "%zd dirs": "%zd Ordner", + "File Options": "Datei-Optionen", "Show Hidden": "Versteckte anzeigen", "Folders First": "Ordner zuerst", - "Hidden Last": "Zuletzt versteckt", + "Hidden Last": "Versteckte zuletzt", "Cut": "Ausschneiden", "Copy": "Kopieren", - "Paste": "", - "Paste ": "", - " file(s)?": "", + "Paste": "Einfügen", + "Paste ": "Einfügen ", + " file(s)?": " Datei(en)?", "Rename": "Umbenennen", - "Set New File Name": "", + "Set New File Name": "Neuen Dateinamen eingeben", "Advanced": "Erweitert", "Advanced Options": "Erweiterte Optionen", "Create File": "Datei erstellen", - "Set File Name": "", + "Set File Name": "Dateinamen eingeben", "Create Folder": "Ordner erstellen", - "Set Folder Name": "", - "View as text (unfinished)": "Als Text anzeigen (unfertig)", - "Empty...": "", - "Open with DayBreak?": "", - "Launch ": "", - "Launch option for: ": "", - "Select launcher for: ": "", + "Set Folder Name": "Ordnernamen eingeben", + "View as text (unfinished)": "Als Text anzeigen (Beta)", + "Empty...": "Leer...", + "Open with DayBreak?": "Mit DayBreak öffnen?", + "Launch ": "Starten ", + "Launch option for: ": "Startoption für: ", + "Select launcher for: ": "Launcher auswählen für: ", "Homebrew": "Homebrew", "Homebrew Options": "Homebrew-Optionen", - "Hide Sphaira": "Sphaira verstecken", + "Hide Sphaira": "Sphaira ausblenden", "Install Forwarder": "Forwarder installieren", - "WARNING: Installing forwarders will lead to a ban!": "ACHTUNG: Die Installation von Forwardern führt zu einem Ban!", - "Installing Forwarder": "", - "Creating Program": "", - "Creating Control": "", - "Creating Meta": "", - "Writing Nca": "", - "Updating ncm databse": "", - "Pushing application record": "", - "Installed!": "", - "Failed to install forwarder": "", - "Unstarred ": "", - "Starred ": "", + "WARNING: Installing forwarders will lead to a ban!": "WARNUNG: Installation von Forwardern führt zum Ban!", + "Installing Forwarder": "Installiere Forwarder", + "Creating Program": "Erstelle Programm", + "Creating Control": "Erstelle Control", + "Creating Meta": "Erstelle Meta", + "Writing Nca": "Schreibe NCA", + "Updating ncm databse": "Aktualisiere NCM-Datenbank", + "Pushing application record": "Übertrage Anwendungsdaten", + "Installed!": "Installiert!", + "Failed to install forwarder": "Forwarder-Installation fehlgeschlagen", + "Unstarred ": "Favorit entfernt ", + "Starred ": "Favorit hinzugefügt ", - "AppStore": "", - "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sortieren: %s | Befehl: %s", + "AppStore": "AppStore", + "Filter: %s | Sort: %s | Order: %s": "Filter: %s | Sortierung: %s | Reihenfolge: %s", "AppStore Options": "AppStore-Optionen", "All": "Alle", "Games": "Spiele", "Emulators": "Emulatoren", - "Tools": "Werkzeuge", + "Tools": "Tools", "Themes": "Themes", "Legacy": "Legacy", - "version: %s": "version: %s", - "updated: %s": "updated: %s", - "category: %s": "category: %s", - "extracted: %.2f MiB": "extracted: %.2f MiB", - "app_dls: %s": "app_dls: %s", - "More by Author": "", - "Leave Feedback": "", + "version: %s": "Version: %s", + "updated: %s": "Aktualisiert: %s", + "category: %s": "Kategorie: %s", + "extracted: %.2f MiB": "Entpackt: %.2f MiB", + "app_dls: %s": "Downloads: %s", + "More by Author": "Mehr vom Entwickler", + "Leave Feedback": "Feedback geben", - "Irs": "Irs", - "Ambient Noise Level: ": "", + "Irs": "IR-Sensor", + "Ambient Noise Level: ": "Umgebungsrauschen: ", "Controller": "Controller", - "Pad ": "Unterlage ", + "Pad ": "Pad ", " (Available)": " (Verfügbar)", - " (Unsupported)": "", + " (Unsupported)": " (Nicht unterstützt)", " (Unconnected)": " (Nicht verbunden)", "HandHeld": "Handheld", - "Rotation": "Drehung", - "0 (Sideways)": "0 (Seitwärts)", - "90 (Flat)": "90 (flach)", - "180 (-Sideways)": "180 (-Seitwärts)", - "270 (Upside down)": "270 (verkehrt herum)", + "Rotation": "Rotation", + "0 (Sideways)": "0° (Seitlich)", + "90 (Flat)": "90° (Flach)", + "180 (-Sideways)": "180° (-Seitlich)", + "270 (Upside down)": "270° (Kopfüber)", "Colour": "Farbe", "Grey": "Grau", - "Ironbow": "Eisenbogen", + "Ironbow": "Ironbow", "Green": "Grün", "Red": "Rot", "Blue": "Blau", - "Light Target": "Leichtes Ziel", + "Light Target": "Lichtziel", "All leds": "Alle LEDs", "Bright group": "Helle Gruppe", "Dim group": "Dunkle Gruppe", - "None": "Keiner", - "Gain": "Gain", - "Negative Image": "Negatives Bild", - "Normal image": "Normales Bild", - "Negative image": "Negatives Bild", + "None": "Keine", + "Gain": "Verstärkung", + "Negative Image": "Negativ-Bild", + "Normal image": "Normal-Bild", + "Negative image": "Negativ-Bild", "Format": "Format", "320x240": "320×240", "160x120": "160×120", "80x60": "80×60", "40x30": "40×30", "20x15": "20×15", - "Trimming Format": "Zuschneideformat", - "External Light Filter": "Externer Lichtfilter", - "Load Default": "Standardoptionen laden", + "Trimming Format": "Beschnitt-Format", + "External Light Filter": "Externes Lichtfilter", + "Load Default": "Standard laden", "Themezer": "Themezer", - "Themezer Options": "", - "Nsfw": "", - "Page": "", - "Page %zu / %zu": "Page %zu / %zu", - "Enter Page Number": "", - "Bad Page": "", - "Download theme?": "", + "Themezer Options": "Themezer-Optionen", + "Nsfw": "NSFW", + "Page": "Seite", + "Page %zu / %zu": "Seite %zu / %zu", + "Enter Page Number": "Seitenzahl eingeben", + "Bad Page": "Ungültige Seite", + "Download theme?": "Theme herunterladen?", - "Installing ": "", - "Uninstalling ": "", - "Deleting ": "", - "Deleting": "", - "Pasting ": "", - "Pasting": "", - "Removing ": "", - "Scanning ": "", - "Creating ": "", - "Copying ": "", - "Trying to load ": "", - "Downloading ": "", - "Checking MD5": "", - "Loading...": "", - "Loading": "", - "Empty!": "", - "Not Ready...": "", - "Error loading page!": "", - "Update avaliable: ": "", - "Download update: ": "", - "Updated to ": "", - "Restart Sphaira?": "", - "Failed to download update": "", - "Delete Selected files?": "", - "Completely remove ": "", - "Are you sure you want to delete ": "Mit dem Löschvorgang fortfahren?", - "Are you sure you wish to cancel?": "", - "If this message appears repeatedly, please open an issue.": "" -} \ No newline at end of file + "Installing ": "Installiere ", + "Uninstalling ": "Deinstalliere ", + "Deleting ": "Lösche ", + "Deleting": "Lösche", + "Pasting ": "Füge ein ", + "Pasting": "Füge ein", + "Removing ": "Entferne ", + "Scanning ": "Scanne ", + "Creating ": "Erstelle ", + "Copying ": "Kopiere ", + "Trying to load ": "Lade ", + "Downloading ": "Lade herunter ", + "Checking MD5": "Prüfe MD5", + "Loading...": "Lade...", + "Loading": "Lade", + "Empty!": "Leer!", + "Not Ready...": "Nicht bereit...", + "Error loading page!": "Fehler beim Laden!", + "Update avaliable: ": "Update verfügbar: ", + "Download update: ": "Update herunterladen: ", + "Updated to ": "Aktualisiert auf ", + "Restart Sphaira?": "Sphaira neustarten?", + "Failed to download update": "Update-Download fehlgeschlagen", + "Delete Selected files?": "Ausgewählte Dateien löschen?", + "Completely remove ": "Vollständig entfernen ", + "Are you sure you want to delete ": "Wirklich löschen ", + "Are you sure you wish to cancel?": "Wirklich abbrechen?", + "If this message appears repeatedly, please open an issue.": "Bei wiederholtem Auftreten bitte Issue erstellen." +} diff --git a/assets/romfs/i18n/fr.json b/assets/romfs/i18n/fr.json index 3af3da1..9bf1881 100644 --- a/assets/romfs/i18n/fr.json +++ b/assets/romfs/i18n/fr.json @@ -14,11 +14,7 @@ "Info": "Info.", "Install": "Installer", "Delete": "Supprimer", -<<<<<<< HEAD "Restart": "Redémarrer", -======= - "Restart": "", ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Changelog": "Changelog", "Details": "Détails", "Update": "Mise à jour", @@ -29,7 +25,7 @@ "Unstar": "Retirer des favories", "Star": "Ajouter aux favories", "System memory": "Mémoire système", - "microSD card": "microSD card", + "microSD card": "Carte microSD", "Yes": "Oui", "No": "Non", "Enabled": "Activé(e)", @@ -42,7 +38,6 @@ "Order": "Ordre", "Search": "Recherche", "Updated": "Mis à jour", -<<<<<<< HEAD "Updated (Star)": "Mis à jour (Favories)", "Downloads": "Téléchargements", "Size": "Taille", @@ -50,15 +45,6 @@ "Alphabetical": "Alphabétique", "Alphabetical (Star)": "Alphabétique (Favories)", "Likes": "Likes", -======= - "Updated (Star)": "", - "Downloads": "Téléchargements", - "Size": "Taille", - "Size (Star)": "", - "Alphabetical": "Alphabétique", - "Alphabetical (Star)": "", - "Likes": "Favoris", ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "ID": "ID", "Decending": "Décroissant", "Descending (down)": "Décroissant", @@ -80,18 +66,13 @@ "Nxlink Connected": "Nxlink Connecté", "Nxlink Upload": "Nxlink téléversement", "Nxlink Finished": "Nxlink terminé", -<<<<<<< HEAD "Switch-Handheld!": "Switch-Portable", "Switch-Docked!": "Switch-Dockée", -======= - "Switch-Handheld!": "", - "Switch-Docked!": "", ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Language": "Langue", "Auto": "Auto", "English": "English", "Japanese": "日本語", - "French": "Français", + "French": "Français", "German": "Deutsch", "Italian": "Italiano", "Spanish": "Español", @@ -133,15 +114,9 @@ "View as text (unfinished)": "Afficher sous forme de texte (inachevé)", "Empty...": "Vide...", "Open with DayBreak?": "Ouvrir avec DayBreak?", -<<<<<<< HEAD "Launch ": "Lancer ", "Launch option for: ": "Option de lancement pour: ", "Select launcher for: ": "Sélectionner le lanceur pour: ", -======= - "Launch ": "", - "Launch option for: ": "Option de lancement pour: ", - "Select launcher for: ": "", ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Homebrew": "Homebrew", "Homebrew Options": "Options Homebrew", @@ -182,11 +157,7 @@ "Controller": "Contrôleur", "Pad ": "Manette ", " (Available)": " (Disponible)", -<<<<<<< HEAD " (Unsupported)": "Non supporté", -======= - " (Unsupported)": "", ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 " (Unconnected)": " (Non connectée)", "HandHeld": "Portable", "Rotation": "Rotation", @@ -238,11 +209,7 @@ "Scanning ": "Scan ", "Creating ": "Création ", "Copying ": "Copie ", -<<<<<<< HEAD "Trying to load ": "Tente de charger ", -======= - "Trying to load ": "", ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Downloading ": "Téléchargement ", "Checking MD5": "Vérification MD5", "Loading...": "Chargement...", @@ -252,21 +219,12 @@ "Error loading page!": "Erreur du chargement de la page!", "Update avaliable: ": "Mise à jour disponible: ", "Download update: ": "Télécharger la mise à jour: ", -<<<<<<< HEAD "Updated to ": "Mis à jour vers ", "Restart Sphaira?": "Redémarrer Sphaira?", -======= - "Updated to ": "", - "Restart Sphaira?": "", ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 "Failed to download update": "Echec du téléchargement de la mise à jour", "Delete Selected files?": "Supprimer les fichiers sélectionnés?", "Completely remove ": "Supprimer totalement ", "Are you sure you want to delete ": "Êtes-vous sûr de vouloir supprimer ", "Are you sure you wish to cancel?": "Souhaitez-vous vraiment annuler?", -<<<<<<< HEAD "If this message appears repeatedly, please open an issue.": "Si ce message apparait en boucle veuillez ouvrir une issue." -======= - "If this message appears repeatedly, please open an issue.": "" ->>>>>>> 3df676df0f432112aa14fbeae26943c91690e829 -} \ No newline at end of file +} From f01dbf7c67ff307e3c5cf456630985233c7aecc6 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Wed, 25 Dec 2024 22:27:25 +0000 Subject: [PATCH 25/25] silence warning, add credit to readme, bump version for release --- README.md | 11 +++++++++-- sphaira/CMakeLists.txt | 2 +- sphaira/source/ftpsrv_helper.cpp | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3d035d2..944b4fd 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ A homebrew menu for the switch. -It was built for my usage, as such, features that may seem out of place are included because i found them useful. - [See the gbatemp thread for more details / discussion](https://gbatemp.net/threads/sphaira-hbmenu-replacement.664523/). ## showcase @@ -26,6 +24,14 @@ please include: - FW version - The bug itself and how to reproduce it +## ftp + +ftp can be enabled via the network menu and listens on port 5000, no username or password is required. + +## mtp + +mtp can be enabled via the network menu. + ## file assoc sphaira has file assoc support. lets say your app supports loading .png files, then you could write an assoc file, then when using the file browser, clicking on a .png file will launch your app along with the .png file as argv[1]. This was primarly added for rom loading support for emulators / frontends such as retroarch, melonds, mgba etc. @@ -52,4 +58,5 @@ see `assets/romfs/assoc/` for more examples of file assoc entries - minIni - gbatemp - hb-appstore +- haze - everyone who has contributed to this project! diff --git a/sphaira/CMakeLists.txt b/sphaira/CMakeLists.txt index 6d78e42..c4ac1a1 100644 --- a/sphaira/CMakeLists.txt +++ b/sphaira/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.13) -set(sphaira_VERSION 0.4.1) +set(sphaira_VERSION 0.5.0) project(sphaira VERSION ${sphaira_VERSION} diff --git a/sphaira/source/ftpsrv_helper.cpp b/sphaira/source/ftpsrv_helper.cpp index ef03698..ef8507d 100644 --- a/sphaira/source/ftpsrv_helper.cpp +++ b/sphaira/source/ftpsrv_helper.cpp @@ -203,7 +203,11 @@ int ftp_vfs_write(struct FtpVfsFile* f, const void* buf, size_t size) { return vfs_fs_set_errno(rc); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" buf += sz; +#pragma GCC diagnostic pop + size -= sz; f->off += f->buf_off; f->buf_off = 0;