diff --git a/Libraries/SDLLib b/Libraries/SDLLib index d86567d..8ee7816 160000 --- a/Libraries/SDLLib +++ b/Libraries/SDLLib @@ -1 +1 @@ -Subproject commit d86567d9c30fa605e171ee0d5f0a2101879a7be5 +Subproject commit 8ee78161dce7b644d2bd9a561477a654f3694b77 diff --git a/include/JKSV.hpp b/include/JKSV.hpp index b04adc7..f8fbbb5 100644 --- a/include/JKSV.hpp +++ b/include/JKSV.hpp @@ -35,9 +35,11 @@ class JKSV /// @brief JKSV icon in upper left corner. sdl::SharedTexture m_headerIcon{}; - /// @brief These are pointers to the translation info. - const char *m_translation{}; - const char *m_author{}; + /// @brief Stores the translation string. + std::string m_translationInfo{}; + + /// @brief Stores the build string. + std::string m_buildString{}; /// @brief Initializes fslib and takes care of a few other things. bool initialize_filesystem(); diff --git a/include/appstates/BlacklistEditState.hpp b/include/appstates/BlacklistEditState.hpp new file mode 100644 index 0000000..7080a85 --- /dev/null +++ b/include/appstates/BlacklistEditState.hpp @@ -0,0 +1,53 @@ +#pragma once +#include "appstates/BaseState.hpp" +#include "ui/ui.hpp" + +#include +#include + +class BlacklistEditState final : public BaseState +{ + public: + /// @brief Constructor. Loads the blacklist and ensures the panel is allocated.S + BlacklistEditState(); + + /// @brief Clears and resets the panel. + ~BlacklistEditState(); + + /// @brief Creates and returns a new state. + static std::shared_ptr create(); + + /// @brief Creates, pushes, then returns a new blacklist edit states. + static std::shared_ptr create_and_push(); + + /// @brief Update override. + void update() override; + + /// @brief Render override. + void render() override; + + private: + /// @brief Local copy of the blacklist. + std::vector m_blacklist{}; + + /// @brief Menu with blacklisted titles. + std::shared_ptr m_blacklistMenu{}; + + /// @brief This panel is shared by all instances. + static inline std::unique_ptr sm_slidePanel{}; + + /// @brief Inits ^. + void initialize_static_members(); + + /// @brief Loads the blacklist from config. + void load_blacklist(); + + /// @brief Fills the menu with the titles blacklisted. + void initialize_menu(); + + /// @brief Updates the menu. + void refresh_menu(); + + /// @brief Removes the selected title from the blacklist and refreshes everything. + void remove_from_blacklist(); +}; diff --git a/include/appstates/ConfirmState.hpp b/include/appstates/ConfirmState.hpp index 530ca3e..7ab656d 100644 --- a/include/appstates/ConfirmState.hpp +++ b/include/appstates/ConfirmState.hpp @@ -1,6 +1,7 @@ #pragma once #include "StateManager.hpp" #include "appstates/BaseState.hpp" +#include "appstates/FadeState.hpp" #include "appstates/ProgressState.hpp" #include "appstates/TaskState.hpp" #include "colors.hpp" @@ -9,7 +10,7 @@ #include "sdl.hpp" #include "strings.hpp" #include "sys/sys.hpp" -#include "ui/render_functions.hpp" +#include "ui/ui.hpp" #include #include @@ -42,21 +43,17 @@ class ConfirmState final : public BaseState /// @param dataStruct shared_ptr that is passed to function. I tried templating this and it was a nightmare. ConfirmState(std::string_view query, bool holdRequired, TaskFunction function, std::shared_ptr dataStruct) : BaseState{false} - , m_queryString{query} - , m_yesText{strings::get_by_name(strings::names::YES_NO, 0)} - , m_noText{strings::get_by_name(strings::names::YES_NO, 1)} - , m_holdRequired{holdRequired} - , m_function{function} - , m_dataStruct{dataStruct} + , m_query(query) + , m_yesText(strings::get_by_name(strings::names::YES_NO, 0)) + , m_noText(strings::get_by_name(strings::names::YES_NO, 1)) + , m_holdRequired(holdRequired) + , m_function(function) + , m_dataStruct(dataStruct) { - const int noWidth = sdl::text::get_width(22, m_noText); - - // This stays the same from here on out. - m_noX = COORD_NO_X - (noWidth / 2); + ConfirmState::initialize_static_members(); + ConfirmState::center_no(); ConfirmState::center_yes(); - - // Gonna loop to do this. - for (int i = 0; i < 3; i++) { m_holdText[i] = strings::get_by_name(strings::names::HOLDING_STRINGS, i); } + ConfirmState::load_holding_strings(); } /// @brief Required even if it does nothing. @@ -77,8 +74,9 @@ class ConfirmState final : public BaseState TaskFunction function, std::shared_ptr dataStruct) { - auto newState = create(query, holdRequired, function, dataStruct); - StateManager::push_state(newState); + // I'm gonna use a sneaky trick here. This shouldn't do this because it's confusing. + auto newState = create(query, holdRequired, function, dataStruct); + auto fadeState = FadeState::create_and_push(colors::DIM_BACKGROUND, 0x00, 0x88, newState); return newState; } @@ -95,66 +93,33 @@ class ConfirmState final : public BaseState const bool holdTriggered = m_triggerGuard && aPressed && m_holdRequired; const bool holdSustained = m_triggerGuard && aHeld && m_holdRequired; - if (noHoldTrigger) - { - ConfirmState::create_push_state(); - BaseState::deactivate(); - } - else if (holdTriggered) - { - m_startingTickCount = SDL_GetTicks64(); - m_yesText = m_holdText[0]; - ConfirmState::center_yes(); - } - else if (holdSustained) - { - const uint64_t totalTicks = SDL_GetTicks64() - m_startingTickCount; - const bool threeSeconds = totalTicks >= 3000; - const bool twoSeconds = totalTicks >= 2000; - const bool oneSecond = totalTicks >= 1000; - - if (threeSeconds) - { - ConfirmState::create_push_state(); - BaseState::deactivate(); - } - else if (twoSeconds) - { - m_yesText = m_holdText[2]; - ConfirmState::center_yes(); - } - else if (oneSecond) - { - m_yesText = m_holdText[1]; - ConfirmState::center_yes(); - } - } - else if (aReleased) - { - m_yesText = strings::get_by_name(strings::names::YES_NO, 0); - ConfirmState::center_yes(); - } - else if (bPressed) { BaseState::deactivate(); } + if (noHoldTrigger) { ConfirmState::confirmed(); } + else if (holdTriggered) { ConfirmState::hold_triggered(); } + else if (holdSustained) { ConfirmState::hold_sustained(); } + else if (aReleased) { ConfirmState::hold_released(); } + else if (bPressed) { ConfirmState::cancelled(); } } /// @brief Renders the state to screen. void render() override { - sdl::render_rect_fill(NULL, 0, 0, 1280, 720, colors::DIM_BACKGROUND); - ui::render_dialog_box(NULL, 280, 262, 720, 256); + const bool hasFocus = BaseState::has_focus(); - sdl::text::render(NULL, 312, 288, 18, 656, colors::WHITE, m_queryString.c_str()); + sdl::render_rect_fill(sdl::Texture::Null, 0, 0, 1280, 720, colors::DIM_BACKGROUND); - sdl::render_line(NULL, 280, 454, 999, 454, colors::WHITE); - sdl::render_line(NULL, 640, 454, 640, 517, colors::WHITE); + sm_dialog->render(sdl::Texture::Null, hasFocus); + sdl::text::render(sdl::Texture::Null, 312, 288, 18, 656, colors::WHITE, m_query); - sdl::text::render(NULL, m_yesX, 476, 22, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_yesText); - sdl::text::render(NULL, m_noX, 476, 22, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_noText); + sdl::render_line(sdl::Texture::Null, 280, 454, 999, 454, colors::WHITE); + sdl::render_line(sdl::Texture::Null, 640, 454, 640, 517, colors::WHITE); + + sdl::text::render(sdl::Texture::Null, m_yesX, 476, 22, sdl::text::NO_WRAP, colors::WHITE, m_yesText); + sdl::text::render(sdl::Texture::Null, m_noX, 476, 22, sdl::text::NO_WRAP, colors::WHITE, m_noText); } private: - /// @brief String displayed - const std::string m_queryString{}; + /// @brief This stores the query text. + std::string m_query{}; /// @brief These are pointers to the strings used to avoid call strings::get_by_name so much. const char *m_yesText{}, *m_noText{}; @@ -174,22 +139,85 @@ class ConfirmState final : public BaseState /// @brief Keep track of the ticks/time needed to confirm. uint64_t m_startingTickCount{}; + /// @brief Keeps track of which + int m_stage{}; + /// @brief Function to execute if action is confirmed. const TaskFunction m_function{}; /// @brief Pointer to data struct passed to ^ const std::shared_ptr m_dataStruct{}; - void create_push_state() + static inline std::shared_ptr sm_dialog{}; + + void initialize_static_members() { - auto newState = std::make_shared(m_function, m_dataStruct); - StateManager::push_state(newState); + if (sm_dialog) { return; } + + sm_dialog = ui::DialogBox::create(280, 262, 720, 256); } // This just centers the Yes or holding text. void center_yes() { - const size_t yesWidth = sdl::text::get_width(22, m_yesText); - m_yesX = COORD_YES_X - (yesWidth / 2); + const int yesWidth = sdl::text::get_width(22, m_yesText); + m_yesX = COORD_YES_X - (yesWidth / 2); + } + + void center_no() + { + const int noWidth = sdl::text::get_width(22, m_noText); + m_noX = COORD_NO_X - (noWidth / 2); + } + + void load_holding_strings() + { + for (int i = 0; const char *string = strings::get_by_name(strings::names::HOLDING_STRINGS, i); i++) + { + m_holdText[i] = string; + } + } + + void confirmed() + { + auto newState = std::make_shared(m_function, m_dataStruct); + StateManager::push_state(newState); + BaseState::deactivate(); + } + + void hold_triggered() + { + m_startingTickCount = SDL_GetTicks64(); + ConfirmState::change_holding_text(0); + } + + void hold_sustained() + { + const uint64_t totalTicks = SDL_GetTicks64() - m_startingTickCount; + const bool threeSeconds = totalTicks >= 3000; + const bool twoSeconds = totalTicks >= 2000; + const bool oneSecond = totalTicks >= 1000; + + if (threeSeconds) { ConfirmState::confirmed(); } + else if (twoSeconds) { ConfirmState::change_holding_text(2); } + else if (oneSecond) { ConfirmState::change_holding_text(1); } + } + + void hold_released() + { + m_yesText = strings::get_by_name(strings::names::YES_NO, 0); + ConfirmState::center_yes(); + } + + void cancelled() + { + FadeState::create_and_push(colors::DIM_BACKGROUND, 0x88, 0x00, nullptr); + BaseState::deactivate(); + } + + void change_holding_text(int index) + { + m_yesText = m_holdText[index]; + ConfirmState::center_yes(); } }; diff --git a/include/appstates/FadeInState.hpp b/include/appstates/FadeInState.hpp deleted file mode 100644 index 45267e7..0000000 --- a/include/appstates/FadeInState.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "appstates/BaseState.hpp" -#include "sys/sys.hpp" - -#include - -class FadeInState final : public BaseState -{ - public: - /// @brief Creates a new fade in state. - /// @param nextState The next state to push after the the fade is finished. - FadeInState(std::shared_ptr nextState); - - ~FadeInState() {}; - - /// @brief Returns a new fade in state. See constructor. - static std::shared_ptr create(std::shared_ptr nextState); - - /// @brief Creates, returns and pushes a new FadeInState to the statemanager. - static std::shared_ptr create_and_push(std::shared_ptr nextState); - - /// @brief Update override. - void update() override; - - /// @brief Render override. - void render() override; - - private: - /// @brief Alpha value. - uint8_t m_alpha = 0xFF; - - sys::Timer m_fadeTimer{}; - - /// @brief Pointer to the next state to push. - std::shared_ptr m_nextState{}; -}; diff --git a/include/appstates/FadeState.hpp b/include/appstates/FadeState.hpp new file mode 100644 index 0000000..0604883 --- /dev/null +++ b/include/appstates/FadeState.hpp @@ -0,0 +1,65 @@ +#pragma once +#include "appstates/BaseState.hpp" +#include "sdl.hpp" +#include "sys/sys.hpp" + +#include + +class FadeState final : public BaseState +{ + public: + /// @brief Direction (In/Out) of the fade. This is auto-determined at construction. + enum class Direction + { + In, + Out + }; + + /// @brief Creates a new fade in state. + /// @param nextState The next state to push after the the fade is finished. + FadeState(sdl::Color baseColor, uint8_t startAlpha, uint8_t endAlpha, std::shared_ptr nextState); + + ~FadeState() {}; + + /// @brief Returns a new fade in state. See constructor. + static std::shared_ptr create(sdl::Color baseColor, + uint8_t startAlpha, + uint8_t endAlpha, + std::shared_ptr nextState); + + /// @brief Creates, returns and pushes a new FadeInState to the statemanager. + static std::shared_ptr create_and_push(sdl::Color baseColor, + uint8_t startAlpha, + uint8_t endAlpha, + std::shared_ptr nextState); + + /// @brief Update override. + void update() override; + + /// @brief Render override. + void render() override; + + private: + sdl::Color m_baseColor{}; + + /// @brief Alpha value. + uint8_t m_alpha{}; + + /// @brief Alpha value to destruct at. + uint8_t m_endAlpha{}; + + FadeState::Direction m_direction{}; + + uint8_t m_divisor{}; + + /// @brief Timer for fade. + sys::Timer m_fadeTimer{}; + + /// @brief Pointer to the next state to push. + std::shared_ptr m_nextState{}; + + void find_divisor(); + void decrease_alpha(); + void increase_alpha(); + void completed(); +}; diff --git a/include/appstates/ProgressState.hpp b/include/appstates/ProgressState.hpp index ef5dff7..3cf74a0 100644 --- a/include/appstates/ProgressState.hpp +++ b/include/appstates/ProgressState.hpp @@ -2,7 +2,9 @@ #include "StateManager.hpp" #include "appstates/BaseTask.hpp" #include "sys/sys.hpp" +#include "ui/ui.hpp" +#include #include #include @@ -16,13 +18,14 @@ class ProgressState final : public BaseTask /// @note All functions passed to this must follow this signature: void function(sys::ProgressTask *, ) template ProgressState(void (*function)(sys::ProgressTask *, Args...), Args... args) - : BaseTask{} + : BaseTask() { + ProgressState::initialize_static_members(); m_task = std::make_unique(function, std::forward(args)...); } /// @brief Required destructor. - ~ProgressState() {}; + ~ProgressState(); template static std::shared_ptr create(void (*function)(sys::ProgressTask *, Args...), Args... args) @@ -56,4 +59,9 @@ class ProgressState final : public BaseTask /// @brief Percentage as a string for printing to screen. std::string m_percentageString{}; + + /// @brief This is the dialog box everything is rendered to. + static inline std::shared_ptr sm_dialog{}; + + void initialize_static_members(); }; diff --git a/include/appstates/SaveCreateState.hpp b/include/appstates/SaveCreateState.hpp index b1ff021..00dc44e 100644 --- a/include/appstates/SaveCreateState.hpp +++ b/include/appstates/SaveCreateState.hpp @@ -18,7 +18,7 @@ class SaveCreateState final : public BaseState SaveCreateState(data::User *user, TitleSelectCommon *titleSelect); /// @brief Required destructor. - ~SaveCreateState() {}; + ~SaveCreateState(); /// @brief Returns a new SaveCreate state. See constructor for arguments. static std::shared_ptr create(data::User *user, TitleSelectCommon *titleSelect); @@ -43,7 +43,7 @@ class SaveCreateState final : public BaseState TitleSelectCommon *m_titleSelect{}; /// @brief Menu populated with every title found on the system. - ui::Menu m_saveMenu; + std::shared_ptr m_saveMenu{}; /// @brief Vector of pointers to the title info. This allows sorting them alphabetically and other things. std::vector m_titleInfoVector{}; diff --git a/include/appstates/SettingsState.hpp b/include/appstates/SettingsState.hpp index 3255c50..6e2b2b3 100644 --- a/include/appstates/SettingsState.hpp +++ b/include/appstates/SettingsState.hpp @@ -48,6 +48,10 @@ class SettingsState final : public BaseState /// @brief Runs a routine to update the menu strings for the menu. void update_menu_options(); + void change_working_directory(); + + void create_push_blacklist_edit(); + /// @brief Toggles or executes the code to changed the selected menu option. void toggle_options(); diff --git a/include/appstates/TaskState.hpp b/include/appstates/TaskState.hpp index 0b6abdd..76bb8f6 100644 --- a/include/appstates/TaskState.hpp +++ b/include/appstates/TaskState.hpp @@ -15,13 +15,13 @@ class TaskState final : public BaseTask /// @note All functions passed must follow this signature: void function(sys::Task *, ) template TaskState(void (*function)(sys::Task *, Args...), Args... args) - : BaseTask{} + : BaseTask() { m_task = std::make_unique(function, std::forward(args)...); } /// @brief Required destructor. - ~TaskState() {}; + ~TaskState(); template static std::shared_ptr create(void (*function)(sys::Task *, Args...), Args... args) diff --git a/include/appstates/TitleOptionState.hpp b/include/appstates/TitleOptionState.hpp index ed5f057..8142d05 100644 --- a/include/appstates/TitleOptionState.hpp +++ b/include/appstates/TitleOptionState.hpp @@ -16,7 +16,7 @@ class TitleOptionState final : public BaseState TitleOptionState(data::User *user, data::TitleInfo *titleInfo, TitleSelectCommon *titleSelect); /// @brief Required destructor. - ~TitleOptionState() {}; + ~TitleOptionState(); /// @brief Returns a new TitleOptionState. See constructor. static std::shared_ptr create(data::User *user, diff --git a/include/config.hpp b/include/config.hpp index 45f63c8..33e8236 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -2,6 +2,7 @@ #include "fslib.hpp" #include +#include namespace config { @@ -53,11 +54,18 @@ namespace config /// @param applicationID Application ID to add or remove. void add_remove_blacklist(uint64_t applicationID); + /// @brief Gets the currently blacklisted application IDs. + /// @param listOut Vector to store application IDs to. + void get_blacklisted_titles(std::vector &listOut); + /// @brief Returns if the title is found in the blacklist. /// @param applicationID Application ID to search for. /// @return True if found. False if not. bool is_blacklisted(uint64_t applicationID); + /// @brief Returns whether or not the blacklist is empty. + bool blacklist_is_empty(); + /// @brief Adds a custom output path for the title. /// @param applicationID Application ID of title to add a path for. /// @param customPath Path to assign to the output. diff --git a/include/data/TitleInfo.hpp b/include/data/TitleInfo.hpp index 80e5151..73dbada 100644 --- a/include/data/TitleInfo.hpp +++ b/include/data/TitleInfo.hpp @@ -85,8 +85,7 @@ namespace data /// @brief Allows the path safe title to be set to a new path. /// @param newPathSafe Buffer containing the new safe path to use. - /// @param newPathLength Size of the buffer passed. - void set_path_safe_title(const char *newPathSafe, size_t newPathLength); + void set_path_safe_title(const char *newPathSafe); private: /// @brief This defines how long the buffer is for the path safe version of the title. diff --git a/include/data/data.hpp b/include/data/data.hpp index 5f0cff2..e9a9864 100644 --- a/include/data/data.hpp +++ b/include/data/data.hpp @@ -9,7 +9,8 @@ namespace data { /// @brief Declaration for user list/user pointer vector. - using UserList = std::vector; + using UserList = std::vector; + using TitleInfoList = std::vector; /// @brief Initializes data. Loads user accounts from system and save data info. /// @param clearCache Whether or not the current cache file should be deleted from the SD card first. @@ -25,9 +26,9 @@ namespace data /// @return Pointer to data. nullptr if it's not found. data::TitleInfo *get_title_info_by_id(uint64_t applicationID); - /// @brief Returns a reference to the title info map. - /// @return Reference to TitleInfoMap. - std::unordered_map &get_title_info_map(); + /// @brief Gets a vector of pointers to the title info. + /// @param listOut List to store pointers in. + void get_title_info_list(data::TitleInfoList &listOut); /// @brief Uses the application ID passed to add/load a title to the map. /// @param applicationID Application/System save data ID to add. @@ -41,5 +42,5 @@ namespace data /// @brief Gets a vector of pointers with all titles with saveType. /// @param saveType Save data type to check for. /// @param vectorOut Vector to push pointers to. - void get_title_info_by_type(FsSaveDataType saveType, std::vector &vectorOut); + void get_title_info_by_type(FsSaveDataType saveType, data::TitleInfoList &listOut); } // namespace data diff --git a/include/fs/PathFilter.hpp b/include/fs/PathFilter.hpp new file mode 100644 index 0000000..79b8328 --- /dev/null +++ b/include/fs/PathFilter.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +#include + +namespace fs +{ + class PathFilter + { + public: + + PathFilter(std::string_view filterPath); + + bool is_filtered(std::string_view path); + + private: + std::vector m_paths{}; + }; +} diff --git a/include/fs/ScopedSaveMount.hpp b/include/fs/ScopedSaveMount.hpp index 9060b60..46163ac 100644 --- a/include/fs/ScopedSaveMount.hpp +++ b/include/fs/ScopedSaveMount.hpp @@ -10,7 +10,8 @@ namespace fs /// @brief Opens a scope save mount using the FsSaveDataInfo passed. /// @param mount Mount point. /// @param info Save info to mount. - ScopedSaveMount(std::string_view mount, const FsSaveDataInfo *saveInfo); + /// @param log Optional. Whether or not logging errors is wanted. True by default. + ScopedSaveMount(std::string_view mount, const FsSaveDataInfo *saveInfo, bool log = true); ScopedSaveMount(ScopedSaveMount &&scopedSaveMount); ScopedSaveMount &operator=(ScopedSaveMount &&scopedSaveMount); @@ -30,5 +31,7 @@ namespace fs /// @brief Stores whether or not mounting the save was successful. bool m_isOpen{}; + + bool m_log{}; }; } diff --git a/include/logger.hpp b/include/logger.hpp index 33ed971..b50a4a5 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -3,12 +3,11 @@ namespace logger { - /// @brief Creates and empties the log file + /// @brief Creates the log file if it doesn't exist already. void initialize(); /// @brief Logs a formatted string. /// @param format Format of string. /// @param arguments Va arguments. void log(const char *format, ...); - } // namespace logger diff --git a/include/mathutil.hpp b/include/mathutil.hpp index 20ad04f..cfc78b9 100644 --- a/include/mathutil.hpp +++ b/include/mathutil.hpp @@ -6,6 +6,6 @@ namespace math class Util { public: - static inline Type get_absolute_distance(Type a, Type b) { return a > b ? a - b : b - a; } + static inline Type absolute_distance(Type a, Type b) { return a > b ? a - b : b - a; } }; } diff --git a/include/remote/Storage.hpp b/include/remote/Storage.hpp index 194cc48..f976be9 100644 --- a/include/remote/Storage.hpp +++ b/include/remote/Storage.hpp @@ -51,8 +51,13 @@ namespace remote remote::Item *get_directory_by_name(std::string_view name); /// @brief Retrieves a listing of the items in the current parent directory. - /// @param out List to fill. - remote::Storage::DirectoryListing get_directory_listing(); + /// @param listOut List to fill. + void get_directory_listing(Storage::DirectoryListing &listOut); + + /// @brief Same as above, but allows any parent to be used. + /// @param item Item that is to be treated as a parent. + /// @param listOut List to fill. + void get_directory_listing_with_parent(const remote::Item *item, Storage::DirectoryListing &listOut); // File functions. /// @brief Returns whether a file with name exists within the current directory. @@ -131,5 +136,10 @@ namespace remote /// @brief Searches to find if a file with name exists within the current parent. /// @param name Name of the file to search for. Storage::List::iterator find_file_by_name(std::string_view name); + + /// @brief Searches starting with the iterator start for items that belong to parentID + /// @param start Beginning iterator for search. + /// @param parentID ParentID to match. + Storage::List::iterator find_by_parent_id(Storage::List::iterator start, std::string_view parentID); }; } // namespace remote diff --git a/include/strings.hpp b/include/strings.hpp index 34000c7..06aba8e 100644 --- a/include/strings.hpp +++ b/include/strings.hpp @@ -33,6 +33,7 @@ namespace strings static constexpr std::string_view SAVE_DATA_TYPES = "SaveDataTypes"; static constexpr std::string_view SETTINGS_DESCRIPTIONS = "SettingsDescriptions"; static constexpr std::string_view SETTINGS_MENU = "SettingsMenu"; + static constexpr std::string_view SETTINGS_POPS = "SettingsPops"; static constexpr std::string_view SORT_TYPES = "SortTypes"; static constexpr std::string_view TITLEINFO = "TitleInfo"; static constexpr std::string_view TITLEOPTION_CONFS = "TitleOptionConfirmations"; diff --git a/include/sys/ProgressTask.hpp b/include/sys/ProgressTask.hpp index bb75689..355a0f5 100644 --- a/include/sys/ProgressTask.hpp +++ b/include/sys/ProgressTask.hpp @@ -1,6 +1,8 @@ #pragma once #include "sys/Task.hpp" +#include + namespace sys { /// @brief Derived class of Task that has methods for tracking progress. diff --git a/include/sys/Task.hpp b/include/sys/Task.hpp index 88cfded..bd49d24 100644 --- a/include/sys/Task.hpp +++ b/include/sys/Task.hpp @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include #include diff --git a/include/sys/Timer.hpp b/include/sys/Timer.hpp index bd7c010..d156b25 100644 --- a/include/sys/Timer.hpp +++ b/include/sys/Timer.hpp @@ -28,9 +28,9 @@ namespace sys private: /// @brief Tick count when the timer starts. - uint64_t m_startingTicks; + uint64_t m_startingTicks{}; /// @brief Number of ticks to trigger on. - uint64_t m_triggerTicks; + uint64_t m_triggerTicks{}; }; } // namespace sys diff --git a/include/ui/BoundingBox.hpp b/include/ui/BoundingBox.hpp new file mode 100644 index 0000000..04d953f --- /dev/null +++ b/include/ui/BoundingBox.hpp @@ -0,0 +1,67 @@ +#pragma once +#include "sdl.hpp" +#include "ui/ColorMod.hpp" +#include "ui/Element.hpp" + +#include + +namespace ui +{ + class BoundingBox final : public ui::Element + { + public: + /// @brief Constructs a new bounding box instance. + /// @param x X coord to render to. + /// @param y Y coord to render to. + /// @param width Width of the box in pixels. + /// @param height Height of the box in pixels. + BoundingBox(int x, int y, int width, int height); + + /// @brief Required destructor. + ~BoundingBox() {}; + + /// @brief Creates a returns a new BoundingBox. See constructor. + static std::shared_ptr create(int x, int y, int width, int height); + + /// @brief Update override. + void update(bool hasFocus) override; + + /// @brief Render override. + void render(sdl::SharedTexture &target, bool hasFocus) override; + + /// @brief Sets the X and Y coord. + /// @param x New X coord. + /// @param y New Y coord. + void set_xy(int x, int y); + + /// @brief Sets the width and height of the bounding box. + /// @param width New width. + /// @param height New height. + void set_width_height(int width, int height); + + /// @brief Passing this to the set functions will keep the same coord. + static inline constexpr int NO_SET = -1; + + private: + /// @brief X coord to render to. + int m_x{}; + + /// @brief Y coord to rend to. + int m_y{}; + + /// @brief Width of the box. + int m_width{}; + + /// @brief Height of the box. + int m_height{}; + + /// @brief Color for the bounding box. + ui::ColorMod m_colorMod{}; + + /// @brief This is shared by all instances. + static inline sdl::SharedTexture sm_corners{}; + + /// @brief Loads ^ + void initialize_static_members(); + }; +} diff --git a/include/ui/DialogBox.hpp b/include/ui/DialogBox.hpp new file mode 100644 index 0000000..e89a695 --- /dev/null +++ b/include/ui/DialogBox.hpp @@ -0,0 +1,64 @@ +#pragma once +#include "sdl.hpp" +#include "ui/Element.hpp" + +#include + +namespace ui +{ + class DialogBox final : public ui::Element + { + public: + /// @brief Creates a new dialog box instance. + /// @param width Width of the dialog box in pixels. + /// @param height Height of the dialog box in pixels. + /// @param text Text to display on the dialog box. + DialogBox(int x, int y, int width, int height); + + /// @brief Required destructor. + ~DialogBox() {}; + + /// @brief Creates and returns a new DialogBox instance. + /// @param x X coord to render to. + /// @param y Y coord to render to. + /// @param width Width of the box. + /// @param height Height of the box. + static std::shared_ptr create(int x, int y, int width, int height); + + /// @brief Update override. This does NOTHING! + void update(bool hasFocus) override {}; + + /// @brief Renders the dialog box to screen. + /// @param target Render target to render to. + /// @param hasFocus This is ignored. + void render(sdl::SharedTexture &target, bool hasFocus) override; + + /// @brief Sets the X and coords for the dialog box. + void set_xy(int x, int y); + + /// @brief Sets the width and height of the dialog. + void set_width_height(int width, int height); + + /// @brief Pass with the set functions to not change. + static inline constexpr int NO_SET = -1; + + private: + /// @brief X render coord. + int m_x{}; + + /// @brief Y render coord. + int m_y{}; + + /// @brief Width of the dialog. + int m_width{}; + + /// @brief Height of the dialog. + int m_height{}; + + /// @brief All instances shared this. + static inline sdl::SharedTexture sm_corners{}; + + /// @brief Initializes and loads the corners texture. + void initialize_static_members(); + }; +} diff --git a/include/ui/Element.hpp b/include/ui/Element.hpp index f4ed710..cb8b76d 100644 --- a/include/ui/Element.hpp +++ b/include/ui/Element.hpp @@ -20,6 +20,6 @@ namespace ui /// @brief Virtual render method. All derived classes must have this. /// @param target Target to render to. /// @param hasFocus Whether or not the containing state has focus. - virtual void render(SDL_Texture *target, bool hasFocus) = 0; + virtual void render(sdl::SharedTexture &target, bool hasFocus) = 0; }; } // namespace ui diff --git a/include/ui/IconMenu.hpp b/include/ui/IconMenu.hpp index 2dbfbcb..9dd1c63 100644 --- a/include/ui/IconMenu.hpp +++ b/include/ui/IconMenu.hpp @@ -1,10 +1,12 @@ #pragma once #include "ui/Menu.hpp" +#include + namespace ui { /// @brief This is a hacky derived class to use Menu's code with Icons instead. - class IconMenu : public ui::Menu + class IconMenu final : public ui::Menu { public: /// @brief Default constructor. @@ -19,20 +21,23 @@ namespace ui /// @brief Required destructor. ~IconMenu() {}; + std::shared_ptr create(int x, int y, int renderTargetHeight); + /// @brief Initializes the menu. /// @param x X coordinate to render the menu to. /// @param y Y coordinate to render the menu to. - /// @param renderTargetHeight Height of the render target to calculate how many options can be displayed at once. + /// @param renderTargetHeight Height of the render target to calculate how many options can be displayed at + /// once. void initialize(int x, int y, int renderTargetHeight); /// @brief Runs the update routine. /// @param hasFocus Whether or not the containing state has focus. - void update(bool hasFocus); + void update(bool hasFocus) override; /// @brief Runs the render routine. /// @param target Target to render to. /// @param hasFocus Whether or not the containing state has focus. - void render(SDL_Texture *target, bool hasFocus); + void render(sdl::SharedTexture &target, bool hasFocus) override; /// @brief Adds a new icon to the menu. /// @param newOption Icon to add. diff --git a/include/ui/Menu.hpp b/include/ui/Menu.hpp index ec9cd67..cc741d0 100644 --- a/include/ui/Menu.hpp +++ b/include/ui/Menu.hpp @@ -1,9 +1,11 @@ #pragma once #include "sdl.hpp" +#include "ui/BoundingBox.hpp" #include "ui/ColorMod.hpp" #include "ui/Element.hpp" #include "ui/TextScroll.hpp" +#include #include #include @@ -24,14 +26,16 @@ namespace ui /// @brief Required destructor. ~Menu() {}; + static std::shared_ptr create(int x, int y, int width, int fontSize, int renderTargetHeight); + /// @brief Runs the update routine. /// @param hasFocus Whether or not the calling state has focus. - void update(bool HasFocus); + void update(bool HasFocus) override; /// @brief Renders the menu. /// @param target Target to render to. /// @param hasFocus Whether or not the calling state has focus. - void render(SDL_Texture *target, bool hasFocus); + void render(sdl::SharedTexture &target, bool hasFocus) override; /// @brief Adds and option to the menu. /// @param newOption Option to add to menu. @@ -66,15 +70,15 @@ namespace ui /// @brief Currently selected option. int m_selected{}; - /// @brief Color mod for bounding box. - ui::ColorMod m_colorMod{}; - /// @brief Height of options in pixels. int m_optionHeight{}; /// @brief Target options are rendered to. sdl::SharedTexture m_optionTarget{}; + /// @brief Bounding box for the selected option. + std::shared_ptr m_boundingBox{}; + private: /// @brief This to preserve the original Y coordinate passed. double m_originalY{}; @@ -100,10 +104,16 @@ namespace ui /// @brief Maximum number of display options render target can show. int m_maxDisplayOptions{}; - /// @brief Text scroll for when the current option is too long to on screen. - ui::TextScroll m_optionScroll{}; - /// @brief Vector of options. std::vector m_options{}; + + /// @brief Text scroll for when the current option is too long to on screen. + std::shared_ptr m_optionScroll{}; + + void update_scroll_text(); + + void update_scrolling(); + + void handle_input(); }; } // namespace ui diff --git a/include/ui/PopMessage.hpp b/include/ui/PopMessage.hpp new file mode 100644 index 0000000..bd2e880 --- /dev/null +++ b/include/ui/PopMessage.hpp @@ -0,0 +1,73 @@ +#pragma once +#include "sys/Timer.hpp" +#include "ui/DialogBox.hpp" + +#include + +namespace ui +{ + class PopMessage + { + public: + /// @brief PopMessage constructor. + PopMessage(int ticks, std::string_view message); + + /// @brief Updates the width, target, and typing. + void update(double targetY); + + /// @brief Renders the dialog and text. + void render(); + + /// @brief Returns whether or not the message can be purged. + bool finished() const; + + private: + // Every message begins off screen. + static inline constexpr int PERMA_X = 20; + static inline constexpr double START_Y = 720; + static inline constexpr int START_WIDTH = 16; + static inline constexpr int PERMA_HEIGHT = 48; + + /// @brief Ticks to start timer with. + int m_ticks{}; + + /// @brief This stores the message for safe keeping. + std::string m_message{}; + + /// @brief The current, actual Y coord. + double m_y{}; + + /// @brief Current width; + int m_width{}; + + /// @brief Target width; + int m_targetWidth{}; + + /// @brief Stores whether or not the dialog is fully expanded. + bool m_expanded{}; + + /// @brief Returns whether or not the message has reached the end of its life. + bool m_finished{}; + + /// @brief The current offset of the substr. + int m_substrOffset{}; + + /// @brief Times when the message should be nuked. + sys::Timer m_displayTimer{}; + + /// @brief This times updates the end of the substr printed. + sys::Timer m_typeTimer{}; + + /// @brief Dialog used to render the background. + std::shared_ptr m_dialog{}; + + /// @brief Updates the Y Coord to match the target passed. + void update_y(double targetY); + + /// @brief Updates and expands the dialog width. + void update_width(); + + /// @brief Updates the current end offset of the text. + void update_text_offset(); + }; +} diff --git a/include/ui/PopMessageManager.hpp b/include/ui/PopMessageManager.hpp index 7e3b5f3..8163fd9 100644 --- a/include/ui/PopMessageManager.hpp +++ b/include/ui/PopMessageManager.hpp @@ -1,5 +1,7 @@ #pragma once #include "sys/sys.hpp" +#include "ui/DialogBox.hpp" +#include "ui/PopMessage.hpp" #include #include @@ -7,22 +9,7 @@ namespace ui { - // This is the actual struct containing data for a message. - typedef struct - { - // Y coordinate - double y{}; - // Target Y coordinate - double targetY{}; - // Width of the message. - size_t width{}; - // Message string. - std::string message{}; - // Timer. - sys::Timer timer{}; - } PopMessage; - - class PopMessageManager + class PopMessageManager final { public: // No copying. @@ -53,6 +40,7 @@ namespace ui static PopMessageManager manager; return manager; } + // The queue for processing. SDL can't handle things being rendered in multiple threads. std::vector> m_messageQueue{}; diff --git a/include/ui/SlideOutPanel.hpp b/include/ui/SlideOutPanel.hpp index 3b0a415..87b38e2 100644 --- a/include/ui/SlideOutPanel.hpp +++ b/include/ui/SlideOutPanel.hpp @@ -2,11 +2,12 @@ #include "sdl.hpp" #include "ui/Element.hpp" +#include #include namespace ui { - class SlideOutPanel : public ui::Element + class SlideOutPanel final : public ui::Element { public: /// @brief Enum for which side of the screen the panel slides from. @@ -24,14 +25,16 @@ namespace ui /// @brief Required destructor. ~SlideOutPanel() {}; + std::shared_ptr create(int width, SlideOutPanel::Side side); + /// @brief Runs the update routine. /// @param hasFocus Whether or not the calling state has focus. - void update(bool hasFocus); + void update(bool hasFocus) override; /// @brief Runs the render routine. /// @param target Target to render to. /// @param hasFocus Whether or the the calling state has focus. - void render(SDL_Texture *target, bool hasFocus); + void render(sdl::SharedTexture &target, bool hasFocus) override; /// @brief Clears the target to a semi-transparent black. To do: Maybe not hard coded color. void clear_target(); @@ -59,7 +62,7 @@ namespace ui /// @brief Returns a pointer to the render target of the panel. /// @return Raw SDL_Texture pointer to target. - SDL_Texture *get_target(); + sdl::SharedTexture &get_target(); private: /// @brief Bool for whether panel is fully open or not. @@ -83,9 +86,6 @@ namespace ui /// @brief Render target if panel. sdl::SharedTexture m_renderTarget{}; - /// @brief This is so I don't need to fetch the scaling every loop. - double m_scaling{}; - /// @brief Vector of elements. std::vector> m_elements{}; diff --git a/include/ui/TextScroll.hpp b/include/ui/TextScroll.hpp index 1cd3ed5..37f71de 100644 --- a/include/ui/TextScroll.hpp +++ b/include/ui/TextScroll.hpp @@ -35,6 +35,17 @@ namespace ui /// @brief Required destructor. ~TextScroll() {}; + /// @brief Creates and returns a new TextScroll. See constructor. + static std::shared_ptr create(std::string_view text, + int x, + int y, + int width, + int height, + int fontSize, + sdl::Color textColor, + sdl::Color clearColor, + bool center = true); + /// @brief Creates/sets the text and parameters for TextScroll. /// @param text Text to display/scroll. /// @param fontSize Font size to use when rendering. @@ -42,15 +53,24 @@ namespace ui /// @param y Y coordinate used to render text. /// @param center Whether or not text should be centered if it's not wide enough for scrolling. /// @param color Color to use to render text. - void create(std::string_view text, - int x, - int y, - int width, - int height, - int fontSize, - sdl::Color textColor, - sdl::Color clearColor, - bool center = true); + void initialize(std::string_view text, + int x, + int y, + int width, + int height, + int fontSize, + sdl::Color textColor, + sdl::Color clearColor, + bool center = true); + + /// @brief Runs the update routine. + /// @param hasFocus Whether or not the calling state has focus. + void update(bool hasFocus) override; + + /// @brief Runs the render routine. + /// @param target Target to render to. + /// @param hasFocus Whether or not the calling state has focus. + void render(sdl::SharedTexture &target, bool hasFocus) override; /// @brief Returns the current text being used for scrolling. std::string_view get_text() const; @@ -61,15 +81,6 @@ namespace ui /// @brief Allows setting of the X and Y render coordinates. void set_xy(int x, int y); - /// @brief Runs the update routine. - /// @param hasFocus Whether or not the calling state has focus. - void update(bool hasFocus); - - /// @brief Runs the render routine. - /// @param target Target to render to. - /// @param hasFocus Whether or not the calling state has focus. - void render(SDL_Texture *target, bool hasFocus); - private: /// @brief Text to display. std::string m_text{}; diff --git a/include/ui/TitleTile.hpp b/include/ui/TitleTile.hpp index 273b85d..133ac7c 100644 --- a/include/ui/TitleTile.hpp +++ b/include/ui/TitleTile.hpp @@ -4,7 +4,7 @@ namespace ui { /// @brief Tile for Titleview. - class TitleTile + class TitleTile final { public: /// @brief Constructor. @@ -20,7 +20,7 @@ namespace ui /// @param target Target to render to. /// @param x X coordinate to render to. /// @param y Y coordinate to render to. - void render(SDL_Texture *target, int x, int y); + void render(sdl::SharedTexture &target, int x, int y); /// @brief Resets the width and height of the tile. void reset(); diff --git a/include/ui/TitleView.hpp b/include/ui/TitleView.hpp index 070d7c0..8206bc0 100644 --- a/include/ui/TitleView.hpp +++ b/include/ui/TitleView.hpp @@ -1,6 +1,7 @@ #pragma once #include "data/data.hpp" #include "sdl.hpp" +#include "ui/BoundingBox.hpp" #include "ui/ColorMod.hpp" #include "ui/Element.hpp" #include "ui/TitleTile.hpp" @@ -10,7 +11,7 @@ namespace ui { /// @brief Presents a grid of icons to select a title from. - class TitleView : public ui::Element + class TitleView final : public ui::Element { public: /// @brief Creates a title view using passed user pointer. @@ -22,17 +23,20 @@ namespace ui /// @brief Runs the update routine. /// @param hasFocus Whether the calling state has focus. - void update(bool hasFocus); + void update(bool hasFocus) override; /// @brief Runs the render routine. /// @param target Target to render to. /// @param hasFocus Whether or not the calling state has focus. - void render(SDL_Texture *target, bool hasFocus); + void render(sdl::SharedTexture &target, bool hasFocus) override; /// @brief Returns index of the currently selected tile. /// @return Index of currently selected tile. int get_selected() const; + /// @brief Sets the currently selected item. + void set_selected(int selected); + /// @brief Forces a refresh of the view. void refresh(); @@ -61,10 +65,16 @@ namespace ui /// @brief Vector of selection tiles. std::vector m_titleTiles{}; + /// @brief Bounding box rendered around the selected title. + std::shared_ptr m_bounding{}; + + /// @brief Performs the input routine. void handle_input(); + /// @brief Performs the "scrolling" routine. void handle_scrolling(); + /// @brief Updates the tiles. void update_tiles(); }; } // namespace ui diff --git a/include/ui/render_functions.hpp b/include/ui/render_functions.hpp deleted file mode 100644 index e925401..0000000 --- a/include/ui/render_functions.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include "sdl.hpp" -#include "ui/ColorMod.hpp" - -// These are just functions to render generic parts of the UI. -namespace ui -{ - /// @brief Renders a dialog box - /// @param target Target to render to. - /// @param x X coordinate to render to. - /// @param y Y coordinate to render to. - /// @param width Width of dialog box in pixels. - /// @param height Height of dialog box in pixels. - void render_dialog_box(SDL_Texture *target, int x, int y, int width, int height); - - /// @brief Renders a bounding box. - /// @param target Target to render to. - /// @param x X coordinate to render to. - /// @param y Y coordinate to render to. - /// @param width Width of dialog box in pixels. - /// @param height Height of dialog box in pixels. - /// @param colorMod Color to multiply in rendering. - void render_bounding_box(SDL_Texture *target, int x, int y, int width, int height, const ui::ColorMod &colorMod); -} // namespace ui diff --git a/include/ui/ui.hpp b/include/ui/ui.hpp index cbbcdd8..ea55e48 100644 --- a/include/ui/ui.hpp +++ b/include/ui/ui.hpp @@ -1,5 +1,7 @@ #pragma once +#include "ui/BoundingBox.hpp" #include "ui/ColorMod.hpp" +#include "ui/DialogBox.hpp" #include "ui/Element.hpp" #include "ui/IconMenu.hpp" #include "ui/Menu.hpp" @@ -8,4 +10,3 @@ #include "ui/TextScroll.hpp" #include "ui/TitleTile.hpp" #include "ui/TitleView.hpp" -#include "ui/render_functions.hpp" diff --git a/romfs/Text/DE.json b/romfs/Text/DE.json index 257895a..3532827 100644 --- a/romfs/Text/DE.json +++ b/romfs/Text/DE.json @@ -1,42 +1,42 @@ { "BackupMenu": [ - "0: Neues Backup" + "0: Neuer Backup" ], "BackupMenuConfirmations": [ - "0: Sind Sie sicher, dass Sie #%s# wirklich überschreiben möchten?", - "1: Sind Sie sicher, dass Sie #%s# wirklich wiederherstellen möchten?", - "2: Sind Sie sicher, dass Sie #%s# wirklich löschen möchten?" + "0: Bist du sicher, dass du #%s# wirklich überschreiben möchtest?", + "1: Bist du sicher, dass du #%s# wirklich wiederherstellen möchtest?", + "2: Bist du sicher, dass du #%s# wirklich löschen möchtest?" ], "BackupMenuPops": [ - "0: Spieldaten sind leer!", + "0: Speicherstand ist leer!", "1: Backup ist leer!", - "2: Fehler beim Zurücksetzen der Spieldaten!", - "3: Fehler beim Öffnen der ZIP-Datei zum Lesen!", + "2: Fehler beim Zurücksetzen der Speicherstände!", + "3: Fehler beim Öffnen der ZIP‑Datei zum Lesen!", "4: Fehler beim Löschen des Backups!", "5: Fehler beim Erstellen des Backups!", "6: Schreiben ins System ist deaktiviert!", - "7: Kann ZIP zum Lesen nicht öffnen!", - "8: Fehler beim Schreiben der Speichermetadaten-Datei!", + "7: Kann ZIP nicht zum Lesen öffnen!", + "8: Fehler beim Schreiben der Metadaten‑Datei!", "9: Fehler beim Herunterladen der Datei!", "10: Fehler beim Hochladen der Datei!", - "11: Fehler bei der Verarbeitung der Speichermetadaten!", + "11: Fehler bei der Verarbeitung der Speicherstand‑Metadaten!", "12: Fehler beim Erstellen des Zielverzeichnisses!", - "13: Backup muss eine ZIP-Datei zum Hochladen sein!", - "14: Fehler beim Einbinden der Spieldaten!", - "15: Fehler beim Schließen der Spieldaten!" + "13: Backup muss eine ZIP‑Datei zum Hochladen sein!", + "14: Fehler beim Einbinden der Speicherstände!", + "15: Fehler beim Schließen der Speicherstände!" ], "BackupMenuStatus": [ - "0: Verarbeite Speichermetadaten-Datei..." + "0: Verarbeite Speicherstand‑Metadaten…" ], "ControlGuides": [ - "0: [A] Auswählen [Y] Alle Saves dumpen [X] Benutzeroptionen", - "1: [A] Auswählen [L] [R] Springen [Y] Favorit [X] Titeloptionen [B] Zurück", + "0: [A] Auswählen [Y] Alle Speicherdaten sichern [X] Benutzer‑Optionen", + "1: [A] Auswählen [L] [R] Springen [Y] Favorit [X] Titel‑Optionen [B] Zurück", "2: [A] Auswählen [Y] Wiederherstellen [X] Löschen [ZR] Hochladen [B] Schließen", "3: [A] Umschalten [X] Standardwerte [B] Zurück" ], "ExtrasMenu": [ "0: Daten neu initialisieren", - "1: SD zu SD Browser", + "1: SD‑zu‑SD‑Browser", "2: ProdInfoF", "3: Sicher", "4: System", @@ -45,61 +45,61 @@ ], "ExtrasPops": [ "0: Daten neu initialisiert!", - "1: Daten-Neuinitialisierung fehlgeschlagen!" + "1: Dateninitialisierung fehlgeschlagen!" ], "GeneralPops": [ "0: JKSV kann nicht beendet werden, während Aufgaben laufen!" ], "GoogleDriveStrings": [ - "0: Um fortzufahren, gehen Sie zu #%s# und geben Sie >%s> ein!", - "1: Erfolgreich bei Google Drive angemeldet!", + "0: Um fortzufahren, gehe zu #%s# und gib >%s> ein!", + "1: Anmeldung bei Google Drive erfolgreich!", "2: Anmeldung bei Google Drive fehlgeschlagen!" ], "HoldingStrings": [ "0: Halte [A]", "1: Halte weiterhin [A]", - "2: Fast geschafft! [A]" + "2: Fast da! [A]" ], "IOStatuses": [ - "0: Kopiere #%s#...", - "1: Komprimiere #%s# zu ZIP...", - "2: Dekomprimiere #%s# aus ZIP...", - "3: Lösche #%s#...", - "4: Lade #%s# herunter...", - "5: Lade #%s# zu Remote-Speicher hoch...", - "6: Aktualisiere #%s# auf Remote-Speicher..." + "0: Kopiere #%s#…", + "1: Komprimiere #%s# zu ZIP…", + "2: Dekomprimiere #%s# aus ZIP…", + "3: Lösche #%s#…", + "4: Lade #%s# herunter…", + "5: Lade #%s# in den Remote‑Speicher hoch…", + "6: Aktualisiere #%s# im Remote‑Speicher…" ], "IOPops": [ - "0: Fehler beim Schreiben der Daten auf das Gerät!" + "0: Fehler beim Commit der Daten auf das Gerät!" ], "KeyboardStrings": [ - "0: Gib einen neuen Backup-Namen ein.", - "1: Cache-Index eingeben.", - "2: Gib einen neuen Ausgabepfad für JKSV ein.", - "3: Prozess-ID zum Beenden eingeben.", - "4: System-Save-ID eingeben", + "0: Gib einen neuen Backup‑Namen ein.", + "1: Gib den Cache‑Index ein.", + "2: Gib einen neuen Ausgabe‑Pfad für JKSV ein.", + "3: Gib die Prozess‑ID ein, die beendet werden soll.", + "4: Gib eine System‑Speicherstand‑ID ein.", "5: Gib einen neuen Namen für das Zielobjekt ein.", "6: Gib einen Namen für den neuen Ordner ein.", - "7: Gib einen neuen Ausgabeverzeichnisnamen für %s ein.", - "8: Gib an, wie viel erweitert werden soll (in MB)." + "7: Gib einen neuen Ausgabefolder‑Namen für %s ein.", + "8: Gib an, um wie viel (in MB) erweitert werden soll." ], "MainMenuConfs": [ - "0: Sind Sie sicher, dass Sie die Spieldaten für alle Benutzer auf diesem System sichern möchten? Dies kann *extrem* lange dauern!" + "0: Bist du sicher, dass du die Speicherdaten für jeden Benutzer dieses Systems sichern willst? Das kann *extrem* lange dauern!" ], "MainMenuPops": [ - "0: `%s` hat keine Spieldaten!" + "0: `%s` hat keine Speicherdaten!" ], "OnOff": [ "0: Aus", - "1: >An<" + "1: >Ein>" ], "RemotePops": [ "0: Keine Internetverbindung verfügbar!" ], "SaveCreatePops": [ - "0: Spieldaten für #%s# erstellt!", - "1: Fehler beim Erstellen der Spieldaten!", - "2: Fehler beim Löschen der Spieldaten!" + "0: Speicherdaten erstellt für #%s#!", + "1: Fehler beim Erstellen der Speicherdaten!", + "2: Fehler beim Löschen der Speicherdaten!" ], "SaveDataTypes": [ "0: System", @@ -108,122 +108,125 @@ "3: Gerät", "4: Temporär", "5: Cache", - "6: System BCAT" + "6: System‑BCAT" ], "SettingsDescriptions": [ - "0: Legt das Arbeitsverzeichnis für JKSV fest. Der Standardwert ist `sdmc:/JKSV`.", + "0: Setzt das Arbeitsverzeichnis für JKSV. Der Standardwert ist `sdmc:/JKSV`.", "1: Ermöglicht das Entfernen von Titeln aus der Blacklist.", - "2: Schließt Gerätespeicherstände oder geteilte Saves bei Benutzern ein.", - "3: Erstellt automatisch ein Backup beim Wiederherstellen eines anderen.", - "4: Benennt Backups automatisch und überspringt die Tastatur.", - "5: Lädt Backups automatisch auf Remote hoch und löscht sie lokal.", - "6: Verwendet immer Anwendungs-IDs für Exportordnernamen.", - "7: Ob das Halten von [A] für drei Sekunden zum Löschen von Backups erforderlich ist.", - "8: Ob das Halten von [A] für drei Sekunden zum Wiederherstellen von Backups erforderlich ist.", - "9: Ob das Halten von [A] für drei Sekunden zum Überschreiben von Backups erforderlich ist.", - "10: Zeigt nur Speicherdaten an, die JKSV erfolgreich öffnen kann.", - "11: Zeigt System-Saves an, die eine Konten-ID besitzen.", - "12: Ermöglicht das Wiederherstellen von Systemsaves und Schreiben in NAND-Partitionen.", - "13: Exportiert Speicherdaten als ZIP-Archive statt als entpackte Ordner.", - "14: Kompressions- oder Deflate-Level beim Schreiben in ZIP. Standard ist 6. Niedrigere Werte sind schneller, bieten aber weniger Kompression. Null ist Speichern ohne Kompression.", - "15: Steuert, wie Titel sortiert und angezeigt werden.", - "16: Zeigt Titel als Textmenüs wie das ursprüngliche JKSM auf 3DS statt als Icon-Gitter.", - "17: Erzwingt Englisch als Sprache statt der erkannten Systemsprache.", - "18: Verschiebt gelöschte Backups in den _TRASH_-Ordner statt sie endgültig zu löschen.", - "19: Legt die Geschwindigkeit fest, mit der Übergänge und Animationen ablaufen. Niedriger ist schneller." + "2: Bezieht Geräte‑ oder geteilte Speicherstände mit Benutzern ein.", + "3: Erstellt beim Wiederherstellen automatisch ein Backup.", + "4: Auto‑Benennung von Backups und Überspringen der Tastatur.", + "5: Lädt Backups automatisch in die Cloud hoch und löscht sie lokal.", + "6: Verwendet immer Application‑IDs für Exportordner‑Namen.", + "7: Ob [A] für drei Sekunden gehalten werden muss, um Backups zu löschen.", + "8: Ob [A] für drei Sekunden gehalten werden muss, um Backups wiederherzustellen.", + "9: Ob [A] für drei Sekunden gehalten werden muss, um Backups zu überschreiben.", + "10: Zeigt nur Speicherstände, die JKSV öffnen kann.", + "11: Zeigt System‑Saves mit Benutzerkonto‑ID.", + "12: Aktiviert das Wiederherstellen von System‑Saves und das Schreiben in NAND‑Partitionen.", + "13: Exportiert Speicherdaten als ZIP‑Archive statt entpackter Ordner.", + "14: Kompressionsniveau für ZIP. Standard ist 6. Niedrigere Werte sind schneller, bieten aber weniger Kompression. 0 bedeutet speichern ohne Kompression.", + "15: Steuerung, wie Titel sortiert und angezeigt werden.", + "16: Zeigt Titel als Textmenüs wie im originalen JKSM auf der 3DS statt als Icon‑Raster.", + "17: Erzwingt Englisch als Sprache statt der Systemsprache.", + "18: Verschiebt gelöschte Backups in den _TRASH_‑Ordner statt sie endgültig zu löschen.", + "19: Legt die Geschwindigkeit der Transitionen und Animationen fest. Niedrigere Werte sind schneller." ], "SettingsMenu": [ - "0: JKSV-Ausgabeverzeichnis festlegen.", + "0: Setze JKSV Ausgabeordner.", "1: Blacklist bearbeiten", - "2: Gerätesaves mit Benutzern einbeziehen: %s", - "3: Automatisches Backup bei Wiederherstellung: %s", - "4: Backups automatisch benennen: %s", - "5: Backups automatisch auf Remote hochladen: %s", - "6: Immer Anwendungs-IDs verwenden: %s", + "2: Geräte‑Saves mit Nutzern einbeziehen: %s", + "3: Auto‑Backup beim Wiederherstellen: %s", + "4: Auto‑Benennung von Backups: %s", + "5: Automatisches Hochladen der Backups: %s", + "6: Immer Application‑IDs verwenden: %s", "7: Halten zum Löschen von Backups: %s", "8: Halten zum Wiederherstellen von Backups: %s", "9: Halten zum Überschreiben von Backups: %s", - "10: Nur mountbare Titel auflisten: %s", - "11: Konto-System-Saves anzeigen: %s", - "12: Schreiben von System-Saves und NAND aktivieren: %s", - "13: Speicherdaten als ZIP exportieren: %s", - "14: ZIP-Kompressionslevel: %u", - "15: Titel-Sortierung: %s", - "16: Textmenü (JKSM)-Modus: %s", + "10: Nur mountbare Titel anzeigen: %s", + "11: Zeige System‑Saves mit Konto‑ID: %s", + "12: Enable writing to system saves and NAND: %s", + "13: Exporte Saves zu ZIP: %s", + "14: ZIP‑Kompressionsniveau: %u", + "15: Titel‑Sortierung: %s", + "16: Textmenü (JKSM) Modus: %s", "17: Englisch erzwingen: %s", "18: Papierkorb aktivieren: %s", "19: Animationsskalierung: %.02f" ], + "SettingsPops": [ + "0: Blacklist ist leer!" + ], "SortTypes": [ "0: Alphabetisch", "1: Meist gespielt", "2: Zuletzt gespielt" ], "TitleInfo": [ - "0: App-ID: %016lX", - "1: Save-ID: %016lx", - "2: Erstes Spielen: %x - %X", - "3: Letztes Spielen: %x - %X", + "0: App‑ID: %016lX", + "1: Save‑ID: %016lx", + "2: Erstes Spielen: %x – %X", + "3: Zuletzt gespielt: %x – %X", "4: Spielzeit: %02d:%02d:%02d", "5: Starts: %i", - "6: Speicherart: %s" + "6: Save‑Typ: %s" ], "TitleOptionConfirmations": [ - "0: Sind Sie sicher, dass Sie #%s# zur Blacklist hinzufügen möchten? Danach erscheint der Titel nicht mehr in Listen oder Auswahlen.", - "1: Sind Sie sicher, dass Sie alle aktuellen Backups für #%s# löschen möchten? *Dies kann nicht rückgängig gemacht werden!*", - "2: Sind Sie sicher, dass Sie die Spieldaten für #%s# zurücksetzen möchten? *Dadurch werden die aktuellen Spieldaten gelöscht, als ob das Spiel nie gestartet wurde!*", - "3: Sind Sie sicher, dass Sie die Spieldaten von `%s` für #%s# löschen möchten? *Dies wird dauerhaft vom System gelöscht.*" + "0: Bist du sicher, dass du #%s# zur Blacklist hinzufügen möchtest? Danach erscheint es nicht mehr in Titellisten.", + "1: Bist du sicher, dass du alle aktuellen Speicher‑Backups für #%s# löschen möchtest? *Das kann nicht rückgängig gemacht werden!*", + "2: Bist du sicher, dass du die Speicherdaten für #%s# zurücksetzen möchtest? *Das löscht die aktuellen Speicherdaten wie bei einem Neuanfang!*", + "3: Bist du sicher, dass du `%s`’s Speicherdaten für #%s# löschen möchtest? *Das wird dauerhaft vom System entfernt.*" ], "TitleOptionPops": [ "0: Alle Backups für #%s# gelöscht!", "1: Löschen aller Backups fehlgeschlagen!", - "2: Fehler beim Zurücksetzen der Spieldaten!", - "3: Spieldaten erfolgreich zurückgesetzt!", - "4: SVI-Datei erfolgreich exportiert!", - "5: Fehler beim Exportieren der SVI-Datei!", - "6: Diese Option ist für System-Saves nicht verfügbar!", + "2: Fehler beim Zurücksetzen der Speicherdaten!", + "3: Speicherdaten erfolgreich zurückgesetzt!", + "4: SVI‑Datei erfolgreich exportiert!", + "5: Fehler beim Export der SVI‑Datei!", + "6: Diese Option ist für System‑Saves nicht verfügbar!", "7: Pfad konnte nicht bereinigt werden!", - "8: Ausgabeverzeichnis auf #%s# gesetzt.", - "9: Fehler beim Setzen des neuen Ausgabepfads!", - "10: Spieldaten erfolgreich erweitert!", - "11: Erweiterung der Spieldaten fehlgeschlagen!" + "8: Ausgabefolder gesetzt auf #%s#.", + "9: Fehler beim Festlegen des neuen Ausgabepfads!", + "10: Speicherdaten erfolgreich erweitert!", + "11: Erweiterung der Speicherdaten ist fehlgeschlagen!" ], "TitleOptionStatus": [ "0: Lösche alle Backups für #%s#.", - "1: Setze Spieldaten für #%s# zurück.", - "2: Lösche Spieldaten von #%s# für `%s`...", - "3: Erweitere Spieldaten von #%s# für `%s`..." + "1: Setze Speicherdaten für #%s# zurück.", + "2: Lösche `%s`’s Speicherdaten für #%s#…", + "3: Erweitere `%s`’s Speicherdaten für #%s#…" ], "TitleOptions": [ "0: Informationen", - "1: Titel auf Blacklist setzen", - "2: Ausgabeverzeichnis ändern", - "3: Im Dateimodus öffnen", + "1: Titel zur Blacklist hinzufügen", + "2: Ausgabeordner ändern", + "3: Datei‑Modus öffnen", "4: Alle lokalen Backups löschen", - "5: Alle Remote-Backups löschen", - "6: Spieldaten zurücksetzen.", - "7: Spieldaten vom System löschen", - "8: Spieldaten erweitern", - "9: SVI-Datei exportieren" + "5: Alle entfernten Backups löschen", + "6: Speicherdaten zurücksetzen", + "7: Speicherdaten vom System löschen", + "8: Speicherdaten erweitern", + "9: SVI‑Datei exportieren" ], "TranslationInfo": [ "0: Übersetzt von: %s", "1: NULL" ], "UserOptionConfirmations": [ - "0: Sind Sie sicher, dass Sie alle Spieldaten für `%s` sichern möchten? Das kann eine Weile dauern.", - "1: Sind Sie sicher, dass Sie für alle auf Ihrem System gefundenen Titel Spieldaten erstellen möchten? Das kann eine Weile dauern.", - "2: Sind Sie sicher, dass Sie alle Spieldaten für `%s` löschen möchten? Dies ist *ENDGÜLTIG* und kann nicht rückgängig gemacht werden." + "0: Bist du sicher, dass du alle Speicherdaten für `%s` sichern möchtest? Das kann eine Weile dauern.", + "1: Bist du sicher, dass du für `%s` Speicherdaten für alle auf dem System gefundenen Titel erstellen möchtest? Das kann eine Weile dauern.", + "2: Bist du sicher, dass du alle Speicherdaten für `%s` löschen möchtest? Das ist *ENDGÜLTIG* und kann nicht rückgängig gemacht werden." ], "UserOptionStatus": [ - "0: Erstelle Spieldaten für #%s#...", - "1: Lösche Spieldaten für #%s#..." + "0: Erstelle Speicherdaten für #%s#…", + "1: Lösche Speicherdaten für #%s#…" ], "UserOptions": [ - "0: Alle für `%s` dumpen", - "1: Spieldaten erstellen für `%s`", - "2: Alle Spieldaten erstellen für `%s`", - "3: Alle Spieldaten löschen für `%s`" + "0: Alles sichern für `%s`", + "1: Speicherdaten erstellen für `%s`", + "2: Alle Speicherdaten für `%s` erstellen", + "3: Alle Speicherdaten für `%s` löschen" ], "WebDavStrings": [ "0: WebDav erfolgreich gestartet!", diff --git a/romfs/Text/ENGB.json b/romfs/Text/ENGB.json index 77664be..6852815 100644 --- a/romfs/Text/ENGB.json +++ b/romfs/Text/ENGB.json @@ -1,236 +1,239 @@ { "BackupMenu": [ - "0: Jolly Good! Create a New Backup" + "0: New Backup" ], "BackupMenuConfirmations": [ - "0: Pray, are you quite certain you wish to overwrite #%s#, old chap?", - "1: Are you absolutely sure you desire to restore #%s#, dear fellow?", - "2: Do you truly wish to delete #%s#, my good man?" + "0: Are you sure you really want to overwrite #%s#?", + "1: Are you sure you really want to restore #%s#?", + "2: Are you sure you really want to delete #%s#?" ], "BackupMenuPops": [ - "0: Egad! The save data is utterly empty!", - "1: Blimey! The backup appears to be empty!", - "2: Dash it! Error resetting the save data!", - "3: Tut tut! Could not open the ZIP file for reading!", - "4: Confound it! Error occurred whilst deleting the backup!", - "5: Alas! Error whilst creating the backup!", - "6: Hold your horses! Writing to the system is presently disabled!", - "7: Crikey! Unable to open ZIP for reading!", - "8: Blast! Error writing the save meta data file!", - "9: Gadzooks! Error encountered whilst downloading the file!", - "10: Pip pip! Error uploading the file!", - "11: By Jove! Error processing the save data meta!", - "12: Egad! Error creating the target directory!", - "13: Good heavens! Backup must be a proper ZIP to upload!", - "14: Fiddlesticks! Error mounting the save data!", - "15: Balderdash! Error closing the save data!" + "0: Save data is empty!", + "1: Backup is empty!", + "2: Error resetting save data!", + "3: Error opening ZIP file for reading!", + "4: Error occurred deleting backup!", + "5: Error creating backup!", + "6: Writing to system is disabled!", + "7: Unable to open zip for reading!", + "8: Error writing save meta data file!", + "9: Error downloading file!", + "10: Error uploading file!", + "11: Error processing save data meta!", + "12: Error creating target directory!", + "13: Backup must be a zip to upload!", + "14: Error mounting save data!", + "15: Error closing save data!" ], "BackupMenuStatus": [ - "0: Processing the save data meta file posthaste..." + "0: Processing save data meta file…" ], "ControlGuides": [ - "0: [A] Select [Y] Dump All Saves [X] User Options, old bean", - "1: [A] Select [L] [R] Jump [Y] Favourite [X] Title Options [B] Back, chap", - "2: [A] Select [Y] Restore [X] Delete [ZR] Upload [B] Close, tally-ho!", - "3: [A] Toggle [X] Defaults [B] Back, cheerio!" + "0: [A] Select [Y] Dump All Saves [X] User Options", + "1: [A] Select [L] [R] Jump [Y] Favourite [X] Title Options [B] Back", + "2: [A] Select [Y] Restore [X] Delete [ZR] Upload [B] Close", + "3: [A] Toggle [X] Defaults [B] Back" ], "ExtrasMenu": [ - "0: Reinitialise Data, if you please", - "1: SD to SD Browser, old sport", - "2: ProdInfoF, dash it all", - "3: Safe and Sound", - "4: System Settings, guv’nor", - "5: User Preferences, pip pip", - "6: Terminate Process, posthaste" + "0: Reinitialise Data", + "1: SD to SD Browser", + "2: ProdInfoF", + "3: Safe", + "4: System", + "5: User", + "6: Terminate Process" ], "ExtrasPops": [ - "0: Data reinitialised with splendid success!", - "1: Data reinitialisation has regrettably failed!" + "0: Data reinitialised!", + "1: Data reinitialisation failed!" ], "GeneralPops": [ - "0: Unable to exit JKSV whilst important tasks are still underway, old chap!" + "0: Unable to exit JKSV while tasks are running!" ], "GoogleDriveStrings": [ - "0: To continue, kindly pop over to #%s# and enter >%s>, if you would be so kind!", - "1: Splendid! Successfully signed in to Google Drive!", - "2: Oh dear! Google Drive sign in has failed!" + "0: To continue, go to #%s# and enter >%s>!", + "1: Successfully signed in to Google Drive!", + "2: Google Drive sign‑in failed!" ], "HoldingStrings": [ - "0: Hold [A], steady now", - "1: Keep holding [A], don't be shy!", - "2: Nearly there! Hold on tight [A]!" + "0: Hold [A]", + "1: Keep Holding [A]", + "2: Almost There! [A]" ], "IOStatuses": [ - "0: Copying #%s#... pip pip!", - "1: Compressing #%s# to a smashing ZIP...", - "2: Decompressing #%s# from jolly good ZIP...", - "3: Deleting #%s#... ta-ta!", - "4: Downloading #%s#... tally-ho!", - "5: Uploading #%s# to the remote storage, posthaste...", - "6: Updating #%s# on the remote storage, old bean..." + "0: Copying #%s#…", + "1: Compressing #%s# to ZIP…", + "2: Decompressing #%s# from ZIP…", + "3: Deleting #%s#…", + "4: Downloading #%s#…", + "5: Uploading #%s# to remote storage…", + "6: Updating #%s# on remote storage…" ], "IOPops": [ - "0: Confound it! Error committing data to the device!" + "0: Error committing data to device!" ], "KeyboardStrings": [ - "0: Please enter a new backup name, if you please.", - "1: Enter the cache index, chap.", - "2: Kindly enter a new output path for JKSV.", - "3: Enter the process ID to terminate, good sir.", - "4: Enter a system save ID, if you would be so kind.", - "5: Enter a new name for the target item, old sport.", - "6: Enter a name for the new folder, tally-ho!", - "7: Enter a new output folder name for %s, pip pip!", - "8: Enter how much to expand (in MB), posthaste." + "0: Enter a new backup name.", + "1: Enter cache index.", + "2: Enter a new output path for JKSV.", + "3: Enter process ID to terminate.", + "4: Enter a system save ID.", + "5: Enter a new name for the target item.", + "6: Enter a name for the new folder.", + "7: Enter a new output folder name for %s.", + "8: Enter how much to expand (in MB)." ], "MainMenuConfs": [ - "0: Are you quite sure you want to backup the save data for every user on this fine system? This may take an *awfully* long time!" + "0: Are you sure you want to back up the save data for every user on this system? This can take an *extremely* long time!" ], "MainMenuPops": [ - "0: `%s` has no save data, old chap!" + "0: `%s` has no save data!" ], "OnOff": [ - "0: Off, guv’nor", - "1: >On<, jolly good!" + "0: Off", + "1: >On>" ], "RemotePops": [ - "0: No internet connection available, dash it all!" + "0: No internet connection available!" ], "SaveCreatePops": [ - "0: Save data created for #%s#! Bravo!", - "1: Error creating save data! Blast!", - "2: Error deleting save data! Tut tut!" + "0: Save data created for #%s#!", + "1: Error creating save data!", + "2: Error deleting save data!" ], "SaveDataTypes": [ - "0: System, old bean", - "1: Account, tally-ho", - "2: BCAT, guv’nor", - "3: Device, pip pip", - "4: Temporary, dash it", - "5: Cache, old sport", - "6: System BCAT, jolly good" + "0: System", + "1: Account", + "2: BCAT", + "3: Device", + "4: Temporary", + "5: Cache", + "6: System BCAT" ], "SettingsDescriptions": [ - "0: Sets the working directory for JKSV. Default is `sdmc:/JKSV`, what what.", - "1: Allows you to remove titles from the blacklist, tally-ho.", - "2: Includes device or shared saves with users, old chap.", - "3: Creates a backup automatically when restoring another, pip pip.", - "4: Auto-names backups and skips the keyboard, dash it all.", - "5: Automatically uploads backups to remote and deletes them locally, smashing.", - "6: Always uses Application IDs for export folder names, guv’nor.", - "7: Whether holding [A] for three seconds is needed to delete backups, old bean.", - "8: Whether holding [A] for three seconds is needed to restore backups, cheerio.", - "9: Whether holding [A] for three seconds is needed to overwrite backups, tally-ho.", - "10: Only shows save data JKSV can successfully open, old sport.", - "11: Shows system saves that have an account ID tied to them, pip pip.", - "12: Enables restoring system saves and writing to NAND partitions, dash it.", - "13: Exports save data to ZIP archives instead of unpacked folders, jolly good.", - "14: Compression or deflate level for ZIP writing. Default 6. Lower is faster but less compression. Zero means store, no compression, old chap.", - "15: Controls how titles are sorted and displayed, what what.", - "16: Displays titles as text menus like original JKSM on 3DS, rather smashing.", - "17: Forces English language instead of detected system language, guv’nor.", - "18: Moves deleted backups to the _TRASH_ folder instead of permanent deletion, old bean.", - "19: Sets transition and animation speed. Lower is quicker, pip pip." + "0: Sets the working directory for JKSV. The default is `sdmc:/JKSV`.", + "1: Allows you to remove titles from the blacklist.", + "2: Includes device or shared saves with users.", + "3: Creates a backup automatically when restoring another.", + "4: Auto‑names backups and skips the keyboard.", + "5: Automatically uploads backups to remote storage and deletes them locally.", + "6: Always uses Application IDs for export folder names.", + "7: Whether holding [A] for three seconds is required to delete backups.", + "8: Whether holding [A] for three seconds is required to restore backups.", + "9: Whether holding [A] for three seconds is required to overwrite backups.", + "10: Only shows save data JKSV can successfully open.", + "11: Shows system saves with an account ID.", + "12: Enables restoring system saves and writing to NAND partitions.", + "13: Exports save data to ZIP archives instead of unpacked folders.", + "14: Compression level for ZIP used when writing. Default is 6. Lower values are faster but offer less compression. Zero means store (no compression).", + "15: Controls how titles are sorted and displayed.", + "16: Displays titles as text menus like the original JKSM on 3DS instead of icon grids.", + "17: Forces English to be used instead of the detected system language.", + "18: Moves deleted backups to the _TRASH_ folder instead of permanently deleting them.", + "19: Sets the speed of transitions and animations. Lower is faster." ], "SettingsMenu": [ - "0: Set JKSV output folder, if you please.", - "1: Edit Blacklist, old sport", - "2: Include Device Saves with users: %s, tally-ho.", - "3: Auto-backup on restore: %s, what what.", - "4: Auto-name backups: %s, jolly good.", - "5: Auto-upload backups to remote storage: %s, pip pip.", - "6: Always use Application IDs: %s, guv’nor.", - "7: Hold to delete backups: %s, dash it all.", - "8: Hold to restore backups: %s, old bean.", - "9: Hold to overwrite backups: %s, cheerio.", - "10: Only list mountable titles: %s, old chap.", - "11: Show account system saves: %s, tally-ho.", - "12: Enable writing to system saves and NAND: %s, smashing.", - "13: Export saves to ZIP: %s, what what.", - "14: Zip compression level: %u, pip pip.", - "15: Title sort type: %s, guv’nor.", - "16: Text menu (JKSM) mode: %s, jolly good.", - "17: Force English: %s, old bean.", - "18: Enable trash bin: %s, tally-ho.", - "19: Animation scaling: %.02f, dash it." + "0: Set JKSV output folder.", + "1: Edit Blacklist", + "2: Include Device Saves with users: %s", + "3: Auto‑backup on restore: %s", + "4: Auto‑name backups: %s", + "5: Auto‑upload backups to remote storage: %s", + "6: Always use Application IDs: %s", + "7: Hold to delete backups: %s", + "8: Hold to restore backups: %s", + "9: Hold to overwrite backups: %s", + "10: Only list mountable titles: %s", + "11: Show account system saves: %s", + "12: Enable writing to system saves and NAND: %s", + "13: Export saves to ZIP: %s", + "14: ZIP compression level: %u", + "15: Title sort type: %s", + "16: Text menu (JKSM) mode: %s", + "17: Force English: %s", + "18: Enable trash bin: %s", + "19: Animation scaling: %.02f" + ], + "SettingsPops": [ + "0: Blacklist is empty!" ], "SortTypes": [ - "0: Alphabetically, old sport", - "1: Most Played, tally-ho", - "2: Last Played, what what" + "0: Alphabetically", + "1: Most Played", + "2: Last Played" ], "TitleInfo": [ - "0: App ID: %016lX, guv’nor", - "1: Save ID: %016lx, pip pip", - "2: First Played: %x - %X, old bean", - "3: Last Played: %x - %X, jolly good", - "4: Play Time: %02d:%02d:%02d, dash it", - "5: Launches: %i, tally-ho", - "6: Save Type: %s, old chap" + "0: App ID: %016lX", + "1: Save ID: %016lx", + "2: First Played: %x – %X", + "3: Last Played: %x – %X", + "4: Play Time: %02d:%02d:%02d", + "5: Launches: %i", + "6: Save Type: %s" ], "TitleOptionConfirmations": [ - "0: Are you sure you wish to add #%s# to your blacklist? Once done, it shall not appear in any list, old chap.", - "1: Are you certain you wish to delete all current save backups for #%s#? *This cannot be undone, dash it!*", - "2: Are you sure you want to reset the save data for #%s#? *This will delete the current save data as if it were never run, old bean!*", - "3: Are you quite sure you want to delete `%s`'s save data for #%s#? *This is permanent, tally-ho!*" + "0: Are you sure you want to add #%s# to your blacklist? Once you do, it will no longer appear in any title lists.", + "1: Are you sure you’d like to delete all current save backups for #%s#? *This cannot be undone!*", + "2: Are you sure you want to reset the save data for #%s#? *This will delete the current save data as if it were never run!*", + "3: Are you sure you want to delete `%s`’s save data for #%s#? *This will permanently remove it from the system.*" ], "TitleOptionPops": [ - "0: All backups deleted for #%s#! Bravo!", - "1: Failed to delete all backups! Blast!", - "2: Error resetting save data! Tut tut!", - "3: Save data successfully reset! Jolly good!", - "4: SVI file exported successfully! Pip pip!", - "5: Error exporting SVI file! Dash it!", - "6: This option is unavailable for system saves, old sport!", - "7: Could not sanitize path for use, confound it!", - "8: Output folder set to #%s#, smashing!", - "9: Error setting new output path! Blast!", - "10: Save data successfully extended! Bravo!", - "11: Save data extension failed! Tut tut!" + "0: All backups deleted for #%s#!", + "1: Failed to delete all backups!", + "2: Error resetting save data!", + "3: Save data successfully reset!", + "4: SVI file exported successfully!", + "5: Error exporting SVI file!", + "6: This option is unavailable for system saves!", + "7: Could not sanitise path for use!", + "8: Output folder set to #%s#.", + "9: Error setting new output path!", + "10: Save data successfully extended!", + "11: Save data extension failed!" ], "TitleOptionStatus": [ - "0: Deleting all backups for #%s#, old bean.", - "1: Resetting save data for #%s#, tally-ho.", - "2: Deleting #%s#'s save data for `%s`... jolly good.", - "3: Extending `%s`'s save data for #%s#... pip pip." + "0: Deleting all backups for #%s#.", + "1: Resetting save data for #%s#.", + "2: Deleting `%s`’s save data for #%s#…", + "3: Extending `%s`’s save data for #%s#…" ], "TitleOptions": [ - "0: Information, old sport", - "1: Blacklist Title, guv’nor", - "2: Change Output folder, dash it", - "3: Open in File Mode, tally-ho", - "4: Delete all local backups, old chap", - "5: Delete all remote backups, pip pip", - "6: Reset save data, what what.", - "7: Delete save data from system, old bean", - "8: Extend save data, smashing", - "9: Export SVI file, cheerio" + "0: Information", + "1: Add title to blacklist", + "2: Change output folder", + "3: Open in file mode", + "4: Delete all local backups", + "5: Delete all remote backups", + "6: Reset save data", + "7: Delete save data from system", + "8: Extend save data", + "9: Export SVI file" ], "TranslationInfo": [ - "0: Translated by: %s, pip pip", - "1: NULL, dash it" + "0: Translated by: %s", + "1: NULL" ], "UserOptionConfirmations": [ - "0: Are you sure you wish to backup all save data for `%s`? This may take a jolly long while.", - "1: Are you certain you wish to create save data for all titles found on your system for `%s`? This may take a spot of time.", - "2: Are you quite sure you want to delete all save data for `%s`? This is *PERMANENT* and simply cannot be undone!" + "0: Are you sure you want to back up the save data for every title found for `%s`? This can take a while.", + "1: Are you sure you want to create save data for all titles found on your system for `%s`? This can take a while.", + "2: Are you sure you want to delete all the save data for `%s`? This is *PERMANENT* and can’t be undone." ], "UserOptionStatus": [ - "0: Creating save data for #%s#... tally-ho!", - "1: Deleting save data for #%s#... pip pip!" + "0: Creating save data for #%s#…", + "1: Deleting save data for #%s#…" ], "UserOptions": [ - "0: Dump all for `%s`, old sport", - "1: Create Save Data for `%s`, guv’nor", - "2: Create All Save Data for `%s`, what what", - "3: Delete All Save Data for `%s`, dash it" + "0: Dump all for `%s`", + "1: Create save data for `%s`", + "2: Create all save data for `%s`", + "3: Delete all save data for `%s`" ], "WebDavStrings": [ - "0: WebDav successfully started! Jolly good!", - "1: WebDav failed! Tut tut!" + "0: WebDav successfully started!", + "1: WebDav failed!" ], "YesNo": [ - "0: Yes [A], old bean", - "1: No [B], dash it" + "0: Yes [A]", + "1: No [B]" ] } diff --git a/romfs/Text/ENUS.json b/romfs/Text/ENUS.json index 4bc0254..006572e 100644 --- a/romfs/Text/ENUS.json +++ b/romfs/Text/ENUS.json @@ -154,6 +154,9 @@ "18: Enable trash bin: %s", "19: Animation scaling: %.02f" ], + "SettingsPops": [ + "0: Blacklist is empty!" + ], "SortTypes": [ "0: Alphabetically", "1: Most Played", diff --git a/romfs/Text/ES.json b/romfs/Text/ES.json index 0697026..59e70b5 100644 --- a/romfs/Text/ES.json +++ b/romfs/Text/ES.json @@ -1,11 +1,11 @@ { "BackupMenu": [ - "0: Nueva copia de seguridad" + "0: Copia de seguridad nueva" ], "BackupMenuConfirmations": [ - "0: ¿Estás seguro de que quieres sobrescribir #%s#?", - "1: ¿Estás seguro de que quieres restaurar #%s#?", - "2: ¿Estás seguro de que quieres eliminar #%s#?" + "0: ¿Seguro que deseas sobrescribir #%s#?", + "1: ¿Seguro que deseas restaurar #%s#?", + "2: ¿Seguro que deseas eliminar #%s#?" ], "BackupMenuPops": [ "0: ¡Los datos guardados están vacíos!", @@ -16,23 +16,23 @@ "5: ¡Error al crear la copia de seguridad!", "6: ¡La escritura en el sistema está deshabilitada!", "7: ¡No se puede abrir el ZIP para lectura!", - "8: ¡Error al escribir el archivo de metadatos guardados!", + "8: ¡Error al escribir el archivo de metadatos de guardado!", "9: ¡Error al descargar el archivo!", "10: ¡Error al subir el archivo!", - "11: ¡Error al procesar los metadatos de los datos guardados!", - "12: ¡Error al crear el directorio destino!", + "11: ¡Error al procesar los metadatos del guardado!", + "12: ¡Error al crear el directorio de destino!", "13: ¡La copia de seguridad debe ser un ZIP para subirla!", "14: ¡Error al montar los datos guardados!", "15: ¡Error al cerrar los datos guardados!" ], "BackupMenuStatus": [ - "0: Procesando el archivo de metadatos de los datos guardados..." + "0: Procesando archivo de metadatos de guardado…" ], "ControlGuides": [ - "0: [A] Seleccionar [Y] Volcar todos los guardados [X] Opciones de usuario", + "0: [A] Seleccionar [Y] Volcar todas las partidas [X] Opciones de usuario", "1: [A] Seleccionar [L] [R] Saltar [Y] Favorito [X] Opciones de título [B] Atrás", - "2: [A] Seleccionar [Y] Restaurar [X] Eliminar [ZR] Subir [B] Cerrar", - "3: [A] Alternar [X] Predeterminado [B] Atrás" + "2: [A] Seleccionar [Y] Restaurar [X] Borrar [ZR] Subir [B] Cerrar", + "3: [A] Alternar [X] Valores predeterminados [B] Atrás" ], "ExtrasMenu": [ "0: Reinicializar datos", @@ -45,61 +45,61 @@ ], "ExtrasPops": [ "0: ¡Datos reinicializados!", - "1: ¡Error al reinicializar datos!" + "1: ¡Reinicialización de datos falló!" ], "GeneralPops": [ "0: ¡No se puede salir de JKSV mientras hay tareas en ejecución!" ], "GoogleDriveStrings": [ "0: Para continuar, ve a #%s# e introduce >%s>!", - "1: ¡Inicio de sesión en Google Drive exitoso!", - "2: ¡Error en el inicio de sesión de Google Drive!" + "1: ¡Sesión en Google Drive iniciada con éxito!", + "2: ¡Error al iniciar sesión en Google Drive!" ], "HoldingStrings": [ - "0: Mantén pulsado [A]", - "1: Sigue manteniendo pulsado [A]", - "2: ¡Casi ahí! [A]" + "0: Mantén [A]", + "1: Sigue manteniendo [A]", + "2: ¡Casi lo tienes! [A]" ], "IOStatuses": [ - "0: Copiando #%s#...", - "1: Comprimiendo #%s# a ZIP...", - "2: Descomprimiendo #%s# desde ZIP...", - "3: Eliminando #%s#...", - "4: Descargando #%s#...", - "5: Subiendo #%s# al almacenamiento remoto...", - "6: Actualizando #%s# en el almacenamiento remoto..." + "0: Copiando #%s#…", + "1: Comprimiendo #%s# a ZIP…", + "2: Descomprimiendo #%s# desde ZIP…", + "3: Borrando #%s#…", + "4: Descargando #%s#…", + "5: Subiendo #%s# al almacenamiento remoto…", + "6: Actualizando #%s# en el almacenamiento remoto…" ], "IOPops": [ - "0: ¡Error al guardar los datos en el dispositivo!" + "0: ¡Error al confirmar los datos en el dispositivo!" ], "KeyboardStrings": [ "0: Introduce un nuevo nombre para la copia de seguridad.", "1: Introduce el índice de caché.", - "2: Introduce una nueva ruta de salida para JKSV", - "3: Introduce el ID del proceso a terminar.", - "4: Introduce un ID de guardado del sistema", - "5: Introduce un nuevo nombre para el objeto objetivo.", - "6: Introduce un nombre para la nueva carpeta.", - "7: Introduce un nuevo nombre para la carpeta de salida de %s.", + "2: Introduce una nueva ruta de salida para JKSV.", + "3: Introduce el ID de proceso a finalizar.", + "4: Introduce un ID de guardado del sistema.", + "5: Introduce un nuevo nombre para el elemento destino.", + "6: Introduce un nombre para la carpeta nueva.", + "7: Introduce un nuevo nombre de carpeta de salida para %s.", "8: Introduce cuánto ampliar (en MB)." ], "MainMenuConfs": [ - "0: ¿Estás seguro de que quieres hacer copia de seguridad de los datos guardados para todos los usuarios de este sistema? ¡Esto puede tardar muchísimo!" + "0: ¿Segurо que quieres hacer copia de seguridad de los datos guardados para todos los usuarios de este sistema? ¡Esto puede tardar *muchísimo*!" ], "MainMenuPops": [ - "0: `%s` no tiene datos guardados." + "0: ¡`%s` no tiene datos guardados!" ], "OnOff": [ "0: Apagado", "1: >Encendido>" ], "RemotePops": [ - "0: ¡No hay conexión a internet disponible!" + "0: ¡No hay conexión a Internet disponible!" ], "SaveCreatePops": [ "0: ¡Datos guardados creados para #%s#!", "1: ¡Error al crear los datos guardados!", - "2: ¡Error al eliminar los datos guardados!" + "2: ¡Error al borrar los datos guardados!" ], "SaveDataTypes": [ "0: Sistema", @@ -111,98 +111,101 @@ "6: BCAT del sistema" ], "SettingsDescriptions": [ - "0: Establece el directorio de trabajo para JKSV. El valor por defecto es `sdmc:/JKSV`.", + "0: Establece el directorio de trabajo para JKSV. El valor predeterminado es `sdmc:/JKSV`.", "1: Permite eliminar títulos de la lista negra.", - "2: Incluye guardados de dispositivo o compartidos con usuarios.", + "2: Incluye partidas del dispositivo o compartidas con usuarios.", "3: Crea una copia de seguridad automáticamente al restaurar otra.", - "4: Nombra las copias automáticamente y omite el teclado.", - "5: Sube automáticamente las copias al almacenamiento remoto y las elimina localmente.", - "6: Siempre usa IDs de aplicación para los nombres de las carpetas de exportación.", - "7: Si es necesario mantener pulsado [A] durante tres segundos para eliminar copias.", - "8: Si es necesario mantener pulsado [A] durante tres segundos para restaurar copias.", - "9: Si es necesario mantener pulsado [A] durante tres segundos para sobrescribir copias.", - "10: Muestra solo datos guardados que JKSV puede abrir correctamente.", - "11: Muestra guardados del sistema que tienen un ID de cuenta asociado.", - "12: Habilita la restauración de guardados del sistema y escritura en particiones NAND.", - "13: Exporta guardados a archivos ZIP en lugar de carpetas sin comprimir.", - "14: Nivel de compresión o deflación al escribir ZIP. Por defecto es 6. Valores menores son más rápidos pero comprimen menos. Cero es almacenar, sin compresión.", + "4: Nombra automáticamente las copias y omite el teclado.", + "5: Sube automáticamente las copias a almacenamiento remoto y las elimina localmente.", + "6: Siempre usa IDs de aplicación para los nombres de carpeta de exportación.", + "7: Si hay que mantener [A] durante tres segundos para borrar copias.", + "8: Si hay que mantener [A] durante tres segundos para restaurar copias.", + "9: Si hay que mantener [A] durante tres segundos para sobrescribir copias.", + "10: Muestra solo partidas que JKSV puede abrir correctamente.", + "11: Muestra partidas del sistema con ID de cuenta.", + "12: Permite restaurar partidas del sistema y escribir en particiones NAND.", + "13: Exporta datos guardados como archivos ZIP en lugar de carpetas sin comprimir.", + "14: Nivel de compresión ZIP usado al escribir. El valor predeterminado es 6. Valores bajos son más rápidos pero comprimen menos. Cero significa guardar sin comprimir.", "15: Controla cómo se ordenan y muestran los títulos.", - "16: Muestra los títulos como menús de texto como el JKSM original en 3DS en lugar de cuadrículas de iconos.", - "17: Fuerza el uso del inglés como idioma en lugar del idioma del sistema detectado.", - "18: Mueve las copias eliminadas a la carpeta _TRASH_ en lugar de eliminarlas permanentemente.", - "19: Establece la velocidad a la que ocurren las transiciones y animaciones. Menor es más rápido." + "16: Muestra los títulos como menús de texto como en el JKSM original de 3DS en vez de mosaicos de iconos.", + "17: Fuerza el uso de inglés en lugar del idioma del sistema detectado.", + "18: Mueve las copias eliminadas a la carpeta _TRASH_ en lugar de eliminarlas definitivamente.", + "19: Establece la velocidad de las transiciones y animaciones. Valores bajos son más rápidos." ], "SettingsMenu": [ "0: Establecer carpeta de salida de JKSV.", "1: Editar lista negra", - "2: Incluir guardados de dispositivo con usuarios: %s", + "2: Incluir partidas de dispositivo con usuarios: %s", "3: Copia automática al restaurar: %s", - "4: Nombre automático para copias: %s", - "5: Subir copias automáticamente al almacenamiento remoto: %s", + "4: Nombres automáticos para copias: %s", + "5: Subida automática a almacenamiento remoto: %s", "6: Usar siempre IDs de aplicación: %s", - "7: Mantener pulsado para eliminar copias: %s", - "8: Mantener pulsado para restaurar copias: %s", - "9: Mantener pulsado para sobrescribir copias: %s", - "10: Mostrar solo títulos montables: %s", - "11: Mostrar guardados del sistema con cuenta: %s", - "12: Permitir escritura en guardados del sistema y NAND: %s", - "13: Exportar guardados a ZIP: %s", + "7: Mantener para borrar copias: %s", + "8: Mantener para restaurar copias: %s", + "9: Mantener para sobrescribir copias: %s", + "10: Solo mostrar títulos montables: %s", + "11: Mostrar partidas del sistema con ID de cuenta: %s", + "12: Habilitar escritura en partidas del sistema y NAND: %s", + "13: Exportar partidas a ZIP: %s", "14: Nivel de compresión ZIP: %u", - "15: Tipo de ordenación de títulos: %s", + "15: Tipo de ordenación de título: %s", "16: Modo menú de texto (JKSM): %s", "17: Forzar inglés: %s", - "18: Activar papelera de reciclaje: %s", - "19: Escala de animación: %.02f" + "18: Activar papelera: %s", + "19: Escalado de animaciones: %.02f" + ], + "SettingsPops": [ + "0: ¡La lista negra está vacía!" ], "SortTypes": [ "0: Alfabéticamente", - "1: Más jugados", - "2: Último jugado" + "1: Más jugado", + "2: Última vez jugado" ], "TitleInfo": [ - "0: ID de app: %016lX", - "1: ID de guardado: %016lx", - "2: Primera vez jugado: %x - %X", - "3: Última vez jugado: %x - %X", + "0: ID de la App: %016lX", + "1: ID del guardado: %016lx", + "2: Primera vez jugado: %x – %X", + "3: Última vez jugado: %x – %X", "4: Tiempo de juego: %02d:%02d:%02d", - "5: Lanzamientos: %i", + "5: Inicios: %i", "6: Tipo de guardado: %s" ], "TitleOptionConfirmations": [ - "0: ¿Estás seguro de que quieres añadir #%s# a la lista negra? Una vez hecho, no aparecerá en ninguna lista ni selección.", - "1: ¿Estás seguro de que quieres eliminar todas las copias guardadas actuales para #%s#? *¡Esto no se puede deshacer!*", - "2: ¿Estás seguro de que quieres reiniciar los datos guardados para #%s#? *¡Esto borrará los datos guardados actuales como si nunca hubieras jugado!*", - "3: ¿Estás seguro de que quieres eliminar los datos guardados de `%s` para #%s#? *Esto los eliminará permanentemente del sistema.*" + "0: ¿Estás seguro de que quieres añadir #%s# a la lista negra? Una vez hecho, ya no aparecerá en ninguna lista de títulos.", + "1: ¿Estás seguro de que deseas eliminar todos los backups actuales para #%s#? *¡Esto no se puede deshacer!*", + "2: ¿Estás seguro de que quieres restablecer los datos guardados para #%s#? *¡Esto eliminará los datos actuales como si nunca se hubiera ejecutado!*", + "3: ¿Estás seguro de que quieres borrar los datos guardados de `%s` para #%s#? *¡Esto lo eliminará permanentemente del sistema!*" ], "TitleOptionPops": [ - "0: ¡Todas las copias eliminadas para #%s#!", - "1: ¡No se pudieron eliminar todas las copias!", - "2: ¡Error al reiniciar los datos guardados!", - "3: ¡Datos guardados reiniciados con éxito!", + "0: ¡Todos los backups eliminados para #%s#!", + "1: ¡Error al eliminar todos los backups!", + "2: ¡Error al restablecer los datos guardados!", + "3: ¡Datos guardados restablecidos con éxito!", "4: ¡Archivo SVI exportado con éxito!", - "5: ¡Error al exportar archivo SVI!", + "5: ¡Error al exportar el archivo SVI!", "6: ¡Esta opción no está disponible para guardados del sistema!", "7: ¡No se pudo sanear la ruta para su uso!", - "8: Carpeta de salida establecida en #%s#.", - "9: ¡Error al establecer nueva ruta de salida!", + "8: ¡Carpeta de salida establecida en #%s#!", + "9: ¡Error al establecer la nueva ruta de salida!", "10: ¡Datos guardados ampliados con éxito!", "11: ¡Error al ampliar los datos guardados!" ], "TitleOptionStatus": [ - "0: Eliminando todas las copias para #%s#.", - "1: Reiniciando los datos guardados para #%s#.", - "2: Eliminando los datos guardados de `%s` para #%s#...", - "3: Ampliando los datos guardados de `%s` para #%s#..." + "0: Eliminando todos los backups para #%s#.", + "1: Restableciendo los datos guardados para #%s#.", + "2: Borrando los datos guardados de `%s` para #%s#…", + "3: Ampliando los datos guardados de `%s` para #%s#…" ], "TitleOptions": [ "0: Información", - "1: Añadir a lista negra", + "1: Añadir título a la lista negra", "2: Cambiar carpeta de salida", "3: Abrir en modo archivo", - "4: Eliminar todas las copias locales", - "5: Eliminar todas las copias remotas", - "6: Reiniciar datos guardados", - "7: Eliminar datos guardados del sistema", + "4: Eliminar todos los backups locales", + "5: Eliminar todos los backups remotos", + "6: Restablecer datos guardados", + "7: Borrar datos guardados del sistema", "8: Ampliar datos guardados", "9: Exportar archivo SVI" ], @@ -211,13 +214,13 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: ¿Estás seguro de que quieres hacer copia de seguridad de todos los datos guardados para `%s`? Esto puede tardar un rato.", - "1: ¿Estás seguro de que quieres crear datos guardados para todos los títulos encontrados en tu sistema para `%s`? Esto puede tardar un rato.", - "2: ¿Estás seguro de que quieres eliminar todos los datos guardados para `%s`? Esto es *PERMANENTE* y no se puede deshacer." + "0: ¿Estás seguro de que deseas hacer copia de los datos guardados de todos los títulos encontrados para `%s`? Esto puede tardar un tiempo.", + "1: ¿Estás seguro de que deseas crear datos guardados para todos los títulos encontrados en tu sistema para `%s`? Esto puede tardar un tiempo.", + "2: ¿Estás seguro de que deseas eliminar todos los datos guardados para `%s`? Esto es *PERMANENTE* y no puede deshacerse." ], "UserOptionStatus": [ - "0: Creando datos guardados para #%s#...", - "1: Eliminando datos guardados para #%s#..." + "0: Creando datos guardados para #%s#…", + "1: Eliminando datos guardados para #%s#…" ], "UserOptions": [ "0: Volcar todo para `%s`", diff --git a/romfs/Text/ES419.json b/romfs/Text/ES419.json index b989f26..c77dd6b 100644 --- a/romfs/Text/ES419.json +++ b/romfs/Text/ES419.json @@ -3,40 +3,40 @@ "0: Nueva copia de seguridad" ], "BackupMenuConfirmations": [ - "0: ¿Estás seguro de que quieres sobrescribir #%s#?", - "1: ¿Estás seguro de que quieres restaurar #%s#?", - "2: ¿Estás seguro de que quieres eliminar #%s#?" + "0: ¿Seguro que quieres sobrescribir #%s#?", + "1: ¿Seguro que quieres restaurar #%s#?", + "2: ¿Seguro que quieres eliminar #%s#?" ], "BackupMenuPops": [ "0: ¡Los datos guardados están vacíos!", "1: ¡La copia de seguridad está vacía!", "2: ¡Error al reiniciar los datos guardados!", "3: ¡Error al abrir el archivo ZIP para lectura!", - "4: ¡Error al eliminar la copia de seguridad!", + "4: ¡Ocurrió un error al eliminar la copia de seguridad!", "5: ¡Error al crear la copia de seguridad!", "6: ¡La escritura en el sistema está deshabilitada!", - "7: ¡No se puede abrir el ZIP para lectura!", - "8: ¡Error al escribir el archivo de metadatos de los datos guardados!", + "7: ¡No se puede abrir el zip para lectura!", + "8: ¡Error al escribir el archivo de metadatos de guardado!", "9: ¡Error al descargar el archivo!", "10: ¡Error al subir el archivo!", - "11: ¡Error al procesar los metadatos de los datos guardados!", + "11: ¡Error al procesar los metadatos del guardado!", "12: ¡Error al crear el directorio destino!", - "13: ¡La copia de seguridad debe ser un archivo ZIP para subirla!", + "13: ¡La copia de seguridad debe ser un zip para subirla!", "14: ¡Error al montar los datos guardados!", "15: ¡Error al cerrar los datos guardados!" ], "BackupMenuStatus": [ - "0: Procesando el archivo de metadatos de los datos guardados..." + "0: Procesando archivo de metadatos de guardado..." ], "ControlGuides": [ "0: [A] Seleccionar [Y] Volcar todos los guardados [X] Opciones de usuario", "1: [A] Seleccionar [L] [R] Saltar [Y] Favorito [X] Opciones de título [B] Atrás", "2: [A] Seleccionar [Y] Restaurar [X] Eliminar [ZR] Subir [B] Cerrar", - "3: [A] Alternar [X] Predeterminado [B] Atrás" + "3: [A] Alternar [X] Predeterminados [B] Atrás" ], "ExtrasMenu": [ - "0: Reiniciar datos", - "1: Navegador SD a SD", + "0: Reinicializar datos", + "1: Navegador de SD a SD", "2: ProdInfoF", "3: Seguro", "4: Sistema", @@ -44,21 +44,21 @@ "6: Terminar proceso" ], "ExtrasPops": [ - "0: ¡Datos reiniciados!", - "1: ¡Error al reiniciar datos!" + "0: ¡Datos reinicializados!", + "1: ¡Fallo al reinicializar datos!" ], "GeneralPops": [ - "0: ¡No se puede salir de JKSV mientras hay tareas en ejecución!" + "0: ¡No se puede salir de JKSV mientras haya tareas en ejecución!" ], "GoogleDriveStrings": [ "0: Para continuar, ve a #%s# e ingresa >%s>!", - "1: ¡Inicio de sesión en Google Drive exitoso!", - "2: ¡Error en el inicio de sesión de Google Drive!" + "1: ¡Sesión iniciada exitosamente en Google Drive!", + "2: ¡Fallo al iniciar sesión en Google Drive!" ], "HoldingStrings": [ "0: Mantén presionado [A]", "1: Sigue manteniendo presionado [A]", - "2: ¡Casi ahí! [A]" + "2: ¡Casi listo! [A]" ], "IOStatuses": [ "0: Copiando #%s#...", @@ -67,10 +67,10 @@ "3: Eliminando #%s#...", "4: Descargando #%s#...", "5: Subiendo #%s# al almacenamiento remoto...", - "6: Actualizando #%s# en el almacenamiento remoto..." + "6: Actualizando #%s# en almacenamiento remoto..." ], "IOPops": [ - "0: ¡Error al guardar los datos en el dispositivo!" + "0: ¡Error al guardar datos en el dispositivo!" ], "KeyboardStrings": [ "0: Ingresa un nuevo nombre para la copia de seguridad.", @@ -78,16 +78,16 @@ "2: Ingresa una nueva ruta de salida para JKSV", "3: Ingresa el ID del proceso a terminar.", "4: Ingresa un ID de guardado del sistema", - "5: Ingresa un nuevo nombre para el objeto objetivo.", + "5: Ingresa un nuevo nombre para el ítem destino.", "6: Ingresa un nombre para la nueva carpeta.", - "7: Ingresa un nuevo nombre para la carpeta de salida de %s.", + "7: Ingresa un nuevo nombre de carpeta de salida para %s.", "8: Ingresa cuánto expandir (en MB)." ], "MainMenuConfs": [ - "0: ¿Estás seguro de que quieres hacer copia de seguridad de los datos guardados para todos los usuarios de este sistema? ¡Esto puede tardar mucho!" + "0: ¿Seguro que quieres hacer copia de seguridad de los datos guardados para todos los usuarios en este sistema? ¡Esto puede tomar muchísimo tiempo!" ], "MainMenuPops": [ - "0: `%s` no tiene datos guardados." + "0: `%s` no tiene datos guardados!" ], "OnOff": [ "0: Apagado", @@ -98,8 +98,8 @@ ], "SaveCreatePops": [ "0: ¡Datos guardados creados para #%s#!", - "1: ¡Error al crear los datos guardados!", - "2: ¡Error al eliminar los datos guardados!" + "1: ¡Error al crear datos guardados!", + "2: ¡Error al eliminar datos guardados!" ], "SaveDataTypes": [ "0: Sistema", @@ -115,49 +115,52 @@ "1: Permite eliminar títulos de la lista negra.", "2: Incluye guardados de dispositivo o compartidos con usuarios.", "3: Crea una copia de seguridad automáticamente al restaurar otra.", - "4: Nombra las copias automáticamente y omite el teclado.", - "5: Sube automáticamente las copias al almacenamiento remoto y las elimina localmente.", - "6: Siempre usa IDs de aplicación para los nombres de las carpetas de exportación.", - "7: Si es necesario mantener presionado [A] durante tres segundos para eliminar copias.", - "8: Si es necesario mantener presionado [A] durante tres segundos para restaurar copias.", - "9: Si es necesario mantener presionado [A] durante tres segundos para sobrescribir copias.", - "10: Muestra solo datos guardados que JKSV puede abrir correctamente.", - "11: Muestra guardados del sistema que tienen un ID de cuenta asociado.", - "12: Habilita la restauración de guardados del sistema y escritura en particiones NAND.", - "13: Exporta guardados a archivos ZIP en lugar de carpetas sin comprimir.", - "14: Nivel de compresión o deflación al escribir ZIP. Por defecto es 6. Valores menores son más rápidos pero comprimen menos. Cero es almacenar, sin compresión.", + "4: Nombra automáticamente las copias y omite el teclado.", + "5: Sube copias de seguridad automáticamente a remoto y las elimina localmente.", + "6: Siempre usa IDs de aplicación para nombres de carpetas de exportación.", + "7: Si es necesario mantener presionado [A] por tres segundos para eliminar copias.", + "8: Si es necesario mantener presionado [A] por tres segundos para restaurar copias.", + "9: Si es necesario mantener presionado [A] por tres segundos para sobrescribir copias.", + "10: Muestra solo los datos guardados que JKSV puede abrir correctamente.", + "11: Muestra guardados del sistema que tienen ID de cuenta asociado.", + "12: Permite restaurar guardados del sistema y escribir en particiones NAND.", + "13: Exporta datos guardados a archivos ZIP en lugar de carpetas descomprimidas.", + "14: Nivel de compresión o deflación usado al escribir en ZIP. El valor por defecto es 6. Valores más bajos son más rápidos, pero ofrecen menos compresión y ahorro de espacio. Cero significa almacenar sin compresión.", "15: Controla cómo se ordenan y muestran los títulos.", - "16: Muestra los títulos como menús de texto como el JKSM original en 3DS en lugar de cuadrículas de íconos.", - "17: Fuerza el uso del inglés como idioma en lugar del idioma del sistema detectado.", - "18: Mueve las copias eliminadas a la carpeta _TRASH_ en lugar de eliminarlas permanentemente.", - "19: Establece la velocidad a la que ocurren las transiciones y animaciones. Menor es más rápido." + "16: Muestra los títulos como menús de texto estilo JKSM original en 3DS, en lugar de rejillas de iconos.", + "17: Fuerza el uso del inglés como idioma en lugar del idioma detectado del sistema.", + "18: Mueve las copias eliminadas a la carpeta _TRASH_ en vez de borrarlas permanentemente.", + "19: Establece la velocidad de transiciones y animaciones. Menor es más rápido." ], "SettingsMenu": [ "0: Establecer carpeta de salida de JKSV.", "1: Editar lista negra", "2: Incluir guardados de dispositivo con usuarios: %s", "3: Copia automática al restaurar: %s", - "4: Nombre automático para copias: %s", - "5: Subir copias automáticamente al almacenamiento remoto: %s", - "6: Usar siempre IDs de aplicación: %s", + "4: Nombres automáticos para copias: %s", + "5: Subir automáticamente copias a almacenamiento remoto: %s", + "6: Siempre usar IDs de aplicación: %s", "7: Mantener presionado para eliminar copias: %s", "8: Mantener presionado para restaurar copias: %s", "9: Mantener presionado para sobrescribir copias: %s", - "10: Mostrar solo títulos montables: %s", - "11: Mostrar guardados del sistema con cuenta: %s", - "12: Permitir escritura en guardados del sistema y NAND: %s", + "10: Solo listar títulos montables: %s", + "11: Mostrar guardados con ID de cuenta: %s", + "12: Permitir escritura en guardados y NAND: %s", "13: Exportar guardados a ZIP: %s", "14: Nivel de compresión ZIP: %u", - "15: Tipo de ordenación de títulos: %s", - "16: Modo menú de texto (JKSM): %s", + "15: Tipo de orden de títulos: %s", + "16: Modo menú texto (JKSM): %s", "17: Forzar inglés: %s", - "18: Activar papelera de reciclaje: %s", + "18: Activar papelera: %s", "19: Escala de animación: %.02f" ], + "SettingsPops": [ + "0: ¡La lista negra está vacía!" + ], "SortTypes": [ "0: Alfabéticamente", "1: Más jugados", - "2: Último jugado" + "2: Última vez jugado" ], "TitleInfo": [ "0: ID de app: %016lX", @@ -169,41 +172,41 @@ "6: Tipo de guardado: %s" ], "TitleOptionConfirmations": [ - "0: ¿Estás seguro de que quieres añadir #%s# a la lista negra? Una vez hecho, no aparecerá en ninguna lista ni selección.", - "1: ¿Estás seguro de que quieres eliminar todas las copias guardadas actuales para #%s#? *¡Esto no se puede deshacer!*", - "2: ¿Estás seguro de que quieres reiniciar los datos guardados para #%s#? *¡Esto borrará los datos guardados actuales como si nunca hubieras jugado!*", - "3: ¿Estás seguro de que quieres eliminar los datos guardados de `%s` para #%s#? *Esto los eliminará permanentemente del sistema.*" + "0: ¿Seguro que quieres añadir #%s# a tu lista negra? Una vez hecho, no aparecerá en ninguna lista o selección de títulos.", + "1: ¿Seguro que quieres eliminar todas las copias de seguridad actuales para #%s#? *¡Esto no se puede deshacer!*", + "2: ¿Seguro que quieres reiniciar los datos guardados para #%s#? *¡Esto eliminará los datos actuales como si nunca hubieras jugado!*", + "3: ¿Seguro que quieres eliminar los datos guardados de `%s` para #%s#? *Esto los borrará permanentemente del sistema.*" ], "TitleOptionPops": [ "0: ¡Todas las copias eliminadas para #%s#!", "1: ¡No se pudieron eliminar todas las copias!", "2: ¡Error al reiniciar los datos guardados!", - "3: ¡Datos guardados reiniciados con éxito!", - "4: ¡Archivo SVI exportado con éxito!", + "3: ¡Datos guardados reiniciados exitosamente!", + "4: ¡Archivo SVI exportado exitosamente!", "5: ¡Error al exportar archivo SVI!", "6: ¡Esta opción no está disponible para guardados del sistema!", - "7: ¡No se pudo sanear la ruta para su uso!", - "8: Carpeta de salida establecida en #%s#.", - "9: ¡Error al establecer nueva ruta de salida!", - "10: ¡Datos guardados ampliados con éxito!", - "11: ¡Error al ampliar los datos guardados!" + "7: ¡No se pudo limpiar la ruta para su uso!", + "8: Carpeta de salida establecida a #%s#.", + "9: ¡Error al establecer la nueva ruta de salida!", + "10: ¡Datos guardados extendidos exitosamente!", + "11: ¡Fallo al extender los datos guardados!" ], "TitleOptionStatus": [ "0: Eliminando todas las copias para #%s#.", - "1: Reiniciando los datos guardados para #%s#.", - "2: Eliminando los datos guardados de `%s` para #%s#...", - "3: Ampliando los datos guardados de `%s` para #%s#..." + "1: Reiniciando datos guardados para #%s#.", + "2: Eliminando los datos de `%s` para #%s#...", + "3: Extendiendo los datos de `%s` para #%s#..." ], "TitleOptions": [ "0: Información", - "1: Añadir a lista negra", + "1: Lista negra del título", "2: Cambiar carpeta de salida", "3: Abrir en modo archivo", "4: Eliminar todas las copias locales", "5: Eliminar todas las copias remotas", - "6: Reiniciar datos guardados", + "6: Reiniciar datos guardados.", "7: Eliminar datos guardados del sistema", - "8: Ampliar datos guardados", + "8: Extender datos guardados", "9: Exportar archivo SVI" ], "TranslationInfo": [ @@ -211,9 +214,9 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: ¿Estás seguro de que quieres hacer copia de seguridad de todos los datos guardados para `%s`? Esto puede tardar un rato.", - "1: ¿Estás seguro de que quieres crear datos guardados para todos los títulos encontrados en tu sistema para `%s`? Esto puede tardar un rato.", - "2: ¿Estás seguro de que quieres eliminar todos los datos guardados para `%s`? Esto es *PERMANENTE* y no se puede deshacer." + "0: ¿Seguro que quieres hacer copia de seguridad de los datos guardados para todos los títulos encontrados para `%s`? Esto puede tardar un rato.", + "1: ¿Seguro que quieres crear datos guardados para todos los títulos encontrados en tu sistema para `%s`? Esto puede tardar un rato.", + "2: ¿Seguro que quieres eliminar todos los datos guardados para `%s`? Esto es *PERMANENTE* y no se puede deshacer." ], "UserOptionStatus": [ "0: Creando datos guardados para #%s#...", @@ -226,7 +229,7 @@ "3: Eliminar todos los datos guardados para `%s`" ], "WebDavStrings": [ - "0: ¡WebDav iniciado con éxito!", + "0: ¡WebDav iniciado exitosamente!", "1: ¡WebDav falló!" ], "YesNo": [ diff --git a/romfs/Text/FR.json b/romfs/Text/FR.json index 0f5c571..a0b6d03 100644 --- a/romfs/Text/FR.json +++ b/romfs/Text/FR.json @@ -3,25 +3,25 @@ "0: Nouvelle sauvegarde" ], "BackupMenuConfirmations": [ - "0: Êtes-vous sûr de vouloir écraser #%s# ?", - "1: Êtes-vous sûr de vouloir restaurer #%s# ?", - "2: Êtes-vous sûr de vouloir supprimer #%s# ?" + "0: Êtes-vous sûr de vouloir vraiment écraser #%s# ?", + "1: Êtes-vous sûr de vouloir vraiment restaurer #%s# ?", + "2: Êtes-vous sûr de vouloir vraiment supprimer #%s# ?" ], "BackupMenuPops": [ - "0: Les données sauvegardées sont vides !", + "0: Les données de sauvegarde sont vides !", "1: La sauvegarde est vide !", "2: Erreur lors de la réinitialisation des données sauvegardées !", "3: Erreur lors de l'ouverture du fichier ZIP en lecture !", - "4: Erreur lors de la suppression de la sauvegarde !", + "4: Une erreur est survenue lors de la suppression de la sauvegarde !", "5: Erreur lors de la création de la sauvegarde !", - "6: L’écriture sur le système est désactivée !", - "7: Impossible d’ouvrir le ZIP en lecture !", + "6: L’écriture dans le système est désactivée !", + "7: Impossible d’ouvrir le zip en lecture !", "8: Erreur lors de l’écriture du fichier méta des données sauvegardées !", "9: Erreur lors du téléchargement du fichier !", - "10: Erreur lors de l’upload du fichier !", - "11: Erreur lors du traitement des métadonnées des données sauvegardées !", + "10: Erreur lors de l’envoi du fichier !", + "11: Erreur lors du traitement des métadonnées de sauvegarde !", "12: Erreur lors de la création du répertoire cible !", - "13: La sauvegarde doit être un ZIP pour être uploadée !", + "13: La sauvegarde doit être un zip pour être téléversée !", "14: Erreur lors du montage des données sauvegardées !", "15: Erreur lors de la fermeture des données sauvegardées !" ], @@ -29,16 +29,16 @@ "0: Traitement du fichier méta des données sauvegardées..." ], "ControlGuides": [ - "0: [A] Sélectionner [Y] Tout dumper [X] Options utilisateur", - "1: [A] Sélectionner [L] [R] Sauter [Y] Favori [X] Options titre [B] Retour", - "2: [A] Sélectionner [Y] Restaurer [X] Supprimer [ZR] Upload [B] Fermer", - "3: [A] Basculer [X] Par défaut [B] Retour" + "0: [A] Sélectionner [Y] Exporter toutes les sauvegardes [X] Options utilisateur", + "1: [A] Sélectionner [L] [R] Sauter [Y] Favori [X] Options du titre [B] Retour", + "2: [A] Sélectionner [Y] Restaurer [X] Supprimer [ZR] Téléverser [B] Fermer", + "3: [A] Basculer [X] Défauts [B] Retour" ], "ExtrasMenu": [ "0: Réinitialiser les données", "1: Navigateur SD vers SD", "2: ProdInfoF", - "3: Sécurisé", + "3: Sécurité", "4: Système", "5: Utilisateur", "6: Terminer le processus" @@ -48,10 +48,10 @@ "1: Échec de la réinitialisation des données !" ], "GeneralPops": [ - "0: Impossible de quitter JKSV pendant l’exécution de tâches !" + "0: Impossible de quitter JKSV tant que des tâches sont en cours !" ], "GoogleDriveStrings": [ - "0: Pour continuer, rendez-vous sur #%s# et saisissez >%s> !", + "0: Pour continuer, allez sur #%s# et saisissez >%s> !", "1: Connexion réussie à Google Drive !", "2: Échec de la connexion à Google Drive !" ], @@ -66,25 +66,25 @@ "2: Décompression de #%s# depuis ZIP...", "3: Suppression de #%s#...", "4: Téléchargement de #%s#...", - "5: Upload de #%s# vers le stockage distant...", + "5: Téléversement de #%s# vers le stockage distant...", "6: Mise à jour de #%s# sur le stockage distant..." ], "IOPops": [ "0: Erreur lors de l’écriture des données sur l’appareil !" ], "KeyboardStrings": [ - "0: Entrez un nouveau nom de sauvegarde.", - "1: Entrez l’indice du cache.", + "0: Entrez un nouveau nom pour la sauvegarde.", + "1: Entrez l’index du cache.", "2: Entrez un nouveau chemin de sortie pour JKSV", "3: Entrez l’ID du processus à terminer.", "4: Entrez un ID de sauvegarde système", "5: Entrez un nouveau nom pour l’élément cible.", "6: Entrez un nom pour le nouveau dossier.", "7: Entrez un nouveau nom de dossier de sortie pour %s.", - "8: Entrez la taille d’extension (en Mo)." + "8: Entrez la taille d’expansion (en Mo)." ], "MainMenuConfs": [ - "0: Êtes-vous sûr de vouloir sauvegarder les données de sauvegarde pour tous les utilisateurs sur ce système ? Cela peut prendre *beaucoup* de temps !" + "0: Êtes-vous sûr de vouloir sauvegarder les données pour tous les utilisateurs de ce système ? Cela peut prendre *beaucoup* de temps !" ], "MainMenuPops": [ "0: `%s` n’a pas de données sauvegardées !" @@ -94,12 +94,12 @@ "1: >Activé>" ], "RemotePops": [ - "0: Pas de connexion Internet disponible !" + "0: Aucune connexion Internet disponible !" ], "SaveCreatePops": [ "0: Données sauvegardées créées pour #%s#!", - "1: Échec de la création des données sauvegardées !", - "2: Échec de la suppression des données sauvegardées !" + "1: Erreur lors de la création des données sauvegardées !", + "2: Erreur lors de la suppression des données sauvegardées !" ], "SaveDataTypes": [ "0: Système", @@ -113,38 +113,38 @@ "SettingsDescriptions": [ "0: Définit le répertoire de travail pour JKSV. La valeur par défaut est `sdmc:/JKSV`.", "1: Permet de retirer des titres de la liste noire.", - "2: Inclut les sauvegardes d’appareil, ou partagées, avec les utilisateurs.", + "2: Inclut les sauvegardes de l’appareil, ou partagées, avec les utilisateurs.", "3: Crée automatiquement une sauvegarde lors de la restauration d’une autre.", - "4: Nomme automatiquement les sauvegardes et saute le clavier.", - "5: Télécharge automatiquement les sauvegardes vers le stockage distant et les supprime localement.", - "6: Utilise toujours les IDs d’application pour les noms de dossiers d’exportation.", - "7: Nécessite de maintenir [A] pendant trois secondes pour supprimer des sauvegardes.", - "8: Nécessite de maintenir [A] pendant trois secondes pour restaurer des sauvegardes.", - "9: Nécessite de maintenir [A] pendant trois secondes pour écraser des sauvegardes.", - "10: N’affiche que les données sauvegardées que JKSV peut ouvrir avec succès.", + "4: Nomme automatiquement les sauvegardes et évite le clavier.", + "5: Téléverse automatiquement les sauvegardes sur un stockage distant et les supprime localement.", + "6: Utilise toujours les IDs d’application pour les noms des dossiers d’exportation.", + "7: Indique si maintenir [A] pendant trois secondes est requis pour supprimer les sauvegardes.", + "8: Indique si maintenir [A] pendant trois secondes est requis pour restaurer les sauvegardes.", + "9: Indique si maintenir [A] pendant trois secondes est requis pour écraser les sauvegardes.", + "10: Affiche uniquement les données que JKSV peut ouvrir correctement.", "11: Affiche les sauvegardes système liées à un ID de compte.", "12: Permet de restaurer les sauvegardes système et d’écrire dans les partitions NAND.", - "13: Exporte les sauvegardes en archives ZIP plutôt qu’en dossiers décompressés.", - "14: Niveau de compression ou décompression utilisé lors de l’écriture en ZIP. La valeur par défaut est 6. Les valeurs basses sont plus rapides mais compressent moins. Zéro signifie stockage, sans compression.", - "15: Contrôle la façon dont les titres sont triés et affichés.", - "16: Affiche les titres en menus texte comme le JKSM original sur 3DS au lieu de grilles d’icônes.", - "17: Force l’utilisation de l’anglais comme langue au lieu de la langue détectée du système.", + "13: Exporte les données sauvegardées dans des archives ZIP au lieu de dossiers décompressés.", + "14: Niveau de compression ou décompression utilisé lors de l’écriture en ZIP. La valeur par défaut est 6. Les valeurs basses sont plus rapides, mais compressent moins et économisent moins d’espace. Zéro signifie stocker sans compression.", + "15: Contrôle la manière dont les titres sont triés et affichés.", + "16: Affiche les titres sous forme de menus texte comme JKSM original sur 3DS au lieu de grilles d’icônes.", + "17: Force l’utilisation de l’anglais comme langue plutôt que la langue système détectée.", "18: Déplace les sauvegardes supprimées vers le dossier _TRASH_ au lieu de les supprimer définitivement.", - "19: Définit la vitesse à laquelle les transitions et animations se produisent. Plus bas est plus rapide." + "19: Définit la vitesse des transitions et animations. Plus bas est plus rapide." ], "SettingsMenu": [ - "0: Définir le dossier de sortie de JKSV.", - "1: Modifier la liste noire", - "2: Inclure les sauvegardes d’appareil avec les utilisateurs : %s", - "3: Sauvegarde automatique à la restauration : %s", + "0: Définir le dossier de sortie JKSV.", + "1: Éditer la liste noire", + "2: Inclure les sauvegardes de l’appareil avec les utilisateurs : %s", + "3: Sauvegarde automatique lors de la restauration : %s", "4: Nom automatique des sauvegardes : %s", - "5: Téléchargement automatique des sauvegardes vers le stockage distant : %s", + "5: Téléversement automatique des sauvegardes sur stockage distant : %s", "6: Toujours utiliser les IDs d’application : %s", "7: Maintenir pour supprimer les sauvegardes : %s", "8: Maintenir pour restaurer les sauvegardes : %s", "9: Maintenir pour écraser les sauvegardes : %s", - "10: N’afficher que les titres montables : %s", - "11: Afficher les sauvegardes système avec compte : %s", + "10: Lister uniquement les titres montables : %s", + "11: Afficher les sauvegardes liées à un compte : %s", "12: Autoriser l’écriture dans les sauvegardes système et NAND : %s", "13: Exporter les sauvegardes en ZIP : %s", "14: Niveau de compression ZIP : %u", @@ -154,24 +154,27 @@ "18: Activer la corbeille : %s", "19: Échelle d’animation : %.02f" ], + "SettingsPops": [ + "0: La liste noire est vide !" + ], "SortTypes": [ "0: Alphabétique", - "1: Plus joués", - "2: Dernier joué" + "1: Plus joué", + "2: Dernière fois joué" ], "TitleInfo": [ - "0: ID de l’application : %016lX", + "0: ID d’application : %016lX", "1: ID de sauvegarde : %016lx", - "2: Première utilisation : %x - %X", - "3: Dernière utilisation : %x - %X", + "2: Première partie : %x - %X", + "3: Dernière partie : %x - %X", "4: Temps de jeu : %02d:%02d:%02d", "5: Lancements : %i", "6: Type de sauvegarde : %s" ], "TitleOptionConfirmations": [ - "0: Êtes-vous sûr de vouloir ajouter #%s# à votre liste noire ? Une fois fait, il ne s’affichera plus dans aucune liste ni sélection.", + "0: Êtes-vous sûr de vouloir ajouter #%s# à votre liste noire ? Une fois fait, il n’apparaîtra plus dans aucune liste ou sélection de titres.", "1: Êtes-vous sûr de vouloir supprimer toutes les sauvegardes actuelles pour #%s# ? *Cela ne peut pas être annulé !*", - "2: Êtes-vous sûr de vouloir réinitialiser les données sauvegardées pour #%s# ? *Cela supprimera les données comme si le titre n’avait jamais été lancé !*", + "2: Êtes-vous sûr de vouloir réinitialiser les données sauvegardées pour #%s# ? *Cela supprimera les données actuelles comme si le titre n’avait jamais été lancé !*", "3: Êtes-vous sûr de vouloir supprimer les données sauvegardées de `%s` pour #%s# ? *Cela les supprimera définitivement du système.*" ], "TitleOptionPops": [ @@ -180,10 +183,10 @@ "2: Erreur lors de la réinitialisation des données sauvegardées !", "3: Données sauvegardées réinitialisées avec succès !", "4: Fichier SVI exporté avec succès !", - "5: Échec de l’export du fichier SVI !", + "5: Erreur lors de l’export du fichier SVI !", "6: Cette option n’est pas disponible pour les sauvegardes système !", - "7: Impossible de nettoyer le chemin pour son utilisation !", - "8: Dossier de sortie défini sur #%s#.", + "7: Impossible de nettoyer le chemin pour l’utiliser !", + "8: Dossier de sortie défini à #%s#.", "9: Erreur lors de la définition du nouveau chemin de sortie !", "10: Données sauvegardées étendues avec succès !", "11: Échec de l’extension des données sauvegardées !" @@ -191,17 +194,17 @@ "TitleOptionStatus": [ "0: Suppression de toutes les sauvegardes pour #%s#.", "1: Réinitialisation des données sauvegardées pour #%s#.", - "2: Suppression des données sauvegardées de `%s` pour #%s#...", - "3: Extension des données sauvegardées de `%s` pour #%s#..." + "2: Suppression des données de `%s` pour #%s#...", + "3: Extension des données de `%s` pour #%s#..." ], "TitleOptions": [ "0: Informations", - "1: Liste noire", + "1: Liste noire du titre", "2: Changer le dossier de sortie", "3: Ouvrir en mode fichier", "4: Supprimer toutes les sauvegardes locales", "5: Supprimer toutes les sauvegardes distantes", - "6: Réinitialiser les données sauvegardées", + "6: Réinitialiser les données sauvegardées.", "7: Supprimer les données sauvegardées du système", "8: Étendre les données sauvegardées", "9: Exporter le fichier SVI" @@ -211,16 +214,16 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: Êtes-vous sûr de vouloir sauvegarder toutes les données sauvegardées pour `%s` ? Cela peut prendre un moment.", + "0: Êtes-vous sûr de vouloir sauvegarder les données pour tous les titres trouvés pour `%s` ? Cela peut prendre un moment.", "1: Êtes-vous sûr de vouloir créer des données sauvegardées pour tous les titres trouvés sur votre système pour `%s` ? Cela peut prendre un moment.", - "2: Êtes-vous sûr de vouloir supprimer toutes les données sauvegardées pour `%s` ? C’est *PERMANENT* et ne peut pas être annulé." + "2: Êtes-vous sûr de vouloir supprimer toutes les données sauvegardées pour `%s` ? C’est *DÉFINITIF* et ne peut pas être annulé." ], "UserOptionStatus": [ "0: Création des données sauvegardées pour #%s#...", "1: Suppression des données sauvegardées pour #%s#..." ], "UserOptions": [ - "0: Tout dumper pour `%s`", + "0: Exporter tout pour `%s`", "1: Créer des données sauvegardées pour `%s`", "2: Créer toutes les données sauvegardées pour `%s`", "3: Supprimer toutes les données sauvegardées pour `%s`" diff --git a/romfs/Text/FRCA.json b/romfs/Text/FRCA.json index d35c286..a18babc 100644 --- a/romfs/Text/FRCA.json +++ b/romfs/Text/FRCA.json @@ -3,25 +3,25 @@ "0: Nouvelle sauvegarde" ], "BackupMenuConfirmations": [ - "0: Êtes-vous certain de vouloir écraser #%s# ?", - "1: Êtes-vous certain de vouloir restaurer #%s# ?", - "2: Êtes-vous certain de vouloir supprimer #%s# ?" + "0: Êtes-vous certain de vouloir vraiment écraser #%s# ?", + "1: Êtes-vous certain de vouloir vraiment restaurer #%s# ?", + "2: Êtes-vous certain de vouloir vraiment supprimer #%s# ?" ], "BackupMenuPops": [ - "0: Les données sauvegardées sont vides !", + "0: Les données de sauvegarde sont vides !", "1: La sauvegarde est vide !", "2: Erreur lors de la réinitialisation des données sauvegardées !", "3: Erreur lors de l’ouverture du fichier ZIP en lecture !", - "4: Erreur lors de la suppression de la sauvegarde !", + "4: Une erreur s’est produite lors de la suppression de la sauvegarde !", "5: Erreur lors de la création de la sauvegarde !", "6: L’écriture dans le système est désactivée !", - "7: Impossible d’ouvrir le ZIP en lecture !", + "7: Impossible d’ouvrir le zip en lecture !", "8: Erreur lors de l’écriture du fichier méta des données sauvegardées !", "9: Erreur lors du téléchargement du fichier !", - "10: Erreur lors du téléversement du fichier !", - "11: Erreur lors du traitement des métadonnées des données sauvegardées !", + "10: Erreur lors de l’envoi du fichier !", + "11: Erreur lors du traitement des métadonnées de sauvegarde !", "12: Erreur lors de la création du répertoire cible !", - "13: La sauvegarde doit être un ZIP pour être téléversée !", + "13: La sauvegarde doit être un fichier zip pour être téléversée !", "14: Erreur lors du montage des données sauvegardées !", "15: Erreur lors de la fermeture des données sauvegardées !" ], @@ -29,16 +29,16 @@ "0: Traitement du fichier méta des données sauvegardées..." ], "ControlGuides": [ - "0: [A] Sélectionner [Y] Tout exporter [X] Options utilisateur", + "0: [A] Sélectionner [Y] Exporter toutes les sauvegardes [X] Options utilisateur", "1: [A] Sélectionner [L] [R] Sauter [Y] Favori [X] Options du titre [B] Retour", "2: [A] Sélectionner [Y] Restaurer [X] Supprimer [ZR] Téléverser [B] Fermer", - "3: [A] Basculer [X] Par défaut [B] Retour" + "3: [A] Basculer [X] Défauts [B] Retour" ], "ExtrasMenu": [ "0: Réinitialiser les données", "1: Navigateur SD vers SD", "2: ProdInfoF", - "3: Sécurisé", + "3: Sécurité", "4: Système", "5: Utilisateur", "6: Terminer le processus" @@ -51,14 +51,14 @@ "0: Impossible de quitter JKSV tant que des tâches sont en cours !" ], "GoogleDriveStrings": [ - "0: Pour continuer, allez à #%s# et saisissez >%s> !", + "0: Pour continuer, allez à #%s# et entrez >%s> !", "1: Connexion réussie à Google Drive !", "2: Échec de la connexion à Google Drive !" ], "HoldingStrings": [ "0: Maintenez [A]", "1: Continuez de maintenir [A]", - "2: Presque là ! [A]" + "2: Presque prêt ! [A]" ], "IOStatuses": [ "0: Copie de #%s# en cours...", @@ -73,18 +73,18 @@ "0: Erreur lors de l’écriture des données sur l’appareil !" ], "KeyboardStrings": [ - "0: Entrez un nouveau nom de sauvegarde.", - "1: Entrez l’indice du cache.", + "0: Entrez un nouveau nom pour la sauvegarde.", + "1: Entrez l’index du cache.", "2: Entrez un nouveau chemin de sortie pour JKSV", "3: Entrez l’ID du processus à terminer.", "4: Entrez un ID de sauvegarde système", "5: Entrez un nouveau nom pour l’élément cible.", "6: Entrez un nom pour le nouveau dossier.", "7: Entrez un nouveau nom de dossier de sortie pour %s.", - "8: Entrez la taille d’extension (en Mo)." + "8: Entrez la taille d’expansion (en Mo)." ], "MainMenuConfs": [ - "0: Êtes-vous certain de vouloir sauvegarder les données pour tous les utilisateurs sur ce système ? Ça peut prendre *beaucoup* de temps !" + "0: Êtes-vous certain de vouloir sauvegarder les données pour tous les utilisateurs de ce système ? Cela peut prendre *beaucoup* de temps !" ], "MainMenuPops": [ "0: `%s` n’a pas de données sauvegardées !" @@ -94,12 +94,12 @@ "1: >Activé>" ], "RemotePops": [ - "0: Pas de connexion Internet disponible !" + "0: Aucune connexion Internet disponible !" ], "SaveCreatePops": [ "0: Données sauvegardées créées pour #%s#!", - "1: Échec de la création des données sauvegardées !", - "2: Échec de la suppression des données sauvegardées !" + "1: Erreur lors de la création des données sauvegardées !", + "2: Erreur lors de la suppression des données sauvegardées !" ], "SaveDataTypes": [ "0: Système", @@ -111,42 +111,42 @@ "6: BCAT système" ], "SettingsDescriptions": [ - "0: Définit le dossier de travail pour JKSV. Par défaut c’est `sdmc:/JKSV`.", + "0: Définit le répertoire de travail pour JKSV. La valeur par défaut est `sdmc:/JKSV`.", "1: Permet de retirer des titres de la liste noire.", - "2: Inclut les sauvegardes d’appareil ou partagées avec les utilisateurs.", - "3: Crée une sauvegarde automatiquement lors de la restauration.", - "4: Nomme automatiquement les sauvegardes et saute le clavier.", - "5: Téléverse automatiquement les sauvegardes vers un stockage distant et les supprime localement.", - "6: Utilise toujours les IDs d’application pour les noms de dossiers d’exportation.", - "7: Exige de maintenir [A] trois secondes pour supprimer des sauvegardes.", - "8: Exige de maintenir [A] trois secondes pour restaurer des sauvegardes.", - "9: Exige de maintenir [A] trois secondes pour écraser des sauvegardes.", - "10: Affiche seulement les données sauvegardées que JKSV peut ouvrir.", + "2: Inclut les sauvegardes de l’appareil, ou partagées, avec les utilisateurs.", + "3: Crée automatiquement une sauvegarde lors de la restauration d’une autre.", + "4: Nomme automatiquement les sauvegardes et évite le clavier.", + "5: Téléverse automatiquement les sauvegardes sur un stockage distant et les supprime localement.", + "6: Utilise toujours les IDs d’application pour les noms des dossiers d’exportation.", + "7: Indique si maintenir [A] pendant trois secondes est requis pour supprimer les sauvegardes.", + "8: Indique si maintenir [A] pendant trois secondes est requis pour restaurer les sauvegardes.", + "9: Indique si maintenir [A] pendant trois secondes est requis pour écraser les sauvegardes.", + "10: Affiche uniquement les données que JKSV peut ouvrir correctement.", "11: Affiche les sauvegardes système liées à un ID de compte.", - "12: Permet de restaurer les sauvegardes système et d’écrire sur les partitions NAND.", - "13: Exporte les sauvegardes en fichiers ZIP plutôt qu’en dossiers décompressés.", - "14: Niveau de compression utilisé lors de la création de ZIP. Par défaut 6. Les valeurs plus basses sont plus rapides mais compressent moins. 0 = stockage sans compression.", - "15: Contrôle la façon dont les titres sont triés et affichés.", - "16: Affiche les titres en menus texte comme l’original JKSM sur 3DS au lieu de grilles d’icônes.", - "17: Force l’utilisation de l’anglais plutôt que la langue système détectée.", + "12: Permet de restaurer les sauvegardes système et d’écrire dans les partitions NAND.", + "13: Exporte les données sauvegardées dans des archives ZIP au lieu de dossiers décompressés.", + "14: Niveau de compression ou décompression utilisé lors de l’écriture en ZIP. La valeur par défaut est 6. Les valeurs basses sont plus rapides, mais compressent moins et économisent moins d’espace. Zéro signifie stocker sans compression.", + "15: Contrôle la manière dont les titres sont triés et affichés.", + "16: Affiche les titres sous forme de menus texte comme JKSM original sur 3DS au lieu de grilles d’icônes.", + "17: Force l’utilisation de l’anglais comme langue plutôt que la langue système détectée.", "18: Déplace les sauvegardes supprimées vers le dossier _TRASH_ au lieu de les supprimer définitivement.", - "19: Définit la vitesse des transitions et animations. Plus bas = plus rapide." + "19: Définit la vitesse des transitions et animations. Plus bas est plus rapide." ], "SettingsMenu": [ - "0: Définir le dossier de sortie de JKSV.", - "1: Modifier la liste noire", - "2: Inclure les sauvegardes d’appareil avec les utilisateurs : %s", - "3: Sauvegarde automatique à la restauration : %s", - "4: Nommage automatique des sauvegardes : %s", - "5: Téléversement automatique vers stockage distant : %s", + "0: Définir le dossier de sortie JKSV.", + "1: Éditer la liste noire", + "2: Inclure les sauvegardes de l’appareil avec les utilisateurs : %s", + "3: Sauvegarde automatique lors de la restauration : %s", + "4: Nom automatique des sauvegardes : %s", + "5: Téléversement automatique des sauvegardes sur stockage distant : %s", "6: Toujours utiliser les IDs d’application : %s", - "7: Maintenir pour supprimer des sauvegardes : %s", - "8: Maintenir pour restaurer des sauvegardes : %s", - "9: Maintenir pour écraser des sauvegardes : %s", - "10: Afficher seulement les titres montables : %s", - "11: Afficher les sauvegardes système avec compte : %s", - "12: Autoriser l’écriture sur sauvegardes système et NAND : %s", - "13: Exporter en ZIP : %s", + "7: Maintenir pour supprimer les sauvegardes : %s", + "8: Maintenir pour restaurer les sauvegardes : %s", + "9: Maintenir pour écraser les sauvegardes : %s", + "10: Lister uniquement les titres montables : %s", + "11: Afficher les sauvegardes liées à un compte : %s", + "12: Autoriser l’écriture dans les sauvegardes système et NAND : %s", + "13: Exporter les sauvegardes en ZIP : %s", "14: Niveau de compression ZIP : %u", "15: Type de tri des titres : %s", "16: Mode menu texte (JKSM) : %s", @@ -154,24 +154,27 @@ "18: Activer la corbeille : %s", "19: Échelle d’animation : %.02f" ], + "SettingsPops": [ + "0: La liste noire est vide !" + ], "SortTypes": [ "0: Alphabétique", - "1: Plus joués", - "2: Dernier joué" + "1: Plus joué", + "2: Dernière fois joué" ], "TitleInfo": [ - "0: ID de l’application : %016lX", + "0: ID d’application : %016lX", "1: ID de sauvegarde : %016lx", - "2: Première utilisation : %x - %X", - "3: Dernière utilisation : %x - %X", + "2: Première partie : %x - %X", + "3: Dernière partie : %x - %X", "4: Temps de jeu : %02d:%02d:%02d", - "5: Nombre de lancements : %i", + "5: Lancements : %i", "6: Type de sauvegarde : %s" ], "TitleOptionConfirmations": [ - "0: Êtes-vous certain de vouloir ajouter #%s# à la liste noire ? Une fois fait, il n’apparaîtra plus dans aucune liste ou sélection.", - "1: Êtes-vous certain de vouloir supprimer toutes les sauvegardes pour #%s# ? *C’est irréversible !*", - "2: Êtes-vous certain de vouloir réinitialiser les données sauvegardées pour #%s# ? *Cela supprimera les données comme si le titre n’avait jamais été lancé !*", + "0: Êtes-vous certain de vouloir ajouter #%s# à votre liste noire ? Une fois fait, il n’apparaîtra plus dans aucune liste ou sélection de titres.", + "1: Êtes-vous certain de vouloir supprimer toutes les sauvegardes actuelles pour #%s# ? *Cela ne peut pas être annulé !*", + "2: Êtes-vous certain de vouloir réinitialiser les données sauvegardées pour #%s# ? *Cela supprimera les données actuelles comme si le titre n’avait jamais été lancé !*", "3: Êtes-vous certain de vouloir supprimer les données sauvegardées de `%s` pour #%s# ? *Cela les supprimera définitivement du système.*" ], "TitleOptionPops": [ @@ -180,10 +183,10 @@ "2: Erreur lors de la réinitialisation des données sauvegardées !", "3: Données sauvegardées réinitialisées avec succès !", "4: Fichier SVI exporté avec succès !", - "5: Échec de l’export du fichier SVI !", + "5: Erreur lors de l’export du fichier SVI !", "6: Cette option n’est pas disponible pour les sauvegardes système !", - "7: Impossible de nettoyer le chemin pour son utilisation !", - "8: Dossier de sortie défini sur #%s#.", + "7: Impossible de nettoyer le chemin pour l’utiliser !", + "8: Dossier de sortie défini à #%s#.", "9: Erreur lors de la définition du nouveau chemin de sortie !", "10: Données sauvegardées étendues avec succès !", "11: Échec de l’extension des données sauvegardées !" @@ -191,17 +194,17 @@ "TitleOptionStatus": [ "0: Suppression de toutes les sauvegardes pour #%s#.", "1: Réinitialisation des données sauvegardées pour #%s#.", - "2: Suppression des données sauvegardées de `%s` pour #%s#...", - "3: Extension des données sauvegardées de `%s` pour #%s#..." + "2: Suppression des données de `%s` pour #%s#...", + "3: Extension des données de `%s` pour #%s#..." ], "TitleOptions": [ "0: Informations", - "1: Liste noire", + "1: Liste noire du titre", "2: Changer le dossier de sortie", "3: Ouvrir en mode fichier", "4: Supprimer toutes les sauvegardes locales", "5: Supprimer toutes les sauvegardes distantes", - "6: Réinitialiser les données sauvegardées", + "6: Réinitialiser les données sauvegardées.", "7: Supprimer les données sauvegardées du système", "8: Étendre les données sauvegardées", "9: Exporter le fichier SVI" @@ -211,16 +214,16 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: Êtes-vous certain de vouloir sauvegarder toutes les données pour `%s` ? Ça peut prendre un moment.", - "1: Êtes-vous certain de vouloir créer des données sauvegardées pour tous les titres trouvés sur votre système pour `%s` ? Ça peut prendre un moment.", - "2: Êtes-vous certain de vouloir supprimer toutes les données sauvegardées pour `%s` ? C’est *PERMANENT* et irréversible." + "0: Êtes-vous certain de vouloir sauvegarder les données pour tous les titres trouvés pour `%s` ? Cela peut prendre un moment.", + "1: Êtes-vous certain de vouloir créer des données sauvegardées pour tous les titres trouvés sur votre système pour `%s` ? Cela peut prendre un moment.", + "2: Êtes-vous certain de vouloir supprimer toutes les données sauvegardées pour `%s` ? C’est *DÉFINITIF* et ne peut pas être annulé." ], "UserOptionStatus": [ "0: Création des données sauvegardées pour #%s#...", "1: Suppression des données sauvegardées pour #%s#..." ], "UserOptions": [ - "0: Tout exporter pour `%s`", + "0: Exporter tout pour `%s`", "1: Créer des données sauvegardées pour `%s`", "2: Créer toutes les données sauvegardées pour `%s`", "3: Supprimer toutes les données sauvegardées pour `%s`" diff --git a/romfs/Text/IT.json b/romfs/Text/IT.json index f2a8d8d..e445119 100644 --- a/romfs/Text/IT.json +++ b/romfs/Text/IT.json @@ -1,6 +1,6 @@ { "BackupMenu": [ - "0: Nuovo backup" + "0: Nuovo Backup" ], "BackupMenuConfirmations": [ "0: Sei sicuro di voler sovrascrivere #%s#?", @@ -10,18 +10,18 @@ "BackupMenuPops": [ "0: I dati di salvataggio sono vuoti!", "1: Il backup è vuoto!", - "2: Errore durante il reset dei dati di salvataggio!", + "2: Errore nel reset dei dati di salvataggio!", "3: Errore nell'apertura del file ZIP in lettura!", "4: Errore durante l'eliminazione del backup!", - "5: Errore durante la creazione del backup!", - "6: La scrittura sul sistema è disabilitata!", - "7: Impossibile aprire il file ZIP in lettura!", - "8: Errore durante la scrittura del file meta dei dati di salvataggio!", + "5: Errore nella creazione del backup!", + "6: Scrittura sul sistema disabilitata!", + "7: Impossibile aprire il file zip in lettura!", + "8: Errore nella scrittura del file meta dei dati di salvataggio!", "9: Errore nel download del file!", - "10: Errore nell'upload del file!", - "11: Errore durante l'elaborazione dei metadati dei dati di salvataggio!", - "12: Errore durante la creazione della directory di destinazione!", - "13: Il backup deve essere un file ZIP per essere caricato!", + "10: Errore nel caricamento del file!", + "11: Errore nell'elaborazione dei meta dati del salvataggio!", + "12: Errore nella creazione della directory di destinazione!", + "13: Il backup deve essere un file zip per l'upload!", "14: Errore nel montaggio dei dati di salvataggio!", "15: Errore nella chiusura dei dati di salvataggio!" ], @@ -29,16 +29,16 @@ "0: Elaborazione del file meta dei dati di salvataggio..." ], "ControlGuides": [ - "0: [A] Seleziona [Y] Dumpa tutti i salvataggi [X] Opzioni utente", + "0: [A] Seleziona [Y] Esporta tutti i salvataggi [X] Opzioni utente", "1: [A] Seleziona [L] [R] Salta [Y] Preferito [X] Opzioni titolo [B] Indietro", "2: [A] Seleziona [Y] Ripristina [X] Elimina [ZR] Carica [B] Chiudi", - "3: [A] Alterna [X] Predefiniti [B] Indietro" + "3: [A] Attiva/Disattiva [X] Predefiniti [B] Indietro" ], "ExtrasMenu": [ "0: Reinizializza dati", - "1: Browser da SD a SD", + "1: Browser SD su SD", "2: ProdInfoF", - "3: Sicuro", + "3: Sicurezza", "4: Sistema", "5: Utente", "6: Termina processo" @@ -48,7 +48,7 @@ "1: Reinizializzazione dati fallita!" ], "GeneralPops": [ - "0: Impossibile uscire da JKSV mentre sono in esecuzione operazioni!" + "0: Impossibile uscire da JKSV mentre ci sono processi in esecuzione!" ], "GoogleDriveStrings": [ "0: Per continuare, vai su #%s# e inserisci >%s>!", @@ -61,16 +61,16 @@ "2: Quasi fatto! [A]" ], "IOStatuses": [ - "0: Copia di #%s# in corso...", - "1: Compressione di #%s# in ZIP...", - "2: Decompressione di #%s# da ZIP...", - "3: Eliminazione di #%s#...", - "4: Download di #%s#...", - "5: Upload di #%s# verso lo storage remoto...", - "6: Aggiornamento di #%s# sullo storage remoto..." + "0: Copiando #%s#...", + "1: Comprendo #%s# in ZIP...", + "2: Decomprimo #%s# da ZIP...", + "3: Eliminando #%s#...", + "4: Scaricando #%s#...", + "5: Caricando #%s# su storage remoto...", + "6: Aggiornando #%s# su storage remoto..." ], "IOPops": [ - "0: Errore nel commit dei dati sul dispositivo!" + "0: Errore durante la scrittura dei dati sul dispositivo!" ], "KeyboardStrings": [ "0: Inserisci un nuovo nome per il backup.", @@ -78,13 +78,13 @@ "2: Inserisci un nuovo percorso di output per JKSV", "3: Inserisci l'ID del processo da terminare.", "4: Inserisci un ID di salvataggio di sistema", - "5: Inserisci un nuovo nome per l'elemento di destinazione.", + "5: Inserisci un nuovo nome per l'elemento target.", "6: Inserisci un nome per la nuova cartella.", - "7: Inserisci un nuovo nome per la cartella di output per %s.", + "7: Inserisci un nuovo nome di cartella di output per %s.", "8: Inserisci quanto espandere (in MB)." ], "MainMenuConfs": [ - "0: Sei sicuro di voler fare il backup dei dati di salvataggio per tutti gli utenti su questo sistema? Potrebbe richiedere *molto* tempo!" + "0: Sei sicuro di voler fare il backup dei dati di salvataggio per ogni utente su questo sistema? Potrebbe richiedere *molto* tempo!" ], "MainMenuPops": [ "0: `%s` non ha dati di salvataggio!" @@ -94,7 +94,7 @@ "1: >Acceso>" ], "RemotePops": [ - "0: Connessione internet non disponibile!" + "0: Nessuna connessione internet disponibile!" ], "SaveCreatePops": [ "0: Dati di salvataggio creati per #%s#!", @@ -112,48 +112,51 @@ ], "SettingsDescriptions": [ "0: Imposta la directory di lavoro per JKSV. Il valore predefinito è `sdmc:/JKSV`.", - "1: Permette di rimuovere titoli dalla blacklist.", - "2: Include salvataggi di dispositivo, o condivisi, con gli utenti.", - "3: Crea un backup automaticamente quando si ripristina un altro.", - "4: Assegna automaticamente il nome ai backup e salta la tastiera.", + "1: Consente di rimuovere titoli dalla lista nera.", + "2: Include i salvataggi del dispositivo o condivisi con gli utenti.", + "3: Crea automaticamente un backup quando si ripristina un altro.", + "4: Nomina automaticamente i backup e salta la tastiera.", "5: Carica automaticamente i backup sul remoto e li elimina localmente.", "6: Usa sempre gli ID applicazione per i nomi delle cartelle di esportazione.", - "7: Richiede di tenere premuto [A] per tre secondi per cancellare i backup.", - "8: Richiede di tenere premuto [A] per tre secondi per ripristinare i backup.", - "9: Richiede di tenere premuto [A] per tre secondi per sovrascrivere i backup.", - "10: Mostra solo i dati di salvataggio che JKSV può aprire con successo.", + "7: Indica se è necessario tenere premuto [A] per tre secondi per eliminare i backup.", + "8: Indica se è necessario tenere premuto [A] per tre secondi per ripristinare i backup.", + "9: Indica se è necessario tenere premuto [A] per tre secondi per sovrascrivere i backup.", + "10: Mostra solo i dati di salvataggio che JKSV può aprire correttamente.", "11: Mostra i salvataggi di sistema che hanno un ID account associato.", - "12: Abilita il ripristino dei salvataggi di sistema e la scrittura nelle partizioni NAND.", - "13: Esporta i salvataggi in archivi ZIP invece di cartelle scompattate.", - "14: Livello di compressione o deflate usato nella scrittura ZIP. Il valore predefinito è 6. Valori più bassi sono più veloci ma offrono meno compressione e risparmio di spazio. Zero significa archivio, senza compressione.", - "15: Controlla il modo in cui i titoli sono ordinati e mostrati.", - "16: Mostra i titoli come menu di testo come il JKSM originale su 3DS invece di griglie di icone.", - "17: Forza l’inglese come lingua invece della lingua di sistema rilevata.", - "18: Sposta i backup cancellati nella cartella _TRASH_ invece di eliminarli definitivamente.", + "12: Consente di ripristinare i salvataggi di sistema e scrivere nelle partizioni NAND.", + "13: Esporta i dati di salvataggio in archivi ZIP invece che in cartelle estratte.", + "14: Livello di compressione o deflate usato quando si scrive in ZIP. Il valore predefinito è 6. Valori più bassi sono più veloci, ma offrono meno compressione e risparmio di spazio. Zero significa memorizzazione senza compressione.", + "15: Controlla come i titoli sono ordinati e visualizzati.", + "16: Visualizza i titoli come menu di testo come l’originale JKSM su 3DS invece che come griglie di icone.", + "17: Forza l’uso dell’inglese come lingua invece della lingua di sistema rilevata.", + "18: Sposta i backup eliminati nella cartella _TRASH_ invece di eliminarli permanentemente.", "19: Imposta la velocità con cui avvengono transizioni e animazioni. Più basso è più veloce." ], "SettingsMenu": [ "0: Imposta la cartella di output di JKSV.", - "1: Modifica blacklist", - "2: Includi salvataggi dispositivo con gli utenti: %s", + "1: Modifica la lista nera", + "2: Includi salvataggi dispositivo con utenti: %s", "3: Backup automatico al ripristino: %s", - "4: Nome automatico dei backup: %s", - "5: Upload automatico dei backup su storage remoto: %s", + "4: Nome automatico per i backup: %s", + "5: Caricamento automatico backup su storage remoto: %s", "6: Usa sempre ID applicazione: %s", - "7: Tieni premuto per cancellare backup: %s", - "8: Tieni premuto per ripristinare backup: %s", - "9: Tieni premuto per sovrascrivere backup: %s", + "7: Tieni premuto per eliminare i backup: %s", + "8: Tieni premuto per ripristinare i backup: %s", + "9: Tieni premuto per sovrascrivere i backup: %s", "10: Mostra solo titoli montabili: %s", - "11: Mostra salvataggi di sistema con account: %s", - "12: Abilita scrittura su salvataggi sistema e NAND: %s", - "13: Esporta salvataggi in ZIP: %s", + "11: Mostra salvataggi sistema con account: %s", + "12: Abilita scrittura su salvataggi di sistema e NAND: %s", + "13: Esporta i salvataggi in ZIP: %s", "14: Livello compressione ZIP: %u", - "15: Tipo di ordinamento titoli: %s", - "16: Modalità menu testo (JKSM): %s", + "15: Tipo ordinamento titoli: %s", + "16: Modalità menu testuale (JKSM): %s", "17: Forza inglese: %s", "18: Abilita cestino: %s", "19: Scala animazioni: %.02f" ], + "SettingsPops": [ + "0: La lista nera è vuota!" + ], "SortTypes": [ "0: Alfabetico", "1: Più giocati", @@ -162,48 +165,48 @@ "TitleInfo": [ "0: ID App: %016lX", "1: ID Salvataggio: %016lx", - "2: Prima esecuzione: %x - %X", - "3: Ultima esecuzione: %x - %X", + "2: Prima partita: %x - %X", + "3: Ultima partita: %x - %X", "4: Tempo di gioco: %02d:%02d:%02d", "5: Avvii: %i", "6: Tipo di salvataggio: %s" ], "TitleOptionConfirmations": [ - "0: Sei sicuro di voler aggiungere #%s# alla blacklist? Una volta fatto, non apparirà più in nessuna lista o selezione.", - "1: Sei sicuro di voler cancellare tutti i backup attuali per #%s#? *Questa azione non può essere annullata!*", - "2: Sei sicuro di voler resettare i dati di salvataggio per #%s#? *Questo eliminerà i dati attuali come se il titolo non fosse mai stato avviato!*", - "3: Sei sicuro di voler cancellare i dati di salvataggio di `%s` per #%s#? *Questa azione li eliminerà definitivamente dal sistema.*" + "0: Sei sicuro di voler aggiungere #%s# alla lista nera? Una volta fatto, non apparirà più in nessuna lista o selezione di titoli.", + "1: Sei sicuro di voler eliminare tutti i backup attuali per #%s#? *Questa operazione non può essere annullata!*", + "2: Sei sicuro di voler resettare i dati di salvataggio per #%s#? *Questo eliminerà i dati attuali come se il titolo non fosse mai stato eseguito!*", + "3: Sei sicuro di voler eliminare i dati di salvataggio di `%s` per #%s#? *Questi saranno eliminati permanentemente dal sistema.*" ], "TitleOptionPops": [ "0: Tutti i backup eliminati per #%s#!", - "1: Fallito nell’eliminare tutti i backup!", - "2: Errore nel resettare i dati di salvataggio!", + "1: Eliminazione di tutti i backup fallita!", + "2: Errore nel reset dei dati di salvataggio!", "3: Dati di salvataggio resettati con successo!", "4: File SVI esportato con successo!", "5: Errore nell’esportazione del file SVI!", "6: Questa opzione non è disponibile per i salvataggi di sistema!", "7: Impossibile sanificare il percorso per l’uso!", "8: Cartella di output impostata su #%s#.", - "9: Errore nell’impostare il nuovo percorso di output!", + "9: Errore nell’impostazione del nuovo percorso di output!", "10: Dati di salvataggio estesi con successo!", - "11: Fallito nell’estendere i dati di salvataggio!" + "11: Estensione dei dati di salvataggio fallita!" ], "TitleOptionStatus": [ "0: Eliminazione di tutti i backup per #%s#.", - "1: Resettaggio dei dati di salvataggio per #%s#.", - "2: Eliminazione dei dati di salvataggio di `%s` per #%s#...", - "3: Estensione dei dati di salvataggio di `%s` per #%s#..." + "1: Resettando i dati di salvataggio per #%s#.", + "2: Eliminazione dei dati di `%s` per #%s#...", + "3: Estendendo i dati di `%s` per #%s#..." ], "TitleOptions": [ "0: Informazioni", - "1: Lista nera", + "1: Lista nera titolo", "2: Cambia cartella di output", "3: Apri in modalità file", "4: Elimina tutti i backup locali", "5: Elimina tutti i backup remoti", - "6: Resetta dati di salvataggio", - "7: Elimina dati di salvataggio dal sistema", - "8: Estendi dati di salvataggio", + "6: Resetta i dati di salvataggio.", + "7: Elimina i dati di salvataggio dal sistema", + "8: Estendi i dati di salvataggio", "9: Esporta file SVI" ], "TranslationInfo": [ @@ -211,16 +214,16 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: Sei sicuro di voler fare il backup di tutti i dati per `%s`? Potrebbe richiedere un po’ di tempo.", - "1: Sei sicuro di voler creare dati di salvataggio per tutti i titoli trovati nel sistema per `%s`? Potrebbe richiedere un po’ di tempo.", - "2: Sei sicuro di voler eliminare tutti i dati di salvataggio per `%s`? Questa è un’azione *PERMANENTE* e non reversibile." + "0: Sei sicuro di voler fare il backup dei dati di salvataggio per tutti i titoli trovati per `%s`? Questo potrebbe richiedere un po' di tempo.", + "1: Sei sicuro di voler creare dati di salvataggio per tutti i titoli trovati sul tuo sistema per `%s`? Questo potrebbe richiedere un po' di tempo.", + "2: Sei sicuro di voler eliminare tutti i dati di salvataggio per `%s`? Questa operazione è *PERMANENTE* e non può essere annullata." ], "UserOptionStatus": [ "0: Creazione dati di salvataggio per #%s#...", "1: Eliminazione dati di salvataggio per #%s#..." ], "UserOptions": [ - "0: Dumpa tutto per `%s`", + "0: Esporta tutto per `%s`", "1: Crea dati di salvataggio per `%s`", "2: Crea tutti i dati di salvataggio per `%s`", "3: Elimina tutti i dati di salvataggio per `%s`" diff --git a/romfs/Text/JA.json b/romfs/Text/JA.json index adba2fe..ecd46ea 100644 --- a/romfs/Text/JA.json +++ b/romfs/Text/JA.json @@ -3,39 +3,39 @@ "0: 新しいバックアップ" ], "BackupMenuConfirmations": [ - "0: #%s# を上書きしてもよろしいですか?", - "1: #%s# を復元してもよろしいですか?", - "2: #%s# を削除してもよろしいですか?" + "0: 本当に #%s# を上書きしてもよろしいですか?", + "1: 本当に #%s# を復元してもよろしいですか?", + "2: 本当に #%s# を削除してもよろしいですか?" ], "BackupMenuPops": [ "0: セーブデータが空です!", "1: バックアップが空です!", - "2: セーブデータのリセットに失敗しました!", + "2: セーブデータのリセット中にエラーが発生しました!", "3: ZIPファイルの読み込みエラー!", "4: バックアップの削除中にエラーが発生しました!", "5: バックアップの作成中にエラーが発生しました!", - "6: システムへの書き込みが無効になっています!", - "7: ZIPの読み込みができません!", + "6: システムへの書き込みは無効です!", + "7: ZIPファイルを開くことができません!", "8: セーブメタデータファイルの書き込みエラー!", - "9: ファイルのダウンロードに失敗しました!", - "10: ファイルのアップロードに失敗しました!", - "11: セーブデータメタの処理中にエラーが発生しました!", - "12: ターゲットディレクトリの作成に失敗しました!", - "13: アップロードするバックアップはZIPでなければなりません!", - "14: セーブデータのマウントに失敗しました!", - "15: セーブデータのクローズに失敗しました!" + "9: ファイルのダウンロードエラー!", + "10: ファイルのアップロードエラー!", + "11: セーブデータメタの処理エラー!", + "12: 対象ディレクトリの作成エラー!", + "13: アップロードにはバックアップがZIPである必要があります!", + "14: セーブデータのマウントエラー!", + "15: セーブデータのクローズエラー!" ], "BackupMenuStatus": [ - "0: セーブメタファイルを処理中..." + "0: セーブデータメタファイルを処理中..." ], "ControlGuides": [ - "0: [A] 選択 [Y] すべてダンプ [X] ユーザーオプション", + "0: [A] 選択 [Y] すべてのセーブをダンプ [X] ユーザーオプション", "1: [A] 選択 [L] [R] ジャンプ [Y] お気に入り [X] タイトルオプション [B] 戻る", "2: [A] 選択 [Y] 復元 [X] 削除 [ZR] アップロード [B] 閉じる", "3: [A] トグル [X] デフォルト [B] 戻る" ], "ExtrasMenu": [ - "0: データ再初期化", + "0: データの再初期化", "1: SDからSDブラウザへ", "2: ProdInfoF", "3: セーフ", @@ -51,14 +51,14 @@ "0: タスク実行中はJKSVを終了できません!" ], "GoogleDriveStrings": [ - "0: 続行するには #%s# にアクセスし、>%s< を入力してください!", - "1: Google Driveにサインインしました!", - "2: Google Driveのサインインに失敗しました!" + "0: 続行するには、 #%s# にアクセスし >%s> を入力してください!", + "1: Googleドライブへのサインインに成功しました!", + "2: Googleドライブへのサインインに失敗しました!" ], "HoldingStrings": [ - "0: [A]を押し続けて", - "1: [A]を押し続けています", - "2: もう少し![A]" + "0: [A] を押し続ける", + "1: [A] を押し続けてください", + "2: もう少しです![A]" ], "IOStatuses": [ "0: #%s# をコピー中...", @@ -75,31 +75,31 @@ "KeyboardStrings": [ "0: 新しいバックアップ名を入力してください。", "1: キャッシュインデックスを入力してください。", - "2: JKSVの新しい出力パスを入力してください。", + "2: JKSVの新しい出力パスを入力してください", "3: 終了するプロセスIDを入力してください。", - "4: システムセーブIDを入力してください。", + "4: システムセーブIDを入力してください", "5: 対象アイテムの新しい名前を入力してください。", - "6: 新しいフォルダ名を入力してください。", - "7: %s の新しい出力フォルダ名を入力してください。", - "8: 拡張サイズをMB単位で入力してください。" + "6: 新しいフォルダー名を入力してください。", + "7: %s の新しい出力フォルダー名を入力してください。", + "8: 拡張量をMB単位で入力してください。" ], "MainMenuConfs": [ - "0: システム上のすべてのユーザーのセーブデータをバックアップしてもよろしいですか?非常に時間がかかることがあります!" + "0: このシステム上の全ユーザーのセーブデータをバックアップしてもよろしいですか?非常に時間がかかる場合があります!" ], "MainMenuPops": [ - "0: `%s` にはセーブデータがありません!" + "0: `%s` はセーブデータがありません!" ], "OnOff": [ "0: オフ", "1: >オン>" ], "RemotePops": [ - "0: インターネット接続がありません!" + "0: インターネット接続が利用できません!" ], "SaveCreatePops": [ - "0: #%s# のセーブデータを作成しました!", - "1: セーブデータの作成に失敗しました!", - "2: セーブデータの削除に失敗しました!" + "0: #%s# のセーブデータが作成されました!", + "1: セーブデータの作成エラー!", + "2: セーブデータの削除エラー!" ], "SaveDataTypes": [ "0: システム", @@ -111,96 +111,99 @@ "6: システムBCAT" ], "SettingsDescriptions": [ - "0: JKSVの作業ディレクトリを設定します。デフォルトは `sdmc:/JKSV` です。", - "1: ブラックリストからタイトルを削除できるようにします。", - "2: デバイスまたは共有セーブをユーザーと一緒に含めます。", - "3: 他のバックアップを復元するときに自動でバックアップを作成します。", - "4: バックアップ名を自動で設定し、キーボードをスキップします。", - "5: バックアップを自動でリモートにアップロードし、ローカルから削除します。", + "0: JKSVの作業ディレクトリを設定します。デフォルト値は `sdmc:/JKSV` です。", + "1: ブラックリストからタイトルを削除できます。", + "2: デバイスまたは共有セーブをユーザーと共に含めます。", + "3: 別のセーブを復元するときに自動でバックアップを作成します。", + "4: バックアップの自動命名とキーボードスキップを有効にします。", + "5: バックアップをリモートに自動アップロードし、ローカルから削除します。", "6: エクスポートフォルダ名に常にアプリケーションIDを使用します。", - "7: バックアップを削除するには[A]を3秒間押し続ける必要があります。", - "8: バックアップを復元するには[A]を3秒間押し続ける必要があります。", - "9: バックアップを上書きするには[A]を3秒間押し続ける必要があります。", + "7: バックアップを削除するには[A]を3秒間押す必要があるかどうか。", + "8: バックアップを復元するには[A]を3秒間押す必要があるかどうか。", + "9: バックアップを上書きするには[A]を3秒間押す必要があるかどうか。", "10: JKSVが正常に開けるセーブデータのみ表示します。", - "11: アカウントIDが紐づいたシステムセーブを表示します。", + "11: アカウントIDに紐づくシステムセーブを表示します。", "12: システムセーブの復元とNANDパーティションへの書き込みを有効にします。", - "13: セーブデータをZIPアーカイブとしてエクスポートします(展開済みフォルダではありません)。", - "14: ZIP書き込み時の圧縮レベル。デフォルトは6。低いほど高速ですが、圧縮率は低くなります。0は非圧縮(ストア)。", - "15: タイトルの並び順と表示方法を制御します。", - "16: 3DSのJKSMのようにタイトルをアイコングリッドではなくテキストメニューで表示します。", - "17: システムの言語設定ではなく英語を強制的に使用します。", - "18: 削除したバックアップを完全削除せずに _TRASH_ フォルダに移動します。", - "19: トランジションやアニメーションの速度を設定します。数値が小さいほど高速。" + "13: セーブデータを展開フォルダーではなくZIPアーカイブにエクスポートします。", + "14: ZIP書き込み時の圧縮レベル。デフォルトは6。低いほど高速ですが圧縮率と節約容量は低くなります。0は無圧縮です。", + "15: タイトルのソートおよび表示方法を制御します。", + "16: タイトルを3DSのJKSMのようにアイコングリッドではなくテキストメニューとして表示します。", + "17: システム言語ではなく英語を強制使用します。", + "18: 削除したバックアップを永久削除ではなく_TRASH_フォルダーに移動します。", + "19: トランジションとアニメーションの速度を設定します。数値が小さいほど高速です。" ], "SettingsMenu": [ - "0: JKSVの出力フォルダを設定します。", - "1: ブラックリスト編集", - "2: ユーザーと一緒にデバイスセーブを含める: %s", + "0: JKSVの出力フォルダーを設定します。", + "1: ブラックリストを編集", + "2: ユーザーとデバイスセーブを含める: %s", "3: 復元時に自動バックアップ: %s", "4: バックアップの自動命名: %s", - "5: バックアップの自動アップロード: %s", + "5: バックアップをリモートに自動アップロード: %s", "6: 常にアプリケーションIDを使用: %s", - "7: バックアップ削除時に保持: %s", - "8: バックアップ復元時に保持: %s", - "9: バックアップ上書き時に保持: %s", + "7: バックアップを削除するには長押し: %s", + "8: バックアップを復元するには長押し: %s", + "9: バックアップを上書きするには長押し: %s", "10: マウント可能なタイトルのみ表示: %s", - "11: アカウントシステムセーブ表示: %s", - "12: システムセーブおよびNANDへの書き込みを有効: %s", - "13: ZIPでエクスポート: %s", + "11: アカウントシステムセーブを表示: %s", + "12: システムセーブとNANDへの書き込みを有効にする: %s", + "13: セーブをZIPにエクスポート: %s", "14: ZIP圧縮レベル: %u", - "15: タイトルの並び替えタイプ: %s", + "15: タイトルソートタイプ: %s", "16: テキストメニューモード(JKSM): %s", "17: 英語を強制: %s", - "18: ごみ箱を有効: %s", + "18: ゴミ箱を有効にする: %s", "19: アニメーションスケーリング: %.02f" ], + "SettingsPops": [ + "0: ブラックリストは空です!" + ], "SortTypes": [ "0: アルファベット順", - "1: プレイ回数順", - "2: 最終プレイ日順" + "1: よく遊ばれている", + "2: 最後に遊んだ" ], "TitleInfo": [ "0: アプリID: %016lX", "1: セーブID: %016lx", - "2: 初回プレイ: %x - %X", + "2: 初プレイ: %x - %X", "3: 最終プレイ: %x - %X", "4: プレイ時間: %02d:%02d:%02d", "5: 起動回数: %i", "6: セーブタイプ: %s" ], "TitleOptionConfirmations": [ - "0: #%s# をブラックリストに追加してもよろしいですか?追加するとタイトル一覧や選択から表示されなくなります。", - "1: #%s# の現在のバックアップをすべて削除してもよろしいですか?*取り消せません!*", - "2: #%s# のセーブデータをリセットしてもよろしいですか?*タイトルを初めて起動した時の状態になります!*", - "3: `%s` の #%s# のセーブデータを削除してもよろしいですか?*システムから完全に削除されます。*" + "0: #%s# をブラックリストに追加してもよろしいですか?追加するとタイトルリストや選択に表示されなくなります。", + "1: #%s# の現在のバックアップをすべて削除してもよろしいですか?*これは元に戻せません!*", + "2: #%s# のセーブデータをリセットしてもよろしいですか?*これにより、タイトルが起動されていなかったかのようにデータが削除されます!*", + "3: `%s` の #%s# のセーブデータを削除してもよろしいですか?*これはシステムから完全に削除されます。*" ], "TitleOptionPops": [ - "0: #%s# のバックアップをすべて削除しました!", - "1: バックアップの削除に失敗しました!", - "2: セーブデータのリセットに失敗しました!", + "0: #%s# のすべてのバックアップを削除しました!", + "1: すべてのバックアップの削除に失敗しました!", + "2: セーブデータリセット中にエラーが発生しました!", "3: セーブデータを正常にリセットしました!", "4: SVIファイルを正常にエクスポートしました!", "5: SVIファイルのエクスポートに失敗しました!", - "6: このオプションはシステムセーブには利用できません!", - "7: 使用できるようにパスのサニタイズに失敗しました!", - "8: 出力フォルダを #%s# に設定しました。", + "6: システムセーブにはこのオプションは利用できません!", + "7: 使用するためのパスのサニタイズに失敗しました!", + "8: 出力フォルダーを #%s# に設定しました。", "9: 新しい出力パスの設定に失敗しました!", - "10: セーブデータの拡張に成功しました!", + "10: セーブデータを正常に拡張しました!", "11: セーブデータの拡張に失敗しました!" ], "TitleOptionStatus": [ - "0: #%s# のバックアップをすべて削除中。", + "0: #%s# のすべてのバックアップを削除中。", "1: #%s# のセーブデータをリセット中。", - "2: `%s` の #%s# のセーブデータを削除中…", - "3: `%s` の #%s# のセーブデータを拡張中…" + "2: `%s` の #%s# のセーブデータを削除中...", + "3: `%s` の #%s# のセーブデータを拡張中..." ], "TitleOptions": [ "0: 情報", - "1: ブラックリストに追加", - "2: 出力フォルダを変更", + "1: タイトルをブラックリストに追加", + "2: 出力フォルダーを変更", "3: ファイルモードで開く", - "4: ローカルバックアップをすべて削除", - "5: リモートバックアップをすべて削除", + "4: すべてのローカルバックアップを削除", + "5: すべてのリモートバックアップを削除", "6: セーブデータをリセット", "7: システムからセーブデータを削除", "8: セーブデータを拡張", @@ -211,13 +214,13 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: `%s` の全タイトルのセーブデータをバックアップしてもよろしいですか?時間がかかる場合があります。", - "1: `%s` のシステム上の全タイトルのセーブデータを作成してもよろしいですか?時間がかかる場合があります。", - "2: `%s` のセーブデータをすべて削除してもよろしいですか?*この操作は永久的で元に戻せません。*" + "0: `%s` のすべてのタイトルのセーブデータをバックアップしてもよろしいですか?時間がかかる場合があります。", + "1: `%s` のすべてのタイトルのセーブデータを作成してもよろしいですか?時間がかかる場合があります。", + "2: `%s` のすべてのセーブデータを削除してもよろしいですか?*これは永久的な操作で元に戻せません。*" ], "UserOptionStatus": [ - "0: #%s# のセーブデータを作成中…", - "1: #%s# のセーブデータを削除中…" + "0: #%s# のセーブデータを作成中...", + "1: #%s# のセーブデータを削除中..." ], "UserOptions": [ "0: `%s` のすべてをダンプ", @@ -226,8 +229,8 @@ "3: `%s` のすべてのセーブデータを削除" ], "WebDavStrings": [ - "0: WebDavの起動に成功しました!", - "1: WebDavの起動に失敗しました!" + "0: WebDavが正常に開始されました!", + "1: WebDavが失敗しました!" ], "YesNo": [ "0: はい [A]", diff --git a/romfs/Text/KO.json b/romfs/Text/KO.json index 901ec25..45e163d 100644 --- a/romfs/Text/KO.json +++ b/romfs/Text/KO.json @@ -3,25 +3,25 @@ "0: 새 백업" ], "BackupMenuConfirmations": [ - "0: #%s# 을(를) 덮어쓰시겠습니까?", - "1: #%s# 을(를) 복원하시겠습니까?", - "2: #%s# 을(를) 삭제하시겠습니까?" + "0: #%s#을 정말 덮어쓰시겠습니까?", + "1: #%s#을 정말 복원하시겠습니까?", + "2: #%s#을 정말 삭제하시겠습니까?" ], "BackupMenuPops": [ "0: 저장 데이터가 비어 있습니다!", "1: 백업이 비어 있습니다!", - "2: 저장 데이터 초기화 오류!", - "3: ZIP 파일을 읽는 중 오류 발생!", + "2: 저장 데이터 재설정 오류!", + "3: ZIP 파일 읽기 오류!", "4: 백업 삭제 중 오류 발생!", - "5: 백업 생성 중 오류 발생!", - "6: 시스템에 쓰기가 비활성화되어 있습니다!", + "5: 백업 생성 오류!", + "6: 시스템 쓰기가 비활성화되어 있습니다!", "7: ZIP 읽기 불가!", - "8: 저장 메타 데이터 파일 쓰기 오류!", + "8: 저장 메타데이터 파일 쓰기 오류!", "9: 파일 다운로드 오류!", "10: 파일 업로드 오류!", "11: 저장 데이터 메타 처리 오류!", "12: 대상 디렉터리 생성 오류!", - "13: 업로드할 백업은 ZIP이어야 합니다!", + "13: 업로드하려면 백업이 ZIP이어야 합니다!", "14: 저장 데이터 마운트 오류!", "15: 저장 데이터 닫기 오류!" ], @@ -32,13 +32,13 @@ "0: [A] 선택 [Y] 모든 저장 덤프 [X] 사용자 옵션", "1: [A] 선택 [L] [R] 점프 [Y] 즐겨찾기 [X] 타이틀 옵션 [B] 뒤로", "2: [A] 선택 [Y] 복원 [X] 삭제 [ZR] 업로드 [B] 닫기", - "3: [A] 전환 [X] 기본값 [B] 뒤로" + "3: [A] 토글 [X] 기본값 [B] 뒤로" ], "ExtrasMenu": [ "0: 데이터 재초기화", - "1: SD에서 SD 브라우저로", + "1: SD to SD 브라우저", "2: ProdInfoF", - "3: 안전 모드", + "3: 안전", "4: 시스템", "5: 사용자", "6: 프로세스 종료" @@ -48,26 +48,26 @@ "1: 데이터 재초기화 실패!" ], "GeneralPops": [ - "0: 작업이 실행 중일 때 JKSV를 종료할 수 없습니다!" + "0: 작업 실행 중에는 JKSV를 종료할 수 없습니다!" ], "GoogleDriveStrings": [ - "0: 계속하려면 #%s# 로 가서 >%s< 를 입력하세요!", - "1: Google Drive 로그인 성공!", - "2: Google Drive 로그인 실패!" + "0: 계속하려면 #%s#로 가서 >%s>를 입력하세요!", + "1: Google 드라이브 로그인 성공!", + "2: Google 드라이브 로그인 실패!" ], "HoldingStrings": [ - "0: [A] 버튼을 누르고 있기", - "1: 계속 [A] 버튼 누르고 있기", + "0: [A] 길게 누르기", + "1: [A] 계속 길게 누르기", "2: 거의 완료! [A]" ], "IOStatuses": [ "0: #%s# 복사 중...", - "1: #%s# 을 ZIP으로 압축 중...", - "2: #%s# 을 ZIP에서 압축 해제 중...", + "1: #%s# ZIP 압축 중...", + "2: #%s# ZIP에서 압축 해제 중...", "3: #%s# 삭제 중...", "4: #%s# 다운로드 중...", - "5: #%s# 을 원격 저장소에 업로드 중...", - "6: #%s# 을 원격 저장소에서 업데이트 중..." + "5: #%s# 원격 저장소로 업로드 중...", + "6: #%s# 원격 저장소에서 업데이트 중..." ], "IOPops": [ "0: 장치에 데이터 커밋 오류!" @@ -80,26 +80,26 @@ "4: 시스템 저장 ID를 입력하세요.", "5: 대상 항목의 새 이름을 입력하세요.", "6: 새 폴더 이름을 입력하세요.", - "7: %s 의 새 출력 폴더 이름을 입력하세요.", - "8: 확장할 용량을 MB 단위로 입력하세요." + "7: %s의 새 출력 폴더 이름을 입력하세요.", + "8: 확장할 용량(MB 단위)을 입력하세요." ], "MainMenuConfs": [ - "0: 시스템의 모든 사용자의 저장 데이터를 백업하시겠습니까? 매우 오래 걸릴 수 있습니다!" + "0: 이 시스템의 모든 사용자 저장 데이터를 백업하시겠습니까? 매우 오래 걸릴 수 있습니다!" ], "MainMenuPops": [ - "0: `%s` 에 저장 데이터가 없습니다!" + "0: `%s`에 저장 데이터가 없습니다!" ], "OnOff": [ - "0: 꺼짐", - "1: >켜짐>" + "0: 끔", + "1: >켬>" ], "RemotePops": [ "0: 인터넷 연결이 없습니다!" ], "SaveCreatePops": [ - "0: #%s# 에 대한 저장 데이터가 생성되었습니다!", - "1: 저장 데이터 생성 실패!", - "2: 저장 데이터 삭제 실패!" + "0: #%s#에 저장 데이터가 생성되었습니다!", + "1: 저장 데이터 생성 오류!", + "2: 저장 데이터 삭제 오류!" ], "SaveDataTypes": [ "0: 시스템", @@ -111,53 +111,56 @@ "6: 시스템 BCAT" ], "SettingsDescriptions": [ - "0: JKSV 작업 디렉터리를 설정합니다. 기본값은 `sdmc:/JKSV` 입니다.", + "0: JKSV 작업 디렉터리를 설정합니다. 기본값은 `sdmc:/JKSV`입니다.", "1: 블랙리스트에서 타이틀을 제거할 수 있습니다.", - "2: 장치 저장 데이터 또는 공유 저장 데이터를 사용자와 함께 포함합니다.", - "3: 다른 백업을 복원할 때 자동으로 백업을 만듭니다.", + "2: 장치 또는 공유 저장 데이터를 사용자와 함께 포함합니다.", + "3: 다른 백업을 복원할 때 자동으로 백업을 생성합니다.", "4: 백업 이름을 자동으로 지정하고 키보드를 건너뜁니다.", "5: 백업을 원격 저장소에 자동으로 업로드하고 로컬에서 삭제합니다.", "6: 내보내기 폴더 이름에 항상 애플리케이션 ID를 사용합니다.", - "7: 백업 삭제 시 3초간 [A] 버튼을 누르고 있어야 합니다.", - "8: 백업 복원 시 3초간 [A] 버튼을 누르고 있어야 합니다.", - "9: 백업 덮어쓰기 시 3초간 [A] 버튼을 누르고 있어야 합니다.", - "10: JKSV가 정상적으로 열 수 있는 저장 데이터만 표시합니다.", - "11: 계정 ID가 연결된 시스템 저장 데이터를 표시합니다.", - "12: 시스템 저장 데이터 복원 및 NAND 파티션 쓰기를 활성화합니다.", - "13: 저장 데이터를 압축해제된 폴더 대신 ZIP 아카이브로 내보냅니다.", - "14: ZIP 작성 시 압축 또는 디플레이트 레벨입니다. 기본값은 6입니다. 낮을수록 빠르지만 압축률은 낮습니다. 0은 저장, 즉 압축 없음입니다.", + "7: 백업 삭제 시 [A]를 3초간 누르고 있어야 하는지 여부입니다.", + "8: 백업 복원 시 [A]를 3초간 누르고 있어야 하는지 여부입니다.", + "9: 백업 덮어쓰기 시 [A]를 3초간 누르고 있어야 하는지 여부입니다.", + "10: JKSV가 성공적으로 열 수 있는 저장 데이터만 표시합니다.", + "11: 계정 ID가 연결된 시스템 저장을 표시합니다.", + "12: 시스템 저장 복원 및 NAND 파티션 쓰기를 활성화합니다.", + "13: 저장 데이터를 풀린 폴더 대신 ZIP 아카이브로 내보냅니다.", + "14: ZIP 작성 시 사용하는 압축 수준입니다. 기본값은 6입니다. 낮을수록 빠르지만 압축률과 공간 절약이 적습니다. 0은 저장, 즉 압축하지 않음입니다.", "15: 타이틀 정렬 및 표시 방식을 제어합니다.", - "16: 3DS의 JKSM과 같이 아이콘 그리드 대신 텍스트 메뉴로 타이틀을 표시합니다.", - "17: 감지된 시스템 언어 대신 영어를 강제로 사용합니다.", + "16: 원래 JKSM처럼 아이콘 그리드 대신 텍스트 메뉴로 타이틀을 표시합니다.", + "17: 감지된 시스템 언어 대신 영어 사용을 강제합니다.", "18: 삭제된 백업을 영구 삭제하지 않고 _TRASH_ 폴더로 이동합니다.", "19: 전환 및 애니메이션 속도를 설정합니다. 낮을수록 빠릅니다." ], "SettingsMenu": [ - "0: JKSV 출력 폴더를 설정합니다.", + "0: JKSV 출력 폴더 설정.", "1: 블랙리스트 편집", - "2: 사용자와 함께 장치 저장 데이터 포함: %s", + "2: 사용자와 장치 저장 포함: %s", "3: 복원 시 자동 백업: %s", "4: 백업 자동 이름 지정: %s", - "5: 원격 저장소로 백업 자동 업로드: %s", + "5: 백업을 원격 저장소로 자동 업로드: %s", "6: 항상 애플리케이션 ID 사용: %s", - "7: 백업 삭제 시 누르기: %s", - "8: 백업 복원 시 누르기: %s", - "9: 백업 덮어쓰기 시 누르기: %s", + "7: 백업 삭제 시 길게 누르기: %s", + "8: 백업 복원 시 길게 누르기: %s", + "9: 백업 덮어쓰기 시 길게 누르기: %s", "10: 마운트 가능한 타이틀만 표시: %s", - "11: 계정 시스템 저장 데이터 표시: %s", + "11: 계정 시스템 저장 표시: %s", "12: 시스템 저장 및 NAND 쓰기 활성화: %s", - "13: ZIP으로 저장 데이터 내보내기: %s", - "14: ZIP 압축 레벨: %u", + "13: 저장을 ZIP으로 내보내기: %s", + "14: ZIP 압축 수준: %u", "15: 타이틀 정렬 유형: %s", - "16: 텍스트 메뉴(JKSM) 모드: %s", + "16: 텍스트 메뉴 (JKSM) 모드: %s", "17: 영어 강제 사용: %s", - "18: 휴지통 사용: %s", + "18: 휴지통 활성화: %s", "19: 애니메이션 스케일링: %.02f" ], + "SettingsPops": [ + "0: 블랙리스트가 비어 있습니다!" + ], "SortTypes": [ "0: 알파벳순", - "1: 가장 많이 플레이한 순", - "2: 마지막 플레이 순" + "1: 가장 많이 플레이함", + "2: 마지막으로 플레이함" ], "TitleInfo": [ "0: 앱 ID: %016lX", @@ -169,39 +172,39 @@ "6: 저장 유형: %s" ], "TitleOptionConfirmations": [ - "0: #%s# 을 블랙리스트에 추가하시겠습니까? 추가하면 타이틀 목록이나 선택에서 더 이상 표시되지 않습니다.", - "1: #%s# 의 현재 백업을 모두 삭제하시겠습니까? *이 작업은 취소할 수 없습니다!*", - "2: #%s# 의 저장 데이터를 초기화하시겠습니까? *이 작업은 타이틀이 처음 실행된 것처럼 저장 데이터를 삭제합니다!*", - "3: `%s` 의 #%s# 저장 데이터를 삭제하시겠습니까? *시스템에서 영구적으로 삭제됩니다.*" + "0: #%s#을 블랙리스트에 추가하시겠습니까? 추가하면 타이틀 목록이나 선택에서 더 이상 나타나지 않습니다.", + "1: #%s#의 현재 모든 백업을 삭제하시겠습니까? *이 작업은 되돌릴 수 없습니다!*", + "2: #%s#의 저장 데이터를 재설정하시겠습니까? *이 작업은 제목이 실행되지 않은 것처럼 현재 저장 데이터를 삭제합니다!*", + "3: `%s`의 #%s# 저장 데이터를 삭제하시겠습니까? *이 작업은 시스템에서 영구적으로 삭제합니다.*" ], "TitleOptionPops": [ - "0: #%s# 의 모든 백업이 삭제되었습니다!", + "0: #%s#의 모든 백업을 삭제했습니다!", "1: 모든 백업 삭제 실패!", - "2: 저장 데이터 초기화 실패!", - "3: 저장 데이터가 성공적으로 초기화되었습니다!", - "4: SVI 파일이 성공적으로 내보내졌습니다!", - "5: SVI 파일 내보내기 실패!", - "6: 이 옵션은 시스템 저장 데이터에는 사용할 수 없습니다!", - "7: 사용 가능한 경로로 변환할 수 없습니다!", - "8: 출력 폴더가 #%s# 로 설정되었습니다.", - "9: 새 출력 경로 설정 실패!", - "10: 저장 데이터가 성공적으로 확장되었습니다!", + "2: 저장 데이터 재설정 오류!", + "3: 저장 데이터 재설정 성공!", + "4: SVI 파일 성공적으로 내보내기 완료!", + "5: SVI 파일 내보내기 오류!", + "6: 시스템 저장에 대해 이 옵션을 사용할 수 없습니다!", + "7: 사용을 위한 경로 정리 실패!", + "8: 출력 폴더가 #%s#로 설정되었습니다.", + "9: 새 출력 경로 설정 오류!", + "10: 저장 데이터 확장 성공!", "11: 저장 데이터 확장 실패!" ], "TitleOptionStatus": [ - "0: #%s# 의 모든 백업을 삭제 중입니다.", - "1: #%s# 의 저장 데이터를 초기화 중입니다.", - "2: `%s` 의 #%s# 저장 데이터를 삭제 중입니다...", - "3: `%s` 의 #%s# 저장 데이터를 확장 중입니다..." + "0: #%s#의 모든 백업 삭제 중.", + "1: #%s#의 저장 데이터 재설정 중.", + "2: `%s`의 #%s# 저장 데이터 삭제 중...", + "3: `%s`의 #%s# 저장 데이터 확장 중..." ], "TitleOptions": [ "0: 정보", - "1: 블랙리스트에 추가", + "1: 타이틀 블랙리스트", "2: 출력 폴더 변경", "3: 파일 모드로 열기", "4: 모든 로컬 백업 삭제", "5: 모든 원격 백업 삭제", - "6: 저장 데이터 초기화", + "6: 저장 데이터 재설정", "7: 시스템에서 저장 데이터 삭제", "8: 저장 데이터 확장", "9: SVI 파일 내보내기" @@ -211,23 +214,23 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: `%s` 에 대해 찾은 모든 타이틀의 저장 데이터를 백업하시겠습니까? 시간이 걸릴 수 있습니다.", - "1: `%s` 의 시스템에서 찾은 모든 타이틀에 대해 저장 데이터를 생성하시겠습니까? 시간이 걸릴 수 있습니다.", - "2: `%s` 의 모든 저장 데이터를 삭제하시겠습니까? *이 작업은 영구적이며 되돌릴 수 없습니다.*" + "0: `%s`에 대해 발견된 모든 타이틀의 저장 데이터를 백업하시겠습니까? 시간이 걸릴 수 있습니다.", + "1: `%s`에 대해 발견된 모든 타이틀의 저장 데이터를 생성하시겠습니까? 시간이 걸릴 수 있습니다.", + "2: `%s`의 모든 저장 데이터를 삭제하시겠습니까? *이 작업은 영구적이며 되돌릴 수 없습니다.*" ], "UserOptionStatus": [ - "0: #%s# 저장 데이터를 생성 중입니다...", - "1: #%s# 저장 데이터를 삭제 중입니다..." + "0: #%s#의 저장 데이터 생성 중...", + "1: #%s#의 저장 데이터 삭제 중..." ], "UserOptions": [ - "0: `%s` 의 모든 데이터 덤프", + "0: `%s`의 모든 덤프", "1: `%s` 저장 데이터 생성", - "2: `%s` 모든 저장 데이터 생성", - "3: `%s` 모든 저장 데이터 삭제" + "2: `%s`의 모든 저장 데이터 생성", + "3: `%s`의 모든 저장 데이터 삭제" ], "WebDavStrings": [ "0: WebDav가 성공적으로 시작되었습니다!", - "1: WebDav 시작 실패!" + "1: WebDav 실패!" ], "YesNo": [ "0: 예 [A]", diff --git a/romfs/Text/NL.json b/romfs/Text/NL.json index 176b64f..5a1d4ad 100644 --- a/romfs/Text/NL.json +++ b/romfs/Text/NL.json @@ -12,24 +12,24 @@ "1: Back-up is leeg!", "2: Fout bij het resetten van opslaggegevens!", "3: Fout bij het openen van ZIP-bestand om te lezen!", - "4: Fout opgetreden bij het verwijderen van back-up!", - "5: Fout opgetreden bij het maken van back-up!", - "6: Schrijven naar het systeem is uitgeschakeld!", + "4: Fout bij het verwijderen van back-up!", + "5: Fout bij het maken van back-up!", + "6: Schrijven naar systeem is uitgeschakeld!", "7: Kan ZIP niet openen om te lezen!", - "8: Fout bij het schrijven van meta-gegevens van opslag!", - "9: Fout bij het downloaden van bestand!", - "10: Fout bij het uploaden van bestand!", - "11: Fout bij het verwerken van meta-gegevens opslag!", - "12: Fout bij het aanmaken van doelmap!", + "8: Fout bij het schrijven van opslagmeta-gegevensbestand!", + "9: Fout bij downloaden van bestand!", + "10: Fout bij uploaden van bestand!", + "11: Fout bij verwerken van opslagmeta-gegevens!", + "12: Fout bij het maken van doelmap!", "13: Back-up moet een ZIP zijn om te uploaden!", - "14: Fout bij het koppelen van opslag!", - "15: Fout bij het sluiten van opslag!" + "14: Fout bij het mounten van opslaggegevens!", + "15: Fout bij het sluiten van opslaggegevens!" ], "BackupMenuStatus": [ - "0: Bezig met verwerken van meta-bestand opslag..." + "0: Verwerken van opslagmeta-bestand..." ], "ControlGuides": [ - "0: [A] Selecteren [Y] Alles dumpen [X] Gebruikersopties", + "0: [A] Selecteren [Y] Alle opslaggegevens dumpen [X] Gebruikersopties", "1: [A] Selecteren [L] [R] Springen [Y] Favoriet [X] Titelopties [B] Terug", "2: [A] Selecteren [Y] Herstellen [X] Verwijderen [ZR] Uploaden [B] Sluiten", "3: [A] Wisselen [X] Standaardwaarden [B] Terug" @@ -45,46 +45,46 @@ ], "ExtrasPops": [ "0: Gegevens opnieuw geïnitialiseerd!", - "1: Gegevens opnieuw initialiseren mislukt!" + "1: Gegevensinitialisatie mislukt!" ], "GeneralPops": [ - "0: JKSV kan niet worden afgesloten terwijl taken bezig zijn!" + "0: JKSV kan niet worden afgesloten terwijl er taken worden uitgevoerd!" ], "GoogleDriveStrings": [ - "0: Ga naar #%s# en voer >%s< in om door te gaan!", - "1: Succesvol ingelogd op Google Drive!", - "2: Inloggen op Google Drive mislukt!" + "0: Ga naar #%s# en voer >%s> in om verder te gaan!", + "1: Succesvol aangemeld bij Google Drive!", + "2: Aanmelden bij Google Drive mislukt!" ], "HoldingStrings": [ "0: Houd [A] ingedrukt", "1: Blijf [A] ingedrukt houden", - "2: Bijna daar! [A]" + "2: Bijna klaar! [A]" ], "IOStatuses": [ - "0: Bezig met kopiëren van #%s#...", - "1: Bezig met comprimeren van #%s# naar ZIP...", - "2: Bezig met uitpakken van #%s# uit ZIP...", - "3: Bezig met verwijderen van #%s#...", - "4: Bezig met downloaden van #%s#...", - "5: Bezig met uploaden van #%s# naar remote opslag...", - "6: Bezig met bijwerken van #%s# op remote opslag..." + "0: Kopiëren van #%s#...", + "1: Comprimeren van #%s# naar ZIP...", + "2: Uitpakken van #%s# uit ZIP...", + "3: Verwijderen van #%s#...", + "4: Downloaden van #%s#...", + "5: Uploaden van #%s# naar externe opslag...", + "6: Bijwerken van #%s# op externe opslag..." ], "IOPops": [ - "0: Fout bij het wegschrijven van gegevens naar het apparaat!" + "0: Fout bij het opslaan van gegevens op apparaat!" ], "KeyboardStrings": [ - "0: Voer een nieuwe back-upnaam in.", - "1: Voer cache-index in.", - "2: Voer een nieuw uitvoerpad voor JKSV in.", + "0: Voer een nieuwe naam voor de back-up in.", + "1: Voer de cache-index in.", + "2: Voer een nieuwe uitvoerlocatie voor JKSV in.", "3: Voer het proces-ID in om te beëindigen.", "4: Voer een systeemopslag-ID in.", "5: Voer een nieuwe naam in voor het doelitem.", "6: Voer een naam in voor de nieuwe map.", "7: Voer een nieuwe uitvoermapnaam in voor %s.", - "8: Voer in hoeveel je wilt uitbreiden (in MB)." + "8: Voer in hoeveel er uitgebreid moet worden (in MB)." ], "MainMenuConfs": [ - "0: Weet je zeker dat je de opslaggegevens voor alle gebruikers op dit systeem wilt back-uppen? Dit kan *extreem* lang duren!" + "0: Weet je zeker dat je de opslaggegevens voor elke gebruiker op dit systeem wilt back-uppen? Dit kan *erg* lang duren!" ], "MainMenuPops": [ "0: `%s` heeft geen opslaggegevens!" @@ -97,8 +97,8 @@ "0: Geen internetverbinding beschikbaar!" ], "SaveCreatePops": [ - "0: Opslaggegevens gemaakt voor #%s#!", - "1: Fout bij het maken van opslaggegevens!", + "0: Opslaggegevens aangemaakt voor #%s#!", + "1: Fout bij het aanmaken van opslaggegevens!", "2: Fout bij het verwijderen van opslaggegevens!" ], "SaveDataTypes": [ @@ -111,88 +111,91 @@ "6: Systeem BCAT" ], "SettingsDescriptions": [ - "0: Stelt de werkmap voor JKSV in. De standaardwaarde is `sdmc:/JKSV`.", - "1: Hiermee kunt u titels uit de zwarte lijst verwijderen.", + "0: Stelt de werkmap in voor JKSV. De standaardwaarde is `sdmc:/JKSV`.", + "1: Hiermee kun je titels van de zwarte lijst verwijderen.", "2: Inclusief apparaat- of gedeelde opslag met gebruikers.", - "3: Maakt automatisch een back-up wanneer een andere wordt hersteld.", - "4: Naam back-ups automatisch en slaat het toetsenbord over.", - "5: Uploadt back-ups automatisch naar remote opslag en verwijdert ze lokaal.", + "3: Maakt automatisch een back-up bij het herstellen van een andere.", + "4: Geeft back-ups automatisch een naam en slaat het toetsenbord over.", + "5: Upload back-ups automatisch naar extern en verwijdert ze lokaal.", "6: Gebruikt altijd applicatie-ID's voor exportmapnamen.", - "7: Vereist het ingedrukt houden van [A] gedurende drie seconden om back-ups te verwijderen.", - "8: Vereist het ingedrukt houden van [A] gedurende drie seconden om back-ups te herstellen.", - "9: Vereist het ingedrukt houden van [A] gedurende drie seconden om back-ups te overschrijven.", - "10: Toont alleen opslaggegevens die JKSV met succes kan openen.", - "11: Toont systeemopslag die aan een account-ID is gekoppeld.", + "7: Of het vereist is om [A] drie seconden ingedrukt te houden om back-ups te verwijderen.", + "8: Of het vereist is om [A] drie seconden ingedrukt te houden om back-ups te herstellen.", + "9: Of het vereist is om [A] drie seconden ingedrukt te houden om back-ups te overschrijven.", + "10: Toont alleen opslaggegevens die JKSV succesvol kan openen.", + "11: Toont systeemopslag met een gekoppeld account-ID.", "12: Schakelt het herstellen van systeemopslag en schrijven naar NAND-partities in.", "13: Exporteert opslaggegevens naar ZIP-archieven in plaats van uitgepakte mappen.", - "14: Compressie- of deflate-niveau gebruikt bij het schrijven naar ZIP. De standaardwaarde is 6. Lagere waarden zijn sneller, maar bieden minder compressie en ruimtebesparing. Nul is opslaan, oftewel geen compressie.", - "15: Regelt de manier waarop titels worden gesorteerd en weergegeven.", - "16: Toont titels als tekstmenu's zoals de originele JKSM op 3DS in plaats van pictogrid.", - "17: Dwingt Engels af als taal in plaats van de gedetecteerde systeemtaal.", - "18: Verplaatst verwijderde back-ups naar de _TRASH_-map in plaats van ze permanent te verwijderen.", + "14: Compressie- of deflate-niveau dat wordt gebruikt bij het schrijven naar ZIP. De standaardwaarde is 6. Lagere waarden zijn sneller, maar bieden minder compressie en ruimtebesparing. Nul is opslaan, of geen compressie.", + "15: Regelt hoe titels worden gesorteerd en weergegeven.", + "16: Toont titels als tekstmenu's zoals de originele JKSM op 3DS in plaats van pictogramroosters.", + "17: Forceert Engels als taal in plaats van de gedetecteerde systeemt taal.", + "18: Verplaatst verwijderde back-ups naar de _TRASH_ map in plaats van ze permanent te verwijderen.", "19: Stelt de snelheid in waarmee overgangen en animaties plaatsvinden. Lager is sneller." ], "SettingsMenu": [ - "0: Stel de uitvoermap van JKSV in.", + "0: Stel JKSV-uitvoermap in.", "1: Bewerk zwarte lijst", - "2: Apparaatopslag opnemen met gebruikers: %s", - "3: Automatische back-up bij herstel: %s", + "2: Inclusief apparaatopslag met gebruikers: %s", + "3: Automatische back-up bij herstellen: %s", "4: Automatische naamgeving back-ups: %s", - "5: Automatisch uploaden van back-ups naar remote opslag: %s", + "5: Automatisch uploaden van back-ups naar externe opslag: %s", "6: Altijd applicatie-ID's gebruiken: %s", "7: Houd ingedrukt om back-ups te verwijderen: %s", "8: Houd ingedrukt om back-ups te herstellen: %s", "9: Houd ingedrukt om back-ups te overschrijven: %s", - "10: Alleen mountbare titels tonen: %s", - "11: Account systeemopslag tonen: %s", + "10: Alleen monteerbare titels weergeven: %s", + "11: Toon account systeemopslag: %s", "12: Schakel schrijven naar systeemopslag en NAND in: %s", "13: Exporteer opslag naar ZIP: %s", - "14: ZIP compressieniveau: %u", - "15: Soort titel sortering: %s", + "14: ZIP-compressieniveau: %u", + "15: Type titel sortering: %s", "16: Tekstmenu (JKSM) modus: %s", "17: Forceer Engels: %s", "18: Schakel prullenbak in: %s", "19: Animatieschaal: %.02f" ], + "SettingsPops": [ + "0: Zwarte lijst is leeg!" + ], "SortTypes": [ "0: Alfabetisch", "1: Meest gespeeld", "2: Laatst gespeeld" ], "TitleInfo": [ - "0: App-ID: %016lX", - "1: Opslag-ID: %016lx", + "0: App ID: %016lX", + "1: Opslag ID: %016lx", "2: Eerste keer gespeeld: %x - %X", "3: Laatste keer gespeeld: %x - %X", "4: Speeltijd: %02d:%02d:%02d", - "5: Aantal keer gestart: %i", + "5: Aantal keren gestart: %i", "6: Opslagtype: %s" ], "TitleOptionConfirmations": [ - "0: Weet je zeker dat je #%s# aan je zwarte lijst wilt toevoegen? Zodra je dit doet, verschijnt het niet meer in een titellijst of selectie.", - "1: Weet je zeker dat je alle huidige back-ups voor #%s# wilt verwijderen? *Dit kan niet ongedaan gemaakt worden!*", - "2: Weet je zeker dat je de opslaggegevens voor #%s# wilt resetten? *Dit verwijdert de huidige opslaggegevens alsof het spel nog nooit is gestart!*", - "3: Weet je zeker dat je `%s`'s opslaggegevens voor #%s# wilt verwijderen? *Dit verwijdert het permanent van het systeem.*" + "0: Weet je zeker dat je #%s# aan je zwarte lijst wilt toevoegen? Hierdoor verschijnt het niet meer in titellijsten of selecties.", + "1: Weet je zeker dat je alle huidige back-ups voor #%s# wilt verwijderen? *Dit kan niet ongedaan worden gemaakt!*", + "2: Weet je zeker dat je de opslaggegevens voor #%s# wilt resetten? *Dit verwijdert de huidige opslaggegevens alsof het spel nooit is gestart!*", + "3: Weet je zeker dat je de opslaggegevens van `%s` voor #%s# wilt verwijderen? *Dit verwijdert het permanent van het systeem.*" ], "TitleOptionPops": [ - "0: Alle back-ups verwijderd voor #%s#!", + "0: Alle back-ups voor #%s# verwijderd!", "1: Verwijderen van alle back-ups mislukt!", - "2: Resetten van opslaggegevens mislukt!", + "2: Fout bij het resetten van opslaggegevens!", "3: Opslaggegevens succesvol gereset!", "4: SVI-bestand succesvol geëxporteerd!", - "5: Fout bij exporteren van SVI-bestand!", + "5: Fout bij het exporteren van SVI-bestand!", "6: Deze optie is niet beschikbaar voor systeemopslag!", - "7: Kon het pad niet saniteren voor gebruik!", + "7: Pad kon niet worden gesaneerd voor gebruik!", "8: Uitvoermap ingesteld op #%s#.", - "9: Fout bij instellen van nieuw uitvoerpad!", + "9: Fout bij het instellen van nieuwe uitvoerlocatie!", "10: Opslaggegevens succesvol uitgebreid!", - "11: Uitbreiden opslaggegevens mislukt!" + "11: Uitbreiden van opslaggegevens mislukt!" ], "TitleOptionStatus": [ - "0: Alle back-ups voor #%s# verwijderen.", - "1: Opslaggegevens voor #%s# resetten.", - "2: `%s`'s opslaggegevens voor #%s# verwijderen...", - "3: `%s`'s opslaggegevens voor #%s# uitbreiden..." + "0: Alle back-ups voor #%s# worden verwijderd.", + "1: Opslaggegevens voor #%s# worden gereset.", + "2: Opslaggegevens voor `%s` van #%s# worden verwijderd...", + "3: Opslaggegevens voor `%s` van #%s# worden uitgebreid..." ], "TitleOptions": [ "0: Informatie", @@ -200,9 +203,9 @@ "2: Uitvoermap wijzigen", "3: Openen in bestandsmodus", "4: Alle lokale back-ups verwijderen", - "5: Alle remote back-ups verwijderen", - "6: Opslaggegevens resetten", - "7: Opslaggegevens verwijderen van systeem", + "5: Alle externe back-ups verwijderen", + "6: Opslaggegevens resetten.", + "7: Opslaggegevens van systeem verwijderen", "8: Opslaggegevens uitbreiden", "9: SVI-bestand exporteren" ], @@ -211,13 +214,13 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: Weet je zeker dat je opslaggegevens voor elke titel gevonden voor `%s` wilt back-uppen? Dit kan een tijdje duren.", - "1: Weet je zeker dat je opslaggegevens wilt aanmaken voor alle titels gevonden op je systeem voor `%s`? Dit kan een tijdje duren.", - "2: Weet je zeker dat je alle opslaggegevens voor `%s` wilt verwijderen? Dit is *PERMANENT* en kan niet ongedaan gemaakt worden." + "0: Weet je zeker dat je de opslaggegevens voor alle titels gevonden voor `%s` wilt back-uppen? Dit kan even duren.", + "1: Weet je zeker dat je opslaggegevens wilt aanmaken voor alle titels gevonden op je systeem voor `%s`? Dit kan even duren.", + "2: Weet je zeker dat je alle opslaggegevens voor `%s` wilt verwijderen? Dit is *PERMANENT* en kan niet ongedaan worden gemaakt." ], "UserOptionStatus": [ - "0: Opslaggegevens aanmaken voor #%s#...", - "1: Opslaggegevens verwijderen voor #%s#..." + "0: Opslaggegevens voor #%s# aan het aanmaken...", + "1: Opslaggegevens voor #%s# aan het verwijderen..." ], "UserOptions": [ "0: Alles dumpen voor `%s`", diff --git a/romfs/Text/PT.json b/romfs/Text/PT.json index 78da3a3..544c049 100644 --- a/romfs/Text/PT.json +++ b/romfs/Text/PT.json @@ -3,70 +3,70 @@ "0: Novo Backup" ], "BackupMenuConfirmations": [ - "0: Tem a certeza que quer mesmo sobrescrever #%s#?", - "1: Tem a certeza que quer mesmo restaurar #%s#?", - "2: Tem a certeza que quer mesmo apagar #%s#?" + "0: Tem a certeza de que pretende substituir realmente #%s#?", + "1: Tem a certeza de que pretende restaurar realmente #%s#?", + "2: Tem a certeza de que pretende eliminar realmente #%s#?" ], "BackupMenuPops": [ "0: Os dados guardados estão vazios!", "1: O backup está vazio!", "2: Erro ao reiniciar os dados guardados!", "3: Erro ao abrir ficheiro ZIP para leitura!", - "4: Ocorreu um erro ao apagar o backup!", - "5: Ocorreu um erro ao criar o backup!", + "4: Ocorreu um erro ao eliminar o backup!", + "5: Erro ao criar o backup!", "6: A escrita no sistema está desativada!", - "7: Não foi possível abrir o zip para leitura!", - "8: Erro ao escrever o ficheiro de meta-dados dos dados guardados!", + "7: Impossível abrir o zip para leitura!", + "8: Erro ao escrever ficheiro de metadados dos dados guardados!", "9: Erro ao transferir ficheiro!", - "10: Erro ao carregar ficheiro!", - "11: Erro ao processar os meta-dados dos dados guardados!", - "12: Erro ao criar o diretório de destino!", - "13: O backup tem de ser um zip para ser carregado!", + "10: Erro ao enviar ficheiro!", + "11: Erro ao processar metadados dos dados guardados!", + "12: Erro ao criar directório de destino!", + "13: O backup tem de ser um zip para fazer upload!", "14: Erro ao montar os dados guardados!", "15: Erro ao fechar os dados guardados!" ], "BackupMenuStatus": [ - "0: A processar ficheiro meta dos dados guardados..." + "0: A processar ficheiro de metadados dos dados guardados..." ], "ControlGuides": [ - "0: [A] Selecionar [Y] Fazer dump de todos os saves [X] Opções do utilizador", - "1: [A] Selecionar [L] [R] Saltar [Y] Favoritos [X] Opções do título [B] Voltar", - "2: [A] Selecionar [Y] Restaurar [X] Apagar [ZR] Carregar [B] Fechar", + "0: [A] Selecionar [Y] Descarregar todos os saves [X] Opções do utilizador", + "1: [A] Selecionar [L] [R] Saltar [Y] Favorito [X] Opções do título [B] Voltar", + "2: [A] Selecionar [Y] Restaurar [X] Apagar [ZR] Enviar [B] Fechar", "3: [A] Alternar [X] Predefinições [B] Voltar" ], "ExtrasMenu": [ - "0: Reinicializar Dados", - "1: Browser SD para SD", + "0: Reinicializar dados", + "1: SD para navegador SD", "2: ProdInfoF", "3: Seguro", "4: Sistema", "5: Utilizador", - "6: Terminar Processo" + "6: Terminar processo" ], "ExtrasPops": [ "0: Dados reinicializados!", - "1: Falha ao reinicializar dados!" + "1: Falha na reinicialização dos dados!" ], "GeneralPops": [ - "0: Incapaz de sair do JKSV enquanto as tarefas estiverem a correr!" + "0: Não é possível sair do JKSV enquanto há tarefas em execução!" ], "GoogleDriveStrings": [ - "0: Para continuar, aceda a #%s# e introduza >%s%s>!", + "1: Início de sessão no Google Drive bem sucedido!", + "2: Falha no início de sessão do Google Drive!" ], "HoldingStrings": [ - "0: Mantenha premido [A]", - "1: Continue a manter premido [A]", + "0: Mantenha [A] premido", + "1: Continue a manter [A] premido", "2: Quase lá! [A]" ], "IOStatuses": [ "0: A copiar #%s#...", "1: A comprimir #%s# para ZIP...", - "2: A descomprimir #%s# do ZIP...", + "2: A descomprimir #%s# de ZIP...", "3: A apagar #%s#...", "4: A transferir #%s#...", - "5: A carregar #%s# para armazenamento remoto...", + "5: A enviar #%s# para armazenamento remoto...", "6: A atualizar #%s# no armazenamento remoto..." ], "IOPops": [ @@ -74,17 +74,17 @@ ], "KeyboardStrings": [ "0: Introduza um novo nome para o backup.", - "1: Introduza o índice da cache.", - "2: Introduza um novo caminho de saída para o JKSV", + "1: Introduza o índice do cache.", + "2: Introduza um novo caminho de saída para o JKSV.", "3: Introduza o ID do processo a terminar.", - "4: Introduza um ID de save do sistema", + "4: Introduza um ID de save do sistema.", "5: Introduza um novo nome para o item alvo.", "6: Introduza um nome para a nova pasta.", "7: Introduza um novo nome para a pasta de saída de %s.", "8: Introduza o quanto expandir (em MB)." ], "MainMenuConfs": [ - "0: Tem a certeza que quer fazer backup dos dados guardados de todos os utilizadores deste sistema? Isto pode demorar *muito* tempo!" + "0: Tem a certeza de que pretende fazer backup dos dados guardados de todos os utilizadores deste sistema? Isto pode demorar *muito* tempo!" ], "MainMenuPops": [ "0: `%s` não tem dados guardados!" @@ -94,12 +94,12 @@ "1: >Ligado>" ], "RemotePops": [ - "0: Sem ligação à internet disponível!" + "0: Não existe ligação à Internet disponível!" ], "SaveCreatePops": [ "0: Dados guardados criados para #%s#!", "1: Erro ao criar dados guardados!", - "2: Erro ao apagar dados guardados!" + "2: Erro ao eliminar dados guardados!" ], "SaveDataTypes": [ "0: Sistema", @@ -111,57 +111,60 @@ "6: BCAT do sistema" ], "SettingsDescriptions": [ - "0: Define a diretoria de trabalho para o JKSV. O valor por defeito é `sdmc:/JKSV`.", - "1: Permite remover títulos da blacklist.", - "2: Inclui saves de dispositivo, ou partilhados, com utilizadores.", - "3: Cria automaticamente um backup ao restaurar outro.", - "4: Nomeia backups automaticamente e ignora o teclado.", - "5: Carrega automaticamente backups para armazenamento remoto e apaga-os localmente.", - "6: Usa sempre IDs de aplicação para nomes de pastas de exportação.", - "7: Exige manter premido [A] por três segundos para apagar backups.", - "8: Exige manter premido [A] por três segundos para restaurar backups.", - "9: Exige manter premido [A] por três segundos para sobrescrever backups.", - "10: Apenas mostra saves que o JKSV consegue abrir com sucesso.", - "11: Mostra saves do sistema ligados a uma conta.", - "12: Ativa a restauração de saves do sistema e escrita nas partições NAND.", - "13: Exporta saves para arquivos ZIP em vez de pastas extraídas.", - "14: Nível de compressão ou deflate usado ao escrever para ZIP. O valor por defeito é 6. Valores mais baixos são mais rápidos, mas oferecem menos compressão e economia de espaço. Zero significa armazenar, ou sem compressão.", + "0: Define o directório de trabalho para o JKSV. O valor predefinido é `sdmc:/JKSV`.", + "1: Permite remover títulos da lista negra.", + "2: Inclui saves de dispositivo ou partilhados com utilizadores.", + "3: Cria backup automaticamente ao restaurar outro.", + "4: Dá nome automático aos backups e salta o teclado.", + "5: Envia automaticamente os backups para o remoto e apaga localmente.", + "6: Usa sempre IDs de aplicação para nomes das pastas de exportação.", + "7: Se é necessário manter [A] premido durante três segundos para apagar backups.", + "8: Se é necessário manter [A] premido durante três segundos para restaurar backups.", + "9: Se é necessário manter [A] premido durante três segundos para sobrescrever backups.", + "10: Mostra apenas dados guardados que o JKSV consegue abrir com sucesso.", + "11: Mostra saves do sistema com ID de conta associada.", + "12: Permite restaurar saves do sistema e escrever em partições NAND.", + "13: Exporta os dados guardados para ficheiros ZIP em vez de pastas descompactadas.", + "14: Nível de compressão ou deflate usado ao escrever em ZIP. O valor predefinido é 6. Valores mais baixos são mais rápidos, mas oferecem menos compressão e economia de espaço. Zero é guardar sem compressão.", "15: Controla a forma como os títulos são ordenados e exibidos.", - "16: Mostra títulos como menus de texto tal como o JKSM original no 3DS em vez de grelhas de ícones.", - "17: Obriga a usar inglês como língua em vez da língua do sistema detectada.", - "18: Move backups apagados para a pasta _TRASH_ em vez de os apagar permanentemente.", + "16: Mostra os títulos como menus de texto, como o JKSM original no 3DS, em vez de grelhas de ícones.", + "17: Força o inglês como idioma, em vez do idioma do sistema detetado.", + "18: Move os backups apagados para a pasta _TRASH_ em vez de os eliminar permanentemente.", "19: Define a velocidade das transições e animações. Valores mais baixos são mais rápidos." ], "SettingsMenu": [ "0: Definir pasta de saída do JKSV.", - "1: Editar blacklist", + "1: Editar lista negra", "2: Incluir saves de dispositivo com utilizadores: %s", "3: Backup automático ao restaurar: %s", "4: Nomear backups automaticamente: %s", - "5: Carregar backups automaticamente para armazenamento remoto: %s", + "5: Enviar backups automaticamente para armazenamento remoto: %s", "6: Usar sempre IDs de aplicação: %s", "7: Manter premido para apagar backups: %s", "8: Manter premido para restaurar backups: %s", "9: Manter premido para sobrescrever backups: %s", "10: Mostrar apenas títulos montáveis: %s", - "11: Mostrar saves do sistema com conta: %s", - "12: Ativar escrita em saves do sistema e NAND: %s", + "11: Mostrar saves de sistema com conta: %s", + "12: Permitir escrita em saves de sistema e NAND: %s", "13: Exportar saves para ZIP: %s", "14: Nível de compressão ZIP: %u", "15: Tipo de ordenação dos títulos: %s", - "16: Modo menu de texto (JKSM): %s", + "16: Modo menu texto (JKSM): %s", "17: Forçar inglês: %s", "18: Ativar contentor de lixo: %s", "19: Escala de animação: %.02f" ], + "SettingsPops": [ + "0: A lista negra está vazia!" + ], "SortTypes": [ "0: Alfabeticamente", "1: Mais jogados", - "2: Últimos jogados" + "2: Última vez jogado" ], "TitleInfo": [ - "0: ID da App: %016lX", - "1: ID do Save: %016lx", + "0: ID da app: %016lX", + "1: ID do save: %016lx", "2: Primeiro jogo: %x - %X", "3: Último jogo: %x - %X", "4: Tempo de jogo: %02d:%02d:%02d", @@ -169,41 +172,41 @@ "6: Tipo de save: %s" ], "TitleOptionConfirmations": [ - "0: Tem a certeza que quer adicionar #%s# à sua blacklist? Depois de o fazer, não aparecerá em nenhuma lista ou seleção de títulos.", - "1: Tem a certeza que quer apagar todos os backups atuais para #%s#? *Isto não pode ser desfeito!*", - "2: Tem a certeza que quer reiniciar os dados guardados para #%s#? *Isto irá apagar os dados guardados atuais como se o título nunca tivesse sido jogado!*", - "3: Tem a certeza que quer apagar os dados guardados de `%s` para #%s#? *Isto irá apagar permanentemente do sistema.*" + "0: Tem a certeza de que pretende adicionar #%s# à sua lista negra? Após isto, não aparecerá em nenhuma lista ou seleção de títulos.", + "1: Tem a certeza de que pretende eliminar todas as cópias de segurança atuais para #%s#? *Isto não pode ser desfeito!*", + "2: Tem a certeza de que pretende reiniciar os dados guardados para #%s#? *Isto apagará os dados guardados actuais como se o título nunca tivesse sido jogado!*", + "3: Tem a certeza de que pretende eliminar os dados guardados de `%s` para #%s#? *Isto eliminará permanentemente do sistema.*" ], "TitleOptionPops": [ - "0: Todos os backups apagados para #%s#!", - "1: Falha ao apagar todos os backups!", - "2: Falha ao reiniciar dados guardados!", + "0: Todas as cópias de segurança para #%s# foram eliminadas!", + "1: Falha ao eliminar todas as cópias de segurança!", + "2: Erro ao reiniciar os dados guardados!", "3: Dados guardados reiniciados com sucesso!", "4: Ficheiro SVI exportado com sucesso!", - "5: Falha ao exportar ficheiro SVI!", + "5: Erro ao exportar ficheiro SVI!", "6: Esta opção não está disponível para saves do sistema!", - "7: Não foi possível sanitizar o caminho para uso!", + "7: Não foi possível sanear o caminho para utilização!", "8: Pasta de saída definida para #%s#.", "9: Erro ao definir novo caminho de saída!", - "10: Dados guardados estendidos com sucesso!", - "11: Falha ao estender dados guardados!" + "10: Dados guardados expandidos com sucesso!", + "11: Falha ao expandir dados guardados!" ], "TitleOptionStatus": [ - "0: A apagar todos os backups para #%s#.", + "0: A eliminar todas as cópias de segurança para #%s#.", "1: A reiniciar dados guardados para #%s#.", - "2: A apagar dados guardados de `%s` para #%s#...", - "3: A estender dados guardados de `%s` para #%s#..." + "2: A eliminar dados guardados de `%s` para #%s#...", + "3: A expandir dados guardados de `%s` para #%s#..." ], "TitleOptions": [ "0: Informação", - "1: Colocar título na blacklist", + "1: Adicionar título à lista negra", "2: Alterar pasta de saída", "3: Abrir em modo ficheiro", - "4: Apagar todos os backups locais", - "5: Apagar todos os backups remotos", - "6: Reiniciar dados guardados", - "7: Apagar dados guardados do sistema", - "8: Estender dados guardados", + "4: Eliminar todas as cópias de segurança locais", + "5: Eliminar todas as cópias de segurança remotas", + "6: Reiniciar dados guardados.", + "7: Eliminar dados guardados do sistema", + "8: Expandir dados guardados", "9: Exportar ficheiro SVI" ], "TranslationInfo": [ @@ -211,19 +214,19 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: Tem a certeza que quer fazer backup dos dados guardados de todos os títulos encontrados para `%s`? Isto pode demorar algum tempo.", - "1: Tem a certeza que quer criar dados guardados para todos os títulos encontrados no seu sistema para `%s`? Isto pode demorar algum tempo.", - "2: Tem a certeza que quer apagar todos os dados guardados para `%s`? Isto é *PERMANENTE* e não pode ser desfeito." + "0: Tem a certeza de que pretende fazer backup dos dados guardados de todos os títulos encontrados para `%s`? Isto pode demorar algum tempo.", + "1: Tem a certeza de que pretende criar dados guardados para todos os títulos encontrados no seu sistema para `%s`? Isto pode demorar algum tempo.", + "2: Tem a certeza de que pretende eliminar todos os dados guardados para `%s`? Isto é *PERMANENTE* e não pode ser desfeito." ], "UserOptionStatus": [ "0: A criar dados guardados para #%s#...", - "1: A apagar dados guardados para #%s#..." + "1: A eliminar dados guardados para #%s#..." ], "UserOptions": [ - "0: Fazer dump de tudo para `%s`", + "0: Descarregar tudo para `%s`", "1: Criar dados guardados para `%s`", "2: Criar todos os dados guardados para `%s`", - "3: Apagar todos os dados guardados para `%s`" + "3: Eliminar todos os dados guardados para `%s`" ], "WebDavStrings": [ "0: WebDav iniciado com sucesso!", diff --git a/romfs/Text/PTBR.json b/romfs/Text/PTBR.json index c7cfff8..d58683a 100644 --- a/romfs/Text/PTBR.json +++ b/romfs/Text/PTBR.json @@ -3,57 +3,57 @@ "0: Novo Backup" ], "BackupMenuConfirmations": [ - "0: Tem certeza que quer realmente sobrescrever #%s#?", - "1: Tem certeza que quer realmente restaurar #%s#?", - "2: Tem certeza que quer realmente deletar #%s#?" + "0: Tem certeza de que deseja realmente sobrescrever #%s#?", + "1: Tem certeza de que deseja realmente restaurar #%s#?", + "2: Tem certeza de que deseja realmente excluir #%s#?" ], "BackupMenuPops": [ - "0: Os dados salvos estão vazios!", - "1: O backup está vazio!", + "0: Dados salvos estão vazios!", + "1: Backup está vazio!", "2: Erro ao resetar os dados salvos!", "3: Erro ao abrir arquivo ZIP para leitura!", - "4: Ocorreu um erro ao deletar o backup!", - "5: Ocorreu um erro ao criar o backup!", - "6: Gravar no sistema está desabilitado!", - "7: Não foi possível abrir o zip para leitura!", - "8: Erro ao escrever o arquivo de meta dados dos saves!", + "4: Erro ao deletar backup!", + "5: Erro ao criar backup!", + "6: Escrita no sistema está desativada!", + "7: Incapaz de abrir zip para leitura!", + "8: Erro ao escrever arquivo de metadados de salvamento!", "9: Erro ao baixar arquivo!", "10: Erro ao enviar arquivo!", - "11: Erro ao processar meta dados dos saves!", - "12: Erro ao criar diretório alvo!", - "13: O backup precisa ser um zip para fazer upload!", + "11: Erro ao processar metadados dos dados salvos!", + "12: Erro ao criar diretório de destino!", + "13: O backup deve ser um zip para upload!", "14: Erro ao montar dados salvos!", "15: Erro ao fechar dados salvos!" ], "BackupMenuStatus": [ - "0: Processando arquivo meta dos dados salvos..." + "0: Processando arquivo de metadados dos dados salvos..." ], "ControlGuides": [ - "0: [A] Selecionar [Y] Descartar Todos os Saves [X] Opções do Usuário", - "1: [A] Selecionar [L] [R] Pular [Y] Favorito [X] Opções do Título [B] Voltar", - "2: [A] Selecionar [Y] Restaurar [X] Deletar [ZR] Enviar [B] Fechar", + "0: [A] Selecionar [Y] Descartar todos os saves [X] Opções do usuário", + "1: [A] Selecionar [L] [R] Pular [Y] Favorito [X] Opções do título [B] Voltar", + "2: [A] Selecionar [Y] Restaurar [X] Excluir [ZR] Enviar [B] Fechar", "3: [A] Alternar [X] Padrões [B] Voltar" ], "ExtrasMenu": [ - "0: Reinicializar Dados", - "1: Navegador SD para SD", + "0: Reinicializar dados", + "1: SD para navegador SD", "2: ProdInfoF", "3: Seguro", "4: Sistema", "5: Usuário", - "6: Terminar Processo" + "6: Terminar processo" ], "ExtrasPops": [ "0: Dados reinicializados!", - "1: Falha ao reinicializar dados!" + "1: Falha na reinicialização dos dados!" ], "GeneralPops": [ "0: Não é possível sair do JKSV enquanto tarefas estão em execução!" ], "GoogleDriveStrings": [ - "0: Para continuar, acesse #%s# e digite >%s%s>!", + "1: Login no Google Drive bem-sucedido!", + "2: Falha no login do Google Drive!" ], "HoldingStrings": [ "0: Segure [A]", @@ -62,9 +62,9 @@ ], "IOStatuses": [ "0: Copiando #%s#...", - "1: Comprimindo #%s# para ZIP...", - "2: Descomprimindo #%s# do ZIP...", - "3: Deletando #%s#...", + "1: Compactando #%s# para ZIP...", + "2: Descompactando #%s# de ZIP...", + "3: Excluindo #%s#...", "4: Baixando #%s#...", "5: Enviando #%s# para armazenamento remoto...", "6: Atualizando #%s# no armazenamento remoto..." @@ -75,19 +75,19 @@ "KeyboardStrings": [ "0: Digite um novo nome para o backup.", "1: Digite o índice do cache.", - "2: Digite um novo caminho de saída para o JKSV", + "2: Digite um novo caminho de saída para o JKSV.", "3: Digite o ID do processo para terminar.", - "4: Digite um ID de save do sistema", + "4: Digite um ID de save do sistema.", "5: Digite um novo nome para o item alvo.", "6: Digite um nome para a nova pasta.", "7: Digite um novo nome para a pasta de saída de %s.", - "8: Digite quanto deseja expandir (em MB)." + "8: Digite o quanto expandir (em MB)." ], "MainMenuConfs": [ - "0: Tem certeza que quer fazer backup dos dados salvos para todos os usuários deste sistema? Isso pode levar um tempo *extremamente* longo!" + "0: Tem certeza de que deseja fazer backup dos dados salvos de todos os usuários deste sistema? Isso pode levar *muito* tempo!" ], "MainMenuPops": [ - "0: `%s` não tem dados salvos!" + "0: `%s` não possui dados salvos!" ], "OnOff": [ "0: Desligado", @@ -99,7 +99,7 @@ "SaveCreatePops": [ "0: Dados salvos criados para #%s#!", "1: Erro ao criar dados salvos!", - "2: Erro ao deletar dados salvos!" + "2: Erro ao excluir dados salvos!" ], "SaveDataTypes": [ "0: Sistema", @@ -111,98 +111,101 @@ "6: BCAT do sistema" ], "SettingsDescriptions": [ - "0: Define a pasta de trabalho do JKSV. O valor padrão é `sdmc:/JKSV`.", + "0: Define o diretório de trabalho para o JKSV. O valor padrão é `sdmc:/JKSV`.", "1: Permite remover títulos da lista negra.", - "2: Inclui saves de dispositivo, ou compartilhados, com usuários.", + "2: Inclui saves de dispositivo ou compartilhados com usuários.", "3: Cria backup automaticamente ao restaurar outro.", - "4: Nomes de backup automáticos e pula o teclado.", - "5: Envia backups automaticamente para armazenamento remoto e os apaga localmente.", - "6: Sempre usa IDs de aplicativo para nomes de pastas de exportação.", - "7: Exige segurar [A] por três segundos para deletar backups.", - "8: Exige segurar [A] por três segundos para restaurar backups.", - "9: Exige segurar [A] por três segundos para sobrescrever backups.", - "10: Mostra apenas saves que o JKSV consegue abrir com sucesso.", - "11: Mostra saves do sistema vinculados a uma conta.", - "12: Habilita restauração de saves do sistema e escrita em partições NAND.", - "13: Exporta saves para arquivos ZIP em vez de pastas descompactadas.", - "14: Nível de compressão usado ao gravar ZIP. O padrão é 6. Valores menores são mais rápidos, mas oferecem menos compressão. Zero é armazenar, ou sem compressão.", - "15: Controla como os títulos são ordenados e exibidos.", - "16: Exibe títulos como menus de texto, como o JKSM original no 3DS, em vez de grade de ícones.", + "4: Nomeia backups automaticamente e pula o teclado.", + "5: Envia backups automaticamente para o remoto e os apaga localmente.", + "6: Sempre usa IDs de Aplicação para nomes de pasta de exportação.", + "7: Se é necessário segurar [A] por três segundos para deletar backups.", + "8: Se é necessário segurar [A] por três segundos para restaurar backups.", + "9: Se é necessário segurar [A] por três segundos para sobrescrever backups.", + "10: Mostra somente saves que o JKSV pode abrir com sucesso.", + "11: Mostra saves de sistema com ID de conta atrelada.", + "12: Permite restaurar saves de sistema e escrever em partições NAND.", + "13: Exporta dados salvos para arquivos ZIP em vez de pastas descompactadas.", + "14: Nível de compressão usado ao escrever em ZIP. O padrão é 6. Valores menores são mais rápidos, porém oferecem menos compressão e economia de espaço. Zero é armazenar, ou sem compressão.", + "15: Controla como os títulos são classificados e exibidos.", + "16: Exibe títulos como menus de texto, como o JKSM original no 3DS, em vez de grades de ícones.", "17: Força o uso do inglês como idioma em vez do idioma detectado do sistema.", "18: Move backups deletados para a pasta _TRASH_ em vez de deletá-los permanentemente.", - "19: Define a velocidade de transições e animações. Valores menores são mais rápidos." + "19: Define a velocidade das transições e animações. Valores menores são mais rápidos." ], "SettingsMenu": [ "0: Definir pasta de saída do JKSV.", "1: Editar lista negra", "2: Incluir saves de dispositivo com usuários: %s", "3: Backup automático ao restaurar: %s", - "4: Nomeação automática de backups: %s", + "4: Nomear backups automaticamente: %s", "5: Enviar backups automaticamente para armazenamento remoto: %s", - "6: Sempre usar IDs de aplicativo: %s", + "6: Sempre usar IDs de Aplicação: %s", "7: Segurar para deletar backups: %s", "8: Segurar para restaurar backups: %s", "9: Segurar para sobrescrever backups: %s", "10: Mostrar apenas títulos montáveis: %s", - "11: Mostrar saves do sistema com conta: %s", - "12: Habilitar escrita em saves do sistema e NAND: %s", + "11: Mostrar saves de sistema com conta: %s", + "12: Permitir escrita em saves de sistema e NAND: %s", "13: Exportar saves para ZIP: %s", "14: Nível de compressão ZIP: %u", - "15: Tipo de ordenação dos títulos: %s", + "15: Tipo de ordenação de títulos: %s", "16: Modo menu texto (JKSM): %s", "17: Forçar inglês: %s", "18: Habilitar lixeira: %s", "19: Escala de animação: %.02f" ], + "SettingsPops": [ + "0: Lista negra está vazia!" + ], "SortTypes": [ "0: Alfabeticamente", "1: Mais jogados", - "2: Últimos jogados" + "2: Última vez jogado" ], "TitleInfo": [ "0: ID do App: %016lX", "1: ID do Save: %016lx", - "2: Primeiro jogado: %x - %X", - "3: Último jogado: %x - %X", - "4: Tempo de jogo: %02d:%02d:%02d", + "2: Primeiro jogo: %x - %X", + "3: Último jogo: %x - %X", + "4: Tempo jogado: %02d:%02d:%02d", "5: Lançamentos: %i", "6: Tipo de save: %s" ], "TitleOptionConfirmations": [ - "0: Tem certeza que quer adicionar #%s# à sua lista negra? Uma vez feito, ele não aparecerá mais em nenhuma lista ou seleção de títulos.", - "1: Tem certeza que quer deletar todos os backups atuais para #%s#? *Isto não pode ser desfeito!*", - "2: Tem certeza que quer resetar os dados salvos para #%s#? *Isto vai deletar os dados atuais como se o título nunca tivesse sido jogado!*", - "3: Tem certeza que quer deletar os dados salvos de `%s` para #%s#? *Isto vai deletar permanentemente do sistema.*" + "0: Tem certeza de que deseja adicionar #%s# à sua lista negra? Depois disso, ele não aparecerá em nenhuma lista ou seleção de títulos.", + "1: Tem certeza de que deseja excluir todos os backups atuais para #%s#? *Isso não pode ser desfeito!*", + "2: Tem certeza de que deseja resetar os dados salvos para #%s#? *Isso deletará os dados salvos atuais como se nunca tivesse sido jogado!*", + "3: Tem certeza de que deseja deletar os dados salvos de `%s` para #%s#? *Isso o deletará permanentemente do sistema.*" ], "TitleOptionPops": [ "0: Todos os backups deletados para #%s#!", "1: Falha ao deletar todos os backups!", - "2: Falha ao resetar dados salvos!", + "2: Erro ao resetar os dados salvos!", "3: Dados salvos resetados com sucesso!", "4: Arquivo SVI exportado com sucesso!", - "5: Falha ao exportar arquivo SVI!", - "6: Esta opção não está disponível para saves do sistema!", + "5: Erro ao exportar arquivo SVI!", + "6: Esta opção não está disponível para saves de sistema!", "7: Não foi possível sanitizar o caminho para uso!", - "8: Pasta de saída configurada para #%s#.", - "9: Erro ao configurar novo caminho de saída!", + "8: Pasta de saída definida para #%s#.", + "9: Erro ao definir novo caminho de saída!", "10: Dados salvos estendidos com sucesso!", "11: Falha ao estender dados salvos!" ], "TitleOptionStatus": [ - "0: Deletando todos os backups para #%s#.", + "0: Excluindo todos os backups para #%s#.", "1: Resetando dados salvos para #%s#.", - "2: Deletando dados salvos de `%s` para #%s#...", + "2: Excluindo dados salvos de `%s` para #%s#...", "3: Estendendo dados salvos de `%s` para #%s#..." ], "TitleOptions": [ - "0: Informações", - "1: Colocar título na lista negra", + "0: Informação", + "1: Adicionar título à lista negra", "2: Alterar pasta de saída", "3: Abrir no modo arquivo", - "4: Deletar todos os backups locais", - "5: Deletar todos os backups remotos", - "6: Resetar dados salvos", - "7: Deletar dados salvos do sistema", + "4: Excluir todos os backups locais", + "5: Excluir todos os backups remotos", + "6: Resetar dados salvos.", + "7: Excluir dados salvos do sistema", "8: Estender dados salvos", "9: Exportar arquivo SVI" ], @@ -211,19 +214,19 @@ "1: NULL" ], "UserOptionConfirmations": [ - "0: Tem certeza que quer fazer backup dos dados salvos de todos os títulos encontrados para `%s`? Isso pode levar um tempo.", - "1: Tem certeza que quer criar dados salvos para todos os títulos encontrados no seu sistema para `%s`? Isso pode levar um tempo.", - "2: Tem certeza que quer deletar todos os dados salvos para `%s`? Isso é *PERMANENTE* e não pode ser desfeito." + "0: Tem certeza de que deseja fazer backup dos dados salvos para todos os títulos encontrados para `%s`? Isso pode demorar um pouco.", + "1: Tem certeza de que deseja criar dados salvos para todos os títulos encontrados no seu sistema para `%s`? Isso pode demorar um pouco.", + "2: Tem certeza de que deseja excluir todos os dados salvos para `%s`? Isso é *PERMANENTE* e não pode ser desfeito." ], "UserOptionStatus": [ "0: Criando dados salvos para #%s#...", - "1: Deletando dados salvos para #%s#..." + "1: Excluindo dados salvos para #%s#..." ], "UserOptions": [ "0: Descartar tudo para `%s`", "1: Criar dados salvos para `%s`", "2: Criar todos os dados salvos para `%s`", - "3: Deletar todos os dados salvos para `%s`" + "3: Excluir todos os dados salvos para `%s`" ], "WebDavStrings": [ "0: WebDav iniciado com sucesso!", diff --git a/romfs/Text/RU.json b/romfs/Text/RU.json index 7d23ec4..355379a 100644 --- a/romfs/Text/RU.json +++ b/romfs/Text/RU.json @@ -1,44 +1,44 @@ { "BackupMenu": [ - "0: Новый бэкап" + "0: Новый резервный копия" ], "BackupMenuConfirmations": [ - "0: Вы уверены, что хотите перезаписать #%s#?", - "1: Вы уверены, что хотите восстановить #%s#?", - "2: Вы уверены, что хотите удалить #%s#?" + "0: Вы уверены, что хотите действительно перезаписать #%s#?", + "1: Вы уверены, что хотите действительно восстановить #%s#?", + "2: Вы уверены, что хотите действительно удалить #%s#?" ], "BackupMenuPops": [ - "0: Данные сохранения пусты!", - "1: Бэкап пуст!", - "2: Ошибка при сбросе данных сохранения!", + "0: Сохранённые данные пусты!", + "1: Резервная копия пуста!", + "2: Ошибка сброса сохранённых данных!", "3: Ошибка при открытии ZIP-файла для чтения!", - "4: Произошла ошибка при удалении бэкапа!", - "5: Произошла ошибка при создании бэкапа!", + "4: Произошла ошибка при удалении резервной копии!", + "5: Ошибка создания резервной копии!", "6: Запись в систему отключена!", - "7: Не удалось открыть ZIP для чтения!", + "7: Не удалось открыть zip для чтения!", "8: Ошибка записи файла метаданных сохранения!", - "9: Ошибка при загрузке файла!", - "10: Ошибка при выгрузке файла!", + "9: Ошибка загрузки файла!", + "10: Ошибка загрузки файла на сервер!", "11: Ошибка обработки метаданных сохранения!", "12: Ошибка создания целевой директории!", - "13: Бэкап должен быть ZIP-файлом для загрузки!", - "14: Ошибка монтирования сохранения!", - "15: Ошибка закрытия сохранения!" + "13: Резервная копия должна быть в формате zip для загрузки!", + "14: Ошибка монтирования сохранённых данных!", + "15: Ошибка закрытия сохранённых данных!" ], "BackupMenuStatus": [ - "0: Обработка файла метаданных сохранения..." + "0: Обработка файла метаданных сохранённых данных..." ], "ControlGuides": [ "0: [A] Выбрать [Y] Сбросить все сохранения [X] Опции пользователя", - "1: [A] Выбрать [L] [R] Перейти [Y] Избранное [X] Опции игры [B] Назад", + "1: [A] Выбрать [L] [R] Перейти [Y] В избранное [X] Опции заголовка [B] Назад", "2: [A] Выбрать [Y] Восстановить [X] Удалить [ZR] Загрузить [B] Закрыть", "3: [A] Переключить [X] По умолчанию [B] Назад" ], "ExtrasMenu": [ "0: Переинициализировать данные", - "1: Браузер SD к SD", + "1: Браузер SD на SD", "2: ProdInfoF", - "3: Безопасность", + "3: Безопасно", "4: Система", "5: Пользователь", "6: Завершить процесс" @@ -51,9 +51,9 @@ "0: Невозможно выйти из JKSV, пока выполняются задачи!" ], "GoogleDriveStrings": [ - "0: Чтобы продолжить, перейдите на #%s# и введите >%s%s>!", "1: Успешный вход в Google Drive!", - "2: Не удалось войти в Google Drive!" + "2: Ошибка входа в Google Drive!" ], "HoldingStrings": [ "0: Удерживайте [A]", @@ -66,28 +66,28 @@ "2: Распаковка #%s# из ZIP...", "3: Удаление #%s#...", "4: Загрузка #%s#...", - "5: Отправка #%s# в удалённое хранилище...", + "5: Загрузка #%s# в удалённое хранилище...", "6: Обновление #%s# в удалённом хранилище..." ], "IOPops": [ "0: Ошибка записи данных на устройство!" ], "KeyboardStrings": [ - "0: Введите новое имя для бэкапа.", - "1: Введите индекс кэша.", - "2: Введите новый путь вывода для JKSV", + "0: Введите новое имя резервной копии.", + "1: Введите индекс кеша.", + "2: Введите новый путь вывода для JKSV.", "3: Введите ID процесса для завершения.", - "4: Введите системный ID сохранения", - "5: Введите новое имя для целевого элемента.", - "6: Введите имя для новой папки.", + "4: Введите системный ID сохранения.", + "5: Введите новое имя для целевого объекта.", + "6: Введите имя новой папки.", "7: Введите новое имя выходной папки для %s.", - "8: Введите, насколько расширить (в МБ)." + "8: Введите, на сколько расширить (в МБ)." ], "MainMenuConfs": [ - "0: Вы уверены, что хотите сделать бэкап сохранений для всех пользователей на этой системе? Это может занять *очень* много времени!" + "0: Вы уверены, что хотите создать резервную копию данных сохранений для каждого пользователя на этой системе? Это может занять *очень* много времени!" ], "MainMenuPops": [ - "0: `%s` не содержит сохранений!" + "0: `%s` не имеет сохранённых данных!" ], "OnOff": [ "0: Выкл", @@ -97,67 +97,70 @@ "0: Нет доступного интернет-соединения!" ], "SaveCreatePops": [ - "0: Данные сохранения созданы для #%s#!", - "1: Ошибка создания данных сохранения!", - "2: Ошибка удаления данных сохранения!" + "0: Созданы сохранённые данные для #%s#!", + "1: Ошибка создания сохранённых данных!", + "2: Ошибка удаления сохранённых данных!" ], "SaveDataTypes": [ "0: Система", "1: Аккаунт", "2: BCAT", "3: Устройство", - "4: Временные", + "4: Временный", "5: Кэш", "6: Системный BCAT" ], "SettingsDescriptions": [ "0: Устанавливает рабочую директорию для JKSV. Значение по умолчанию — `sdmc:/JKSV`.", - "1: Позволяет удалять игры из черного списка.", - "2: Включает сохранения устройства, или общие, с пользователями.", - "3: Автоматически создаёт бэкап при восстановлении другого.", - "4: Автоматически называет бэкапы и пропускает клавиатуру.", - "5: Автоматически загружает бэкапы в облако и удаляет их локально.", - "6: Всегда использует ID приложений для имен папок экспорта.", - "7: Требует удерживать [A] три секунды для удаления бэкапов.", - "8: Требует удерживать [A] три секунды для восстановления бэкапов.", - "9: Требует удерживать [A] три секунды для перезаписи бэкапов.", - "10: Показывает только сохранения, которые JKSV может открыть.", - "11: Показывает системные сохранения, связанные с аккаунтом.", - "12: Включает восстановление системных сохранений и запись в NAND.", - "13: Экспортирует сохранения в ZIP вместо распакованных папок.", - "14: Уровень сжатия при записи ZIP. По умолчанию 6. Меньше — быстрее, но меньше сжатие. 0 — без сжатия.", + "1: Позволяет удалять игры из чёрного списка.", + "2: Включает устройства или общие сохранения с пользователями.", + "3: Автоматически создаёт резервную копию при восстановлении другой.", + "4: Автоматически именует резервные копии и пропускает клавиатуру.", + "5: Автоматически загружает резервные копии в удалённое хранилище и удаляет локально.", + "6: Всегда использует ID приложений для имён папок экспорта.", + "7: Требует удерживать [A] три секунды для удаления резервных копий.", + "8: Требует удерживать [A] три секунды для восстановления резервных копий.", + "9: Требует удерживать [A] три секунды для перезаписи резервных копий.", + "10: Показывает только сохранённые данные, которые JKSV может успешно открыть.", + "11: Показывает системные сохранения, связанные с ID аккаунта.", + "12: Позволяет восстанавливать системные сохранения и записывать в NAND-разделы.", + "13: Экспортирует сохранённые данные в ZIP-архивы вместо распакованных папок.", + "14: Уровень сжатия при записи в ZIP. Значение по умолчанию — 6. Меньшие значения быстрее, но с меньшим сжатием и экономией места. Ноль — без сжатия.", "15: Управляет сортировкой и отображением игр.", - "16: Показывает игры как текстовые меню, как в оригинальном JKSM на 3DS, вместо сетки иконок.", - "17: Принуждает использовать английский язык вместо системного.", - "18: Перемещает удалённые бэкапы в папку _TRASH_ вместо полного удаления.", - "19: Устанавливает скорость переходов и анимаций. Меньше — быстрее." + "16: Показывает игры в виде текстовых меню, как в оригинальном JKSM на 3DS, вместо сетки иконок.", + "17: Принудительно использовать английский язык вместо системного.", + "18: Перемещает удалённые резервные копии в папку _TRASH_, вместо постоянного удаления.", + "19: Настраивает скорость переходов и анимаций. Меньшие значения — быстрее." ], "SettingsMenu": [ "0: Установить папку вывода JKSV.", - "1: Редактировать черный список", - "2: Включить сохранения устройства с пользователями: %s", - "3: Автоматический бэкап при восстановлении: %s", - "4: Автоматическое имя бэкапа: %s", - "5: Автоматическая загрузка бэкапов в облако: %s", + "1: Редактировать чёрный список", + "2: Включить сохранения устройств с пользователями: %s", + "3: Автобэкап при восстановлении: %s", + "4: Автоматически именовать резервные копии: %s", + "5: Автоматически загружать резервные копии в удалённое хранилище: %s", "6: Всегда использовать ID приложений: %s", - "7: Удерживать для удаления бэкапов: %s", - "8: Удерживать для восстановления бэкапов: %s", - "9: Удерживать для перезаписи бэкапов: %s", + "7: Удерживать для удаления резервных копий: %s", + "8: Удерживать для восстановления резервных копий: %s", + "9: Удерживать для перезаписи резервных копий: %s", "10: Показывать только монтируемые игры: %s", "11: Показывать системные сохранения с аккаунтом: %s", - "12: Включить запись системных сохранений и NAND: %s", + "12: Включить запись в системные сохранения и NAND: %s", "13: Экспортировать сохранения в ZIP: %s", "14: Уровень сжатия ZIP: %u", "15: Тип сортировки игр: %s", - "16: Режим текстового меню (JKSM): %s", + "16: Текстовый режим меню (JKSM): %s", "17: Принудительный английский: %s", "18: Включить корзину: %s", "19: Масштаб анимации: %.02f" ], + "SettingsPops": [ + "0: Чёрный список пуст!" + ], "SortTypes": [ "0: По алфавиту", - "1: По количеству запусков", - "2: По дате последнего запуска" + "1: Самые играемые", + "2: Последние игры" ], "TitleInfo": [ "0: ID приложения: %016lX", @@ -169,61 +172,61 @@ "6: Тип сохранения: %s" ], "TitleOptionConfirmations": [ - "0: Вы уверены, что хотите добавить #%s# в черный список? После этого он не будет отображаться в списках и выборе игр.", - "1: Вы уверены, что хотите удалить все текущие бэкапы для #%s#? *Это нельзя отменить!*", - "2: Вы уверены, что хотите сбросить данные сохранения для #%s#? *Это удалит текущие данные так, как будто игра никогда не запускалась!*", - "3: Вы уверены, что хотите удалить сохранения `%s` для #%s#? *Это удалит их навсегда из системы.*" + "0: Вы уверены, что хотите добавить #%s# в чёрный список? После этого он больше не будет отображаться в списках или выборах.", + "1: Вы уверены, что хотите удалить все текущие резервные копии для #%s#? *Это нельзя отменить!*", + "2: Вы уверены, что хотите сбросить сохранённые данные для #%s#? *Это удалит текущие данные, как если бы игра не запускалась!*", + "3: Вы уверены, что хотите удалить сохранённые данные `%s` для #%s#? *Это удалит их навсегда с системы.*" ], "TitleOptionPops": [ - "0: Все бэкапы удалены для #%s#!", - "1: Не удалось удалить все бэкапы!", - "2: Ошибка при сбросе данных сохранения!", - "3: Данные сохранения успешно сброшены!", + "0: Все резервные копии для #%s# удалены!", + "1: Не удалось удалить все резервные копии!", + "2: Ошибка сброса сохранённых данных!", + "3: Сохранённые данные успешно сброшены!", "4: Файл SVI успешно экспортирован!", - "5: Ошибка при экспорте файла SVI!", + "5: Ошибка экспорта файла SVI!", "6: Эта опция недоступна для системных сохранений!", - "7: Не удалось очистить путь для использования!", - "8: Папка вывода установлена на #%s#.", - "9: Ошибка при установке нового пути вывода!", - "10: Данные сохранения успешно расширены!", - "11: Ошибка при расширении данных сохранения!" + "7: Не удалось обработать путь для использования!", + "8: Папка вывода установлена в #%s#.", + "9: Ошибка установки нового пути вывода!", + "10: Данные успешно расширены!", + "11: Не удалось расширить данные!" ], "TitleOptionStatus": [ - "0: Удаление всех бэкапов для #%s#.", - "1: Сброс данных сохранения для #%s#.", - "2: Удаление сохранений `%s` для #%s#...", - "3: Расширение сохранений `%s` для #%s#..." + "0: Удаление всех резервных копий для #%s#.", + "1: Сброс сохранённых данных для #%s#.", + "2: Удаление сохранённых данных `%s` для #%s#...", + "3: Расширение сохранённых данных `%s` для #%s#..." ], "TitleOptions": [ "0: Информация", - "1: Добавить игру в черный список", + "1: Добавить игру в чёрный список", "2: Изменить папку вывода", "3: Открыть в файловом режиме", - "4: Удалить все локальные бэкапы", - "5: Удалить все удалённые бэкапы", - "6: Сбросить данные сохранения", - "7: Удалить данные сохранения из системы", - "8: Расширить данные сохранения", + "4: Удалить все локальные резервные копии", + "5: Удалить все удалённые резервные копии", + "6: Сбросить сохранённые данные.", + "7: Удалить сохранённые данные из системы", + "8: Расширить сохранённые данные", "9: Экспортировать файл SVI" ], "TranslationInfo": [ - "0: Переводчик: %s", + "0: Перевод выполнен: %s", "1: NULL" ], "UserOptionConfirmations": [ - "0: Вы уверены, что хотите сделать бэкап всех данных сохранения для всех игр, найденных для `%s`? Это может занять время.", - "1: Вы уверены, что хотите создать данные сохранения для всех игр, найденных в вашей системе для `%s`? Это может занять время.", - "2: Вы уверены, что хотите удалить все данные сохранения для `%s`? Это *НАВСЕГДА* и не может быть отменено." + "0: Вы уверены, что хотите создать резервную копию данных сохранений для всех найденных игр для `%s`? Это может занять некоторое время.", + "1: Вы уверены, что хотите создать сохранённые данные для всех найденных игр на вашей системе для `%s`? Это может занять некоторое время.", + "2: Вы уверены, что хотите удалить все сохранённые данные для `%s`? Это *НАВСЕГДА* и не может быть отменено." ], "UserOptionStatus": [ - "0: Создание данных сохранения для #%s#...", - "1: Удаление данных сохранения для #%s#..." + "0: Создание сохранённых данных для #%s#...", + "1: Удаление сохранённых данных для #%s#..." ], "UserOptions": [ "0: Сбросить всё для `%s`", - "1: Создать данные сохранения для `%s`", - "2: Создать все данные сохранения для `%s`", - "3: Удалить все данные сохранения для `%s`" + "1: Создать сохранённые данные для `%s`", + "2: Создать все сохранённые данные для `%s`", + "3: Удалить все сохранённые данные для `%s`" ], "WebDavStrings": [ "0: WebDav успешно запущен!", diff --git a/romfs/Text/ZHCN.json b/romfs/Text/ZHCN.json index 78b35bf..461a7ea 100644 --- a/romfs/Text/ZHCN.json +++ b/romfs/Text/ZHCN.json @@ -3,40 +3,40 @@ "0: 新建备份" ], "BackupMenuConfirmations": [ - "0: 您确定真的要覆盖#%s#吗?", - "1: 您确定真的要恢复#%s#吗?", - "2: 您确定真的要删除#%s#吗?" + "0: 您确定要覆盖 #%s# 吗?", + "1: 您确定要还原 #%s# 吗?", + "2: 您确定要删除 #%s# 吗?" ], "BackupMenuPops": [ - "0: 存档数据为空!", + "0: 保存数据为空!", "1: 备份为空!", - "2: 重置存档数据时出错!", - "3: 打开ZIP文件读取时出错!", + "2: 重置保存数据出错!", + "3: 打开ZIP文件读取出错!", "4: 删除备份时出错!", - "5: 创建备份时出错!", - "6: 系统写入已禁用!", - "7: 无法打开ZIP读取!", - "8: 写入存档元数据文件时出错!", - "9: 下载文件时出错!", - "10: 上传文件时出错!", - "11: 处理存档元数据时出错!", - "12: 创建目标目录时出错!", - "13: 备份必须是ZIP格式才能上传!", - "14: 挂载存档时出错!", - "15: 关闭存档时出错!" + "5: 创建备份出错!", + "6: 系统写入被禁用!", + "7: 无法打开ZIP进行读取!", + "8: 写入保存元数据文件出错!", + "9: 下载文件出错!", + "10: 上传文件出错!", + "11: 处理保存元数据出错!", + "12: 创建目标目录出错!", + "13: 上传的备份必须是ZIP格式!", + "14: 挂载保存数据出错!", + "15: 关闭保存数据出错!" ], "BackupMenuStatus": [ - "0: 正在处理存档元数据文件..." + "0: 正在处理保存元数据文件..." ], "ControlGuides": [ - "0: [A]选择 [Y]全部导出 [X]用户选项", - "1: [A]选择 [L] [R]跳转 [Y]添加收藏 [X]标题选项 [B]返回", - "2: [A]选择 [Y]恢复 [X]删除 [ZR]上传 [B]关闭", - "3: [A]切换 [X]默认设置 [B]返回" + "0: [A] 选择 [Y] 导出所有存档 [X] 用户选项", + "1: [A] 选择 [L] [R] 跳转 [Y] 收藏 [X] 标题选项 [B] 返回", + "2: [A] 选择 [Y] 还原 [X] 删除 [ZR] 上传 [B] 关闭", + "3: [A] 切换 [X] 默认 [B] 返回" ], "ExtrasMenu": [ "0: 重新初始化数据", - "1: SD卡文件管理", + "1: SD卡浏览器", "2: ProdInfoF", "3: 安全", "4: 系统", @@ -44,62 +44,62 @@ "6: 终止进程" ], "ExtrasPops": [ - "0: 数据重新初始化完成!", + "0: 数据已重新初始化!", "1: 数据重新初始化失败!" ], "GeneralPops": [ - "0: 任务正在运行中,无法退出JKSV!" + "0: 任务正在运行时无法退出JKSV!" ], "GoogleDriveStrings": [ - "0: 继续操作,请访问#%s#并输入>%s%s>!", + "1: 成功登录Google Drive!", + "2: Google Drive登录失败!" ], "HoldingStrings": [ - "0: 按住[A]", - "1: 继续按住[A]", + "0: 按住 [A]", + "1: 继续按住 [A]", "2: 快完成了![A]" ], "IOStatuses": [ - "0: 正在复制#%s#...", - "1: 正在压缩#%s#为ZIP...", - "2: 正在解压#%s#从ZIP...", - "3: 正在删除#%s#...", - "4: 正在下载#%s#...", - "5: 正在上传#%s#至远程存储...", - "6: 正在更新远程存储中的#%s#..." + "0: 正在复制 #%s#...", + "1: 正在将 #%s# 压缩为ZIP...", + "2: 正在从ZIP解压 #%s#...", + "3: 正在删除 #%s#...", + "4: 正在下载 #%s#...", + "5: 正在上传 #%s# 到远程存储...", + "6: 正在更新远程存储中的 #%s#..." ], "IOPops": [ - "0: 向设备提交数据时出错!" + "0: 提交数据到设备时出错!" ], "KeyboardStrings": [ "0: 输入新的备份名称。", "1: 输入缓存索引。", - "2: 输入JKSV的新输出路径", + "2: 输入JKSV的新输出路径。", "3: 输入要终止的进程ID。", - "4: 输入系统存档ID", + "4: 输入系统保存ID。", "5: 输入目标项的新名称。", - "6: 输入新建文件夹名称。", - "7: 输入%s的新输出文件夹名称。", - "8: 输入扩展大小(以MB计)。" + "6: 输入新文件夹名称。", + "7: 输入 %s 的新输出文件夹名称。", + "8: 输入扩展大小(MB)。" ], "MainMenuConfs": [ - "0: 您确定要为本系统上所有用户备份存档数据吗?这过程可能会花费*极*长的时间!" + "0: 您确定要为此系统上的每个用户备份保存数据吗?这可能会花费*非常*长的时间!" ], "MainMenuPops": [ - "0: `%s`没有存档数据!" + "0: `%s` 没有保存数据!" ], "OnOff": [ - "0: 关", - "1: >开<" + "0: 关闭", + "1: >开启>" ], "RemotePops": [ - "0: 没有可用的网络连接!" + "0: 无可用的网络连接!" ], "SaveCreatePops": [ - "0: 为#%s#成功创建了存档!", - "1: 创建存档失败!", - "2: 删除存档失败!" + "0: 已为 #%s# 创建保存数据!", + "1: 创建保存数据出错!", + "2: 删除保存数据出错!" ], "SaveDataTypes": [ "0: 系统", @@ -111,123 +111,126 @@ "6: 系统BCAT" ], "SettingsDescriptions": [ - "0: 设定JKSV的工作目录。默认值为`sdmc:/JKSV`。", - "1: 允许从黑名单中移除标题。", - "2: 将设备(共享存档)包含在用户中。", - "3: 恢复其他备份时自动创建备份。", - "4: 自动命名备份并跳过键盘。", - "5: 自动上传备份到远程并本地删除。", - "6: 始终使用应用ID作为导出文件夹名称。", - "7: 删除备份时需持续按[A]三秒。", - "8: 恢复备份时需持续按[A]三秒。", - "9: 覆盖备份时需持续按[A]三秒。", - "10: 仅显示JKSV可成功打开的存档。", - "11: 显示绑定账户的系统存档。", - "12: 启用恢复系统存档和NAND写入。", - "13: 导出存档为ZIP档案而非解压文件夹。", - "14: 写入ZIP时的压缩等级。默认为6。数值越低,速度越快,压缩效果越弱。0表示不压缩。", + "0: 设置JKSV的工作目录。默认值为 `sdmc:/JKSV`。", + "1: 允许您从黑名单中移除标题。", + "2: 包括设备或共享的保存数据与用户一起显示。", + "3: 恢复时自动创建备份。", + "4: 自动命名备份并跳过键盘输入。", + "5: 自动将备份上传到远程并本地删除。", + "6: 始终使用应用ID作为导出文件夹名。", + "7: 是否需要按住[A]三秒钟才能删除备份。", + "8: 是否需要按住[A]三秒钟才能恢复备份。", + "9: 是否需要按住[A]三秒钟才能覆盖备份。", + "10: 仅显示JKSV能成功打开的保存数据。", + "11: 显示绑定有账户ID的系统保存数据。", + "12: 启用恢复系统保存数据及写入NAND分区。", + "13: 将保存数据导出为ZIP归档,而非解压文件夹。", + "14: 写入ZIP时使用的压缩等级。默认值为6。数值越低速度越快,但压缩率和节省空间越少。0表示存储,无压缩。", "15: 控制标题的排序和显示方式。", - "16: 使用文本菜单(类JKSM)模式显示标题,而非图标网格。", - "17: 强制使用英文语言,而非系统侦测语言。", - "18: 删除的备份移动到_TRASH_文件夹,而非永久删除。", - "19: 设定转场和动画的速度。数值越小,速度越快。" + "16: 以文本菜单方式显示标题,类似JKSM在3DS上的原始界面,而非图标网格。", + "17: 强制使用英语作为语言,而非系统检测的语言。", + "18: 将删除的备份移动至_TRASH_文件夹,而非永久删除。", + "19: 设置过渡和动画速度。数值越低速度越快。" ], "SettingsMenu": [ - "0: 设定JKSV输出文件夹。", + "0: 设置JKSV输出文件夹。", "1: 编辑黑名单", - "2: 包含设备存档与用户:%s", + "2: 包含设备保存与用户:%s", "3: 恢复时自动备份:%s", "4: 自动命名备份:%s", - "5: 自动上传备份至远程存储:%s", + "5: 自动上传备份到远程存储:%s", "6: 始终使用应用ID:%s", - "7: 持续按[A]删除备份:%s", - "8: 持续按[A]恢复备份:%s", - "9: 持续按[A]覆盖备份:%s", - "10: 仅显示可挂载标题:%s", - "11: 显示绑定账户的系统存档:%s", - "12: 启用系统存档和NAND写入:%s", - "13: 导出存档为ZIP:%s", + "7: 按住删除备份:%s", + "8: 按住恢复备份:%s", + "9: 按住覆盖备份:%s", + "10: 仅显示可挂载的标题:%s", + "11: 显示账户系统保存:%s", + "12: 启用写入系统保存及NAND:%s", + "13: 导出保存为ZIP:%s", "14: ZIP压缩等级:%u", "15: 标题排序类型:%s", "16: 文本菜单(JKSM)模式:%s", - "17: 强制英文:%s", - "18: 启用垃圾桶:%s", - "19: 动画缩放比例:%.02f" + "17: 强制英语:%s", + "18: 启用回收站:%s", + "19: 动画缩放:%.02f" + ], + "SettingsPops": [ + "0: 黑名单为空!" ], "SortTypes": [ "0: 按字母顺序", - "1: 玩得最多", - "2: 最后玩过" + "1: 最常玩", + "2: 最后玩" ], "TitleInfo": [ - "0: 应用ID:%016lX", - "1: 存档ID:%016lx", - "2: 第一次玩:%x - %X", - "3: 最后一次玩:%x - %X", - "4: 游戏时长:%02d:%02d:%02d", - "5: 启动次数:%i", - "6: 存档类型:%s" + "0: 应用ID: %016lX", + "1: 保存ID: %016lx", + "2: 首次游玩: %x - %X", + "3: 最后游玩: %x - %X", + "4: 游戏时间: %02d:%02d:%02d", + "5: 启动次数: %i", + "6: 保存类型: %s" ], "TitleOptionConfirmations": [ - "0: 您确定要将#%s#加入黑名单吗?加入后将不会出现在任何标题列表或选择中。", - "1: 您确定要删除#%s#的所有当前备份吗?*此操作不可撤销!*", - "2: 您确定要重置#%s#的存档数据吗?*这会删除当前存档,如同从未游玩过!*", - "3: 您确定要删除`%s`的#%s#存档吗?*此操作将永久从系统中删除。*" + "0: 您确定要将 #%s# 加入黑名单吗?加入后,它将不再出现在任何标题列表或选择中。", + "1: 您确定要删除所有 #%s# 的当前备份吗?*此操作不可撤销!*", + "2: 您确定要重置 #%s# 的保存数据吗?*这将删除当前保存的数据,就像从未运行过该标题一样!*", + "3: 您确定要删除 `%s` 的 #%s# 保存数据吗?*这将在系统中永久删除它。*" ], "TitleOptionPops": [ - "0: 已删除#%s#的所有备份!", + "0: 已删除所有 #%s# 的备份!", "1: 删除所有备份失败!", - "2: 重置存档数据失败!", - "3: 成功重置存档数据!", - "4: 成功导出SVI文件!", - "5: 导出SVI文件失败!", - "6: 此选项不适用于系统存档!", + "2: 重置保存数据出错!", + "3: 保存数据重置成功!", + "4: SVI文件导出成功!", + "5: 导出SVI文件出错!", + "6: 该选项对系统保存不可用!", "7: 无法清理路径以供使用!", - "8: 输出文件夹设置为#%s#。", - "9: 设置新输出路径失败!", - "10: 成功扩展存档数据!", - "11: 扩展存档数据失败!" + "8: 输出文件夹设置为 #%s#。", + "9: 设置新输出路径出错!", + "10: 保存数据扩展成功!", + "11: 保存数据扩展失败!" ], "TitleOptionStatus": [ - "0: 正在删除#%s#的所有备份。", - "1: 正在重置#%s#的存档数据。", - "2: 正在删除`%s`的#%s#存档...", - "3: 正在扩展`%s`的#%s#存档..." + "0: 正在删除所有 #%s# 的备份。", + "1: 正在重置 #%s# 的保存数据。", + "2: 正在删除 `%s` 的 #%s# 保存数据…", + "3: 正在扩展 `%s` 的 #%s# 保存数据…" ], "TitleOptions": [ "0: 信息", - "1: 加入黑名单", + "1: 黑名单标题", "2: 更改输出文件夹", "3: 以文件模式打开", "4: 删除所有本地备份", "5: 删除所有远程备份", - "6: 重置存档数据", - "7: 从系统中删除存档", - "8: 扩展存档数据", + "6: 重置保存数据。", + "7: 从系统删除保存数据", + "8: 扩展保存数据", "9: 导出SVI文件" ], "TranslationInfo": [ - "0: 翻译:%s", + "0: 译者:%s", "1: NULL" ], "UserOptionConfirmations": [ - "0: 您确定要为`%s`找到的所有标题备份存档数据吗?这需要一段时间。", - "1: 您确定要为系统中找到的所有标题创建存档数据吗?这需要一段时间。", - "2: 您确定要删除`%s`的所有存档数据吗?*此操作不可撤销!*" + "0: 您确定要备份 `%s` 找到的所有标题的保存数据吗?这可能需要一段时间。", + "1: 您确定要为系统中找到的所有 `%s` 标题创建保存数据吗?这可能需要一段时间。", + "2: 您确定要删除 `%s` 的所有保存数据吗?此操作*不可恢复*。" ], "UserOptionStatus": [ - "0: 正在为#%s#创建存档数据...", - "1: 正在为#%s#删除存档数据..." + "0: 正在为 #%s# 创建保存数据…", + "1: 正在删除 #%s# 的保存数据…" ], "UserOptions": [ - "0: 全部导出`%s`", - "1: 创建`%s`的存档数据", - "2: 创建`%s`的所有存档数据", - "3: 删除`%s`的所有存档数据" + "0: 导出 `%s` 的所有内容", + "1: 为 `%s` 创建保存数据", + "2: 为 `%s` 创建所有保存数据", + "3: 删除 `%s` 的所有保存数据" ], "WebDavStrings": [ - "0: WebDav启动成功!", - "1: WebDav启动失败!" + "0: WebDav 启动成功!", + "1: WebDav 启动失败!" ], "YesNo": [ "0: 是 [A]", diff --git a/romfs/Text/ZHTW.json b/romfs/Text/ZHTW.json index 4b0bb7e..4d63710 100644 --- a/romfs/Text/ZHTW.json +++ b/romfs/Text/ZHTW.json @@ -1,42 +1,42 @@ { "BackupMenu": [ - "0: 新建備份" + "0: 新增備份" ], "BackupMenuConfirmations": [ - "0: 您確定真的要覆蓋#%s#嗎?", - "1: 您確定真的要還原#%s#嗎?", - "2: 您確定真的要刪除#%s#嗎?" + "0: 您確定要覆蓋 #%s# 嗎?", + "1: 您確定要還原 #%s# 嗎?", + "2: 您確定要刪除 #%s# 嗎?" ], "BackupMenuPops": [ - "0: 存檔資料為空!", + "0: 儲存資料為空!", "1: 備份為空!", - "2: 重設存檔資料時出錯!", - "3: 開啟ZIP檔案讀取時出錯!", - "4: 刪除備份時出錯!", - "5: 建立備份時出錯!", - "6: 系統寫入已被禁用!", - "7: 無法開啟ZIP讀取!", - "8: 寫入存檔元資料檔案時出錯!", - "9: 下載檔案時出錯!", - "10: 上傳檔案時出錯!", - "11: 處理存檔元資料時出錯!", - "12: 建立目標資料夾時出錯!", - "13: 備份必須為ZIP格式才能上傳!", - "14: 掛載存檔時出錯!", - "15: 關閉存檔時出錯!" + "2: 重置儲存資料時發生錯誤!", + "3: 開啟 ZIP 檔案讀取時發生錯誤!", + "4: 刪除備份時發生錯誤!", + "5: 建立備份時發生錯誤!", + "6: 系統寫入已被停用!", + "7: 無法開啟 zip 讀取!", + "8: 寫入儲存資料元資料檔案時發生錯誤!", + "9: 下載檔案時發生錯誤!", + "10: 上傳檔案時發生錯誤!", + "11: 處理儲存資料元資料時發生錯誤!", + "12: 建立目標資料夾時發生錯誤!", + "13: 上傳的備份必須是 zip 格式!", + "14: 掛載儲存資料時發生錯誤!", + "15: 關閉儲存資料時發生錯誤!" ], "BackupMenuStatus": [ - "0: 正在處理存檔元資料檔案..." + "0: 正在處理儲存資料元資料檔案..." ], "ControlGuides": [ - "0: [A] 選擇 [Y] 全部匯出 [X] 使用者選項", - "1: [A] 選擇 [L] [R] 跳轉 [Y] 加入收藏 [X] 標題選項 [B] 返回", + "0: [A] 選擇 [Y] 匯出所有存檔 [X] 使用者選項", + "1: [A] 選擇 [L] [R] 跳轉 [Y] 收藏 [X] 標題選項 [B] 返回", "2: [A] 選擇 [Y] 還原 [X] 刪除 [ZR] 上傳 [B] 關閉", - "3: [A] 切換 [X] 預設設定 [B] 返回" + "3: [A] 切換 [X] 預設 [B] 返回" ], "ExtrasMenu": [ "0: 重新初始化資料", - "1: SD卡瀏覽器", + "1: SD 至 SD 瀏覽器", "2: ProdInfoF", "3: 安全", "4: 系統", @@ -44,190 +44,193 @@ "6: 終止程序" ], "ExtrasPops": [ - "0: 資料重新初始化完成!", + "0: 資料已重新初始化!", "1: 資料重新初始化失敗!" ], "GeneralPops": [ - "0: 任務正在執行中,無法退出JKSV!" + "0: 任務執行時無法離開 JKSV!" ], "GoogleDriveStrings": [ - "0: 繼續操作,請前往#%s#並輸入>%s%s>!", + "1: 成功登入 Google Drive!", + "2: Google Drive 登入失敗!" ], "HoldingStrings": [ - "0: 按住[A]", - "1: 持續按住[A]", + "0: 按住 [A]", + "1: 繼續按住 [A]", "2: 快完成了![A]" ], "IOStatuses": [ - "0: 正在複製#%s#...", - "1: 正在壓縮#%s#為ZIP...", - "2: 正在解壓#%s#從ZIP...", - "3: 正在刪除#%s#...", - "4: 正在下載#%s#...", - "5: 正在上傳#%s#到遠端存儲...", - "6: 正在更新遠端存儲中的#%s#..." + "0: 正在複製 #%s#...", + "1: 正在壓縮 #%s# 至 ZIP...", + "2: 正在從 ZIP 解壓縮 #%s#...", + "3: 正在刪除 #%s#...", + "4: 正在下載 #%s#...", + "5: 正在上傳 #%s# 至遠端儲存...", + "6: 正在更新遠端儲存中的 #%s#..." ], "IOPops": [ - "0: 向裝置提交資料時出錯!" + "0: 提交資料至裝置時發生錯誤!" ], "KeyboardStrings": [ "0: 輸入新的備份名稱。", "1: 輸入快取索引。", - "2: 輸入JKSV的新輸出路徑", - "3: 輸入要終止的程序ID。", - "4: 輸入系統存檔ID", - "5: 輸入目標項的新名稱。", + "2: 輸入 JKSV 的新輸出路徑。", + "3: 輸入要終止的程序 ID。", + "4: 輸入系統存檔 ID。", + "5: 輸入目標項目新的名稱。", "6: 輸入新資料夾名稱。", - "7: 輸入%s的新輸出資料夾名稱。", + "7: 輸入 %s 的新輸出資料夾名稱。", "8: 輸入擴展大小(MB)。" ], "MainMenuConfs": [ - "0: 您確定要為本系統上所有使用者備份存檔資料嗎?這可能會花費*極*長時間!" + "0: 您確定要備份此系統中所有使用者的存檔資料嗎?這可能需要*非常*長的時間!" ], "MainMenuPops": [ - "0: `%s`沒有存檔資料!" + "0: `%s` 沒有存檔資料!" ], "OnOff": [ - "0: 關", - "1: >開<" + "0: 關閉", + "1: >開啟>" ], "RemotePops": [ "0: 無可用的網路連線!" ], "SaveCreatePops": [ - "0: 為#%s#成功建立存檔!", - "1: 建立存檔失敗!", - "2: 刪除存檔失敗!" + "0: 已為 #%s# 建立存檔資料!", + "1: 建立存檔資料失敗!", + "2: 刪除存檔資料失敗!" ], "SaveDataTypes": [ "0: 系統", - "1: 帳戶", + "1: 帳號", "2: BCAT", "3: 裝置", "4: 臨時", "5: 快取", - "6: 系統BCAT" + "6: 系統 BCAT" ], "SettingsDescriptions": [ - "0: 設定JKSV的工作目錄。預設為`sdmc:/JKSV`。", - "1: 允許從黑名單移除標題。", - "2: 將裝置(共享存檔)包含於使用者中。", - "3: 還原其他備份時自動建立備份。", - "4: 自動命名備份並跳過鍵盤。", - "5: 自動上傳備份至遠端並於本地刪除。", - "6: 始終使用應用ID作為匯出資料夾名稱。", - "7: 刪除備份時需持續按[A]三秒。", - "8: 還原備份時需持續按[A]三秒。", - "9: 覆蓋備份時需持續按[A]三秒。", - "10: 僅顯示JKSV可成功開啟的存檔。", - "11: 顯示綁定帳戶的系統存檔。", - "12: 啟用還原系統存檔及NAND寫入。", - "13: 匯出存檔為ZIP檔案,而非解壓資料夾。", - "14: 寫入ZIP時的壓縮等級。預設為6。數值越低,速度越快,壓縮效果越差。0表示不壓縮。", - "15: 控制標題排序及顯示方式。", - "16: 使用文字選單(類JKSM)模式顯示標題,而非圖示格子。", - "17: 強制使用英文語言,而非系統偵測語言。", - "18: 刪除的備份移至_TRASH_資料夾,而非永久刪除。", - "19: 設定過場及動畫速度。數值越小,速度越快。" + "0: 設定 JKSV 的工作目錄。預設值為 `sdmc:/JKSV`。", + "1: 允許您從黑名單中移除標題。", + "2: 包含裝置或共用存檔與使用者一起顯示。", + "3: 還原時自動建立備份。", + "4: 自動命名備份並跳過鍵盤輸入。", + "5: 自動將備份上傳到遠端並本地刪除。", + "6: 始終使用應用程式 ID 作為匯出資料夾名稱。", + "7: 是否需要按住 [A] 三秒才能刪除備份。", + "8: 是否需要按住 [A] 三秒才能還原備份。", + "9: 是否需要按住 [A] 三秒才能覆寫備份。", + "10: 只顯示 JKSV 可成功開啟的存檔資料。", + "11: 顯示綁定帳號 ID 的系統存檔。", + "12: 啟用還原系統存檔並寫入 NAND 分割區。", + "13: 將存檔匯出為 ZIP 壓縮檔而非解壓資料夾。", + "14: 寫入 ZIP 時使用的壓縮等級。預設值為 6。數值越低速度越快,但壓縮和空間節省較少。0 為儲存,無壓縮。", + "15: 控制標題排序與顯示方式。", + "16: 以文字選單顯示標題,類似原版 3DS JKSM,而非圖示網格。", + "17: 強制使用英文語言,而非系統語言。", + "18: 將刪除的備份移至 _TRASH_ 資料夾,而非永久刪除。", + "19: 設定轉場和動畫速度。數值越低速度越快。" ], "SettingsMenu": [ - "0: 設定JKSV輸出資料夾。", + "0: 設定 JKSV 輸出資料夾。", "1: 編輯黑名單", "2: 包含裝置存檔與使用者:%s", "3: 還原時自動備份:%s", "4: 自動命名備份:%s", - "5: 自動上傳備份至遠端存儲:%s", - "6: 始終使用應用ID:%s", - "7: 持續按[A]刪除備份:%s", - "8: 持續按[A]還原備份:%s", - "9: 持續按[A]覆蓋備份:%s", - "10: 僅顯示可掛載標題:%s", - "11: 顯示綁定帳戶的系統存檔:%s", - "12: 啟用系統存檔及NAND寫入:%s", - "13: 匯出存檔為ZIP:%s", - "14: ZIP壓縮等級:%u", + "5: 自動上傳備份至遠端儲存:%s", + "6: 始終使用應用程式 ID:%s", + "7: 按住刪除備份:%s", + "8: 按住還原備份:%s", + "9: 按住覆寫備份:%s", + "10: 只列出可掛載標題:%s", + "11: 顯示帳號系統存檔:%s", + "12: 啟用寫入系統存檔與 NAND:%s", + "13: 匯出存檔至 ZIP:%s", + "14: ZIP 壓縮等級:%u", "15: 標題排序類型:%s", "16: 文字選單(JKSM)模式:%s", - "17: 強制英文:%s", - "18: 啟用垃圾桶:%s", - "19: 動畫縮放比例:%.02f" + "17: 強制使用英文:%s", + "18: 啟用資源回收桶:%s", + "19: 動畫縮放:%.02f" + ], + "SettingsPops": [ + "0: 黑名單為空!" ], "SortTypes": [ - "0: 按字母順序", - "1: 最多遊玩", - "2: 最後遊玩" + "0: 按字母排序", + "1: 最常遊玩", + "2: 最近遊玩" ], "TitleInfo": [ - "0: 應用ID:%016lX", - "1: 存檔ID:%016lx", - "2: 第一次遊玩:%x - %X", - "3: 最後一次遊玩:%x - %X", - "4: 遊戲時長:%02d:%02d:%02d", - "5: 啟動次數:%i", - "6: 存檔類型:%s" + "0: 應用程式 ID: %016lX", + "1: 存檔 ID: %016lx", + "2: 首次遊玩: %x - %X", + "3: 最近遊玩: %x - %X", + "4: 遊玩時間: %02d:%02d:%02d", + "5: 啟動次數: %i", + "6: 存檔類型: %s" ], "TitleOptionConfirmations": [ - "0: 您確定要將#%s#加入黑名單嗎?加入後將不會出現在任何標題列表或選擇中。", - "1: 您確定要刪除#%s#的所有目前備份嗎?*此操作無法還原!*", - "2: 您確定要重設#%s#的存檔資料嗎?*這將刪除目前存檔,就像從未遊玩過一樣!*", - "3: 您確定要刪除`%s`的#%s#存檔嗎?*此操作將永久從系統中刪除。*" + "0: 您確定要將 #%s# 加入黑名單嗎?加入後,將不會出現在任何標題列表或選擇中。", + "1: 您確定要刪除 #%s# 的所有當前備份嗎?*此操作無法復原!*", + "2: 您確定要重置 #%s# 的存檔資料嗎?*這將刪除該標題的當前存檔,就像從未執行過一樣!*", + "3: 您確定要刪除 `%s` 的 #%s# 存檔資料嗎?*這將從系統永久刪除它。*" ], "TitleOptionPops": [ - "0: 已刪除#%s#的所有備份!", + "0: 已刪除 #%s# 的所有備份!", "1: 刪除所有備份失敗!", - "2: 重設存檔資料失敗!", - "3: 成功重設存檔資料!", - "4: 成功匯出SVI檔案!", - "5: 匯出SVI檔案失敗!", - "6: 此選項不適用於系統存檔!", - "7: 無法清理路徑供使用!", - "8: 輸出資料夾設定為#%s#。", - "9: 設定新輸出路徑失敗!", - "10: 成功擴展存檔資料!", - "11: 擴展存檔資料失敗!" + "2: 重置存檔資料錯誤!", + "3: 存檔資料重置成功!", + "4: SVI 檔案匯出成功!", + "5: 匯出 SVI 檔案錯誤!", + "6: 此選項對系統存檔不可用!", + "7: 無法清理路徑以供使用!", + "8: 輸出資料夾已設定為 #%s#。", + "9: 設定新輸出路徑錯誤!", + "10: 存檔資料擴展成功!", + "11: 存檔資料擴展失敗!" ], "TitleOptionStatus": [ - "0: 正在刪除#%s#的所有備份。", - "1: 正在重設#%s#的存檔資料。", - "2: 正在刪除`%s`的#%s#存檔...", - "3: 正在擴展`%s`的#%s#存檔..." + "0: 正在刪除 #%s# 的所有備份。", + "1: 正在重置 #%s# 的存檔資料。", + "2: 正在刪除 `%s` 的 #%s# 存檔資料…", + "3: 正在擴展 `%s` 的 #%s# 存檔資料…" ], "TitleOptions": [ "0: 資訊", - "1: 加入黑名單", + "1: 黑名單標題", "2: 更改輸出資料夾", "3: 以檔案模式開啟", "4: 刪除所有本地備份", "5: 刪除所有遠端備份", - "6: 重設存檔資料", - "7: 從系統中刪除存檔", + "6: 重置存檔資料。", + "7: 從系統刪除存檔資料", "8: 擴展存檔資料", - "9: 匯出SVI檔案" + "9: 匯出 SVI 檔案" ], "TranslationInfo": [ - "0: 翻譯:%s", + "0: 翻譯者:%s", "1: NULL" ], "UserOptionConfirmations": [ - "0: 您確定要為`%s`找到的所有標題備份存檔資料嗎?這可能需要一段時間。", - "1: 您確定要為系統中找到的所有標題建立存檔資料嗎?這可能需要一段時間。", - "2: 您確定要刪除`%s`的所有存檔資料嗎?*此操作無法還原!*" + "0: 您確定要備份 `%s` 找到的所有標題的存檔資料嗎?這可能需要一些時間。", + "1: 您確定要為系統中找到的所有 `%s` 標題建立存檔資料嗎?這可能需要一些時間。", + "2: 您確定要刪除 `%s` 的所有存檔資料嗎?此操作*不可復原*。" ], "UserOptionStatus": [ - "0: 正在為#%s#建立存檔資料...", - "1: 正在為#%s#刪除存檔資料..." + "0: 正在為 #%s# 建立存檔資料…", + "1: 正在刪除 #%s# 的存檔資料…" ], "UserOptions": [ - "0: 全部匯出`%s`", - "1: 建立`%s`的存檔資料", - "2: 建立`%s`的所有存檔資料", - "3: 刪除`%s`的所有存檔資料" + "0: 匯出 `%s` 的所有資料", + "1: 為 `%s` 建立存檔資料", + "2: 為 `%s` 建立所有存檔資料", + "3: 刪除 `%s` 的所有存檔資料" ], "WebDavStrings": [ - "0: WebDav啟動成功!", - "1: WebDav啟動失敗!" + "0: WebDav 啟動成功!", + "1: WebDav 啟動失敗!" ], "YesNo": [ "0: 是 [A]", diff --git a/romfs/Textures/Icon.alpha b/romfs/Textures/Icon.alpha deleted file mode 100644 index 9735322..0000000 Binary files a/romfs/Textures/Icon.alpha and /dev/null differ diff --git a/source/JKSV.cpp b/source/JKSV.cpp index 54e4e65..1a3df49 100644 --- a/source/JKSV.cpp +++ b/source/JKSV.cpp @@ -1,7 +1,6 @@ #include "JKSV.hpp" #include "StateManager.hpp" -#include "appstates/FadeInState.hpp" #include "appstates/MainMenuState.hpp" #include "appstates/TaskState.hpp" #include "colors.hpp" @@ -14,6 +13,7 @@ #include "remote/remote.hpp" #include "sdl.hpp" #include "strings.hpp" +#include "stringutil.hpp" #include "ui/PopMessageManager.hpp" #include @@ -49,6 +49,8 @@ static bool initialize_service(Result (*function)(Args...), const char *serviceN // This can't really have an initializer list since it sets everything up. JKSV::JKSV() { + const std::time_t beginTime = std::time(nullptr); + appletSetCpuBoostMode(ApmCpuBoostMode_FastLoad); ABORT_ON_FAILURE(JKSV::initialize_services()); ABORT_ON_FAILURE(JKSV::initialize_filesystem()); @@ -57,9 +59,12 @@ JKSV::JKSV() ABORT_ON_FAILURE(curl::initialize()); ABORT_ON_FAILURE(strings::initialize()); // This is fatal now. - m_translation = strings::get_by_name(strings::names::TRANSLATION, 0); - m_author = strings::get_by_name(strings::names::TRANSLATION, 1); - m_showTranslationInfo = std::char_traits::compare(m_author, "NULL", 4) != 0; // This is whether or not to show. + + const char *translationFormat = strings::get_by_name(strings::names::TRANSLATION, 0); + const char *author = strings::get_by_name(strings::names::TRANSLATION, 1); + m_showTranslationInfo = std::char_traits::compare(author, "NULL", 4) != 0; // This is whether or not to show. + m_translationInfo = stringutil::get_formatted_string(translationFormat, author); + m_buildString = stringutil::get_formatted_string("v. %02d.%02d.%04d", BUILD_MON, BUILD_DAY, BUILD_YEAR); input::initialize(); config::initialize(); @@ -78,6 +83,10 @@ JKSV::JKSV() if (fslib::file_exists(remote::PATH_GOOGLE_DRIVE_CONFIG)) { remote::initialize_google_drive(); } else if (fslib::file_exists(remote::PATH_WEBDAV_CONFIG)) { remote::initialize_webdav(); } + const std::time_t endTime = std::time(nullptr); + const double diff = std::difftime(endTime, beginTime); + logger::log("Boot time: %.02f seconds.", diff); + m_isRunning = true; } @@ -111,32 +120,20 @@ void JKSV::render() sdl::frame_begin(colors::CLEAR_COLOR); // Top and bottom divider lines. - sdl::render_line(NULL, 30, 88, 1250, 88, colors::WHITE); - sdl::render_line(NULL, 30, 648, 1250, 648, colors::WHITE); - + sdl::render_line(sdl::Texture::Null, 30, 88, 1250, 88, colors::WHITE); + sdl::render_line(sdl::Texture::Null, 30, 648, 1250, 648, colors::WHITE); // Icon - m_headerIcon->render(NULL, 66, 27); - + m_headerIcon->render(sdl::Texture::Null, 66, 27); // "JKSV" - sdl::text::render(NULL, 130, 32, 34, sdl::text::NO_TEXT_WRAP, colors::WHITE, "JKSV"); + sdl::text::render(sdl::Texture::Null, 130, 32, 34, sdl::text::NO_WRAP, colors::WHITE, "JKSV"); // Translation info in bottom left. if (m_showTranslationInfo) { - sdl::text::render(NULL, 8, 680, 14, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_translation, m_author); + sdl::text::render(sdl::Texture::Null, 8, 680, 14, sdl::text::NO_WRAP, colors::WHITE, m_translationInfo); } - // Build date - sdl::text::render(NULL, - 8, - 700, - 14, - sdl::text::NO_TEXT_WRAP, - colors::WHITE, - "v. %02d.%02d.%04d", - BUILD_MON, - BUILD_DAY, - BUILD_YEAR); + sdl::text::render(sdl::Texture::Null, 8, 700, 14, sdl::text::NO_WRAP, colors::WHITE, m_buildString); StateManager::render(); ui::PopMessageManager::render(); diff --git a/source/appstates/BackupMenuState.cpp b/source/appstates/BackupMenuState.cpp index 6e0416b..45ffe14 100644 --- a/source/appstates/BackupMenuState.cpp +++ b/source/appstates/BackupMenuState.cpp @@ -2,6 +2,7 @@ #include "StateManager.hpp" #include "appstates/ConfirmState.hpp" +#include "appstates/FadeState.hpp" #include "appstates/ProgressState.hpp" #include "colors.hpp" #include "config.hpp" @@ -28,12 +29,12 @@ namespace } // namespace BackupMenuState::BackupMenuState(data::User *user, data::TitleInfo *titleInfo) - : m_user{user} - , m_titleInfo{titleInfo} - , m_saveType{m_user->get_account_save_type()} - , m_directoryPath{config::get_working_directory() / m_titleInfo->get_path_safe_title()} - , m_dataStruct{std::make_shared()} - , m_controlGuide{strings::get_by_name(strings::names::CONTROL_GUIDES, 2)} + : m_user(user) + , m_titleInfo(titleInfo) + , m_saveType(m_user->get_account_save_type()) + , m_directoryPath(config::get_working_directory() / m_titleInfo->get_path_safe_title()) + , m_dataStruct(std::make_shared()) + , m_controlGuide(strings::get_by_name(strings::names::CONTROL_GUIDES, 2)) { BackupMenuState::initialize_static_members(); BackupMenuState::ensure_target_directory(); @@ -46,14 +47,12 @@ BackupMenuState::BackupMenuState(data::User *user, data::TitleInfo *titleInfo) BackupMenuState::~BackupMenuState() { - fslib::close_file_system(fs::DEFAULT_SAVE_MOUNT); - sm_slidePanel->clear_elements(); sm_slidePanel->reset(); sm_backupMenu->reset(); remote::Storage *remote = remote::get_remote_storage(); - if (remote && remote->is_initialized()) { remote->return_to_root(); } + if (remote) { remote->return_to_root(); } } std::shared_ptr BackupMenuState::create(data::User *user, data::TitleInfo *titleInfo) @@ -70,7 +69,11 @@ std::shared_ptr BackupMenuState::create_and_push(data::User *us void BackupMenuState::update() { - const bool hasFocus = BaseState::has_focus(); + const bool hasFocus = BaseState::has_focus(); + const bool isOpen = sm_slidePanel->is_open(); + sm_slidePanel->update(hasFocus); + if (!isOpen) { return; } + const int selected = sm_backupMenu->get_selected(); const bool aPressed = input::button_pressed(HidNpadButton_A); const bool bPressed = input::button_pressed(HidNpadButton_B); @@ -96,27 +99,26 @@ void BackupMenuState::update() else if (sm_slidePanel->is_closed()) { BaseState::deactivate(); } m_titleScroll.update(hasFocus); - sm_slidePanel->update(hasFocus); sm_backupMenu->update(hasFocus); } void BackupMenuState::render() { - const bool hasFocus = BaseState::has_focus(); - SDL_Texture *target = sm_slidePanel->get_target(); + const bool hasFocus = BaseState::has_focus(); + sdl::SharedTexture &target = sm_slidePanel->get_target(); sm_slidePanel->clear_target(); m_titleScroll.render(target, hasFocus); sdl::render_line(target, 10, 42, sm_panelWidth - 10, 42, colors::WHITE); sdl::render_line(target, 10, 648, sm_panelWidth - 10, 648, colors::WHITE); - sdl::text::render(target, 32, 673, 22, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_controlGuide); + sdl::text::render(target, 32, 673, 22, sdl::text::NO_WRAP, colors::WHITE, m_controlGuide); sm_menuRenderTarget->clear(colors::TRANSPARENT); - sm_backupMenu->render(sm_menuRenderTarget->get(), hasFocus); + sm_backupMenu->render(sm_menuRenderTarget, hasFocus); sm_menuRenderTarget->render(target, 0, 43); - sm_slidePanel->render(NULL, hasFocus); + sm_slidePanel->render(sdl::Texture::Null, hasFocus); } void BackupMenuState::refresh() @@ -124,19 +126,18 @@ void BackupMenuState::refresh() const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD); remote::Storage *remote = remote::get_remote_storage(); m_directoryListing.open(m_directoryPath); - if (!autoUpload && !m_directoryListing) { return; } - const char *optionNew = strings::get_by_name(strings::names::BACKUPMENU_MENU, 0); - + if (!autoUpload && !m_directoryListing.is_open()) { return; } sm_backupMenu->reset(); m_menuEntries.clear(); + const char *optionNew = strings::get_by_name(strings::names::BACKUPMENU_MENU, 0); sm_backupMenu->add_option(optionNew); m_menuEntries.push_back({MenuEntryType::Null, 0}); - if (remote && remote->is_initialized()) + if (remote) { const std::string_view prefix = remote->get_prefix(); - m_remoteListing = remote->get_directory_listing(); + remote->get_directory_listing(m_remoteListing); int index{}; for (const remote::Item *item : m_remoteListing) { @@ -163,13 +164,13 @@ void BackupMenuState::save_data_written() void BackupMenuState::initialize_static_members() { - constexpr int SDL_TEX_FLAGS = SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET; if (sm_backupMenu && sm_slidePanel && sm_menuRenderTarget && sm_panelWidth) { return; } - sm_panelWidth = sdl::text::get_width(22, m_controlGuide) + 64; - sm_backupMenu = std::make_shared(8, 8, sm_panelWidth - 14, 24, 600); - sm_slidePanel = std::make_unique(sm_panelWidth, ui::SlideOutPanel::Side::Right); - sm_menuRenderTarget = sdl::TextureManager::create_load_texture("backupMenuTarget", sm_panelWidth, 600, SDL_TEX_FLAGS); + sm_panelWidth = sdl::text::get_width(22, m_controlGuide) + 64; + sm_backupMenu = std::make_shared(8, 8, sm_panelWidth - 16, 24, 600); + sm_slidePanel = std::make_unique(sm_panelWidth, ui::SlideOutPanel::Side::Right); + sm_menuRenderTarget = + sdl::TextureManager::create_load_texture("backupMenuTarget", sm_panelWidth, 600, SDL_TEXTUREACCESS_TARGET); } void BackupMenuState::ensure_target_directory() @@ -198,7 +199,7 @@ void BackupMenuState::initialize_info_string() const char *title = m_titleInfo->get_title(); const std::string infoString = stringutil::get_formatted_string("`%s` - %s", nickname, title); - m_titleScroll.create(infoString, 8, 8, sm_panelWidth - 16, 30, 22, colors::WHITE, colors::TRANSPARENT); + m_titleScroll.initialize(infoString, 8, 8, sm_panelWidth - 16, 30, 22, colors::WHITE, colors::TRANSPARENT); } void BackupMenuState::save_data_check() @@ -240,7 +241,6 @@ void BackupMenuState::name_and_create_backup() const bool exportZip = autoUpload || config::get_by_key(config::keys::EXPORT_TO_ZIP); const bool zrHeld = input::button_held(HidNpadButton_ZR); const bool autoNamed = (autoName || zrHeld); // This can be eval'd here. - const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; char name[SIZE_NAME_LENGTH + 1] = {0}; { @@ -267,16 +267,8 @@ void BackupMenuState::name_and_create_backup() else { fslib::Path target{m_directoryPath / name}; - const bool dirNeeded = !exportZip && !fslib::directory_exists(target); - const bool dirError = dirNeeded && error::fslib(fslib::create_directory(target)); + if (!hasZipExt && (autoUpload || exportZip)) { target += STRING_ZIP_EXT; } // We're going to append zip either way. - if (exportZip && !hasZipExt) { target += STRING_ZIP_EXT; } - else if (!exportZip && dirNeeded && dirError) - { - const char *popErrorCreating = strings::get_by_name(strings::names::BACKUPMENU_POPS, 5); - ui::PopMessageManager::push_message(popTicks, popErrorCreating); - return; - } ProgressState::create_and_push(tasks::backup::create_new_backup_local, m_user, m_titleInfo, target, this, true); } } @@ -338,7 +330,8 @@ void BackupMenuState::confirm_restore() m_dataStruct->path = target; const std::string query = stringutil::get_formatted_string(confirmTemplate, m_directoryListing[entry.index]); - ProgressConfirm::create_and_push(query, holdRequired, tasks::backup::restore_backup_local, m_dataStruct); + auto confirm = ProgressConfirm::create(query, holdRequired, tasks::backup::restore_backup_local, m_dataStruct); + FadeState::create_and_push(colors::DIM_BACKGROUND, 0x00, 0x88, confirm); } else if (entry.type == MenuEntryType::Remote) { @@ -346,7 +339,8 @@ void BackupMenuState::confirm_restore() const std::string query = stringutil::get_formatted_string(confirmTemplate, target->get_name().data()); m_dataStruct->remoteItem = target; - ProgressConfirm::create_and_push(query, holdRequired, tasks::backup::restore_backup_remote, m_dataStruct); + auto confirm = ProgressConfirm::create(query, holdRequired, tasks::backup::restore_backup_remote, m_dataStruct); + FadeState::create_and_push(colors::DIM_BACKGROUND, 0x00, 0x88, confirm); } } diff --git a/source/appstates/BaseState.cpp b/source/appstates/BaseState.cpp index 594ad7a..c7f1d20 100644 --- a/source/appstates/BaseState.cpp +++ b/source/appstates/BaseState.cpp @@ -1,18 +1,20 @@ #include "appstates/BaseState.hpp" +#include "error.hpp" + #include BaseState::BaseState(bool isClosable) - : m_isClosable{isClosable} + : m_isClosable(isClosable) { if (m_isClosable) { return; } - appletBeginBlockingHomeButton(0); + error::libnx(appletBeginBlockingHomeButton(0)); } BaseState::~BaseState() { if (m_isClosable) { return; } - appletEndBlockingHomeButton(); + error::libnx(appletEndBlockingHomeButton()); } void BaseState::deactivate() { m_isActive = false; } diff --git a/source/appstates/BaseTask.cpp b/source/appstates/BaseTask.cpp index 998bf31..ab1841d 100644 --- a/source/appstates/BaseTask.cpp +++ b/source/appstates/BaseTask.cpp @@ -12,8 +12,8 @@ namespace } // namespace BaseTask::BaseTask() - : BaseState{false} - , m_popUnableExit{strings::get_by_name(strings::names::GENERAL_POPS, 0)} + : BaseState(false) + , m_popUnableExit(strings::get_by_name(strings::names::GENERAL_POPS, 0)) { m_frameTimer.start(TICKS_GLYPH_TRIGGER); } @@ -38,7 +38,5 @@ void BaseTask::update() void BaseTask::render_loading_glyph() { - const char *currentFrame = sm_glyphArray[m_currentFrame].data(); - - sdl::text::render(NULL, 56, 673, 32, sdl::text::NO_TEXT_WRAP, m_colorMod, currentFrame); + sdl::text::render(sdl::Texture::Null, 56, 673, 32, sdl::text::NO_WRAP, m_colorMod, sm_glyphArray[m_currentFrame]); } diff --git a/source/appstates/BlacklistEditState.cpp b/source/appstates/BlacklistEditState.cpp new file mode 100644 index 0000000..22a9f56 --- /dev/null +++ b/source/appstates/BlacklistEditState.cpp @@ -0,0 +1,95 @@ +#include "appstates/BlacklistEditState.hpp" + +#include "StateManager.hpp" +#include "appstates/MainMenuState.hpp" +#include "config.hpp" +#include "data/data.hpp" +#include "error.hpp" +#include "input.hpp" + +BlacklistEditState::BlacklistEditState() + : BaseState() +{ + BlacklistEditState::initialize_static_members(); + BlacklistEditState::load_blacklist(); + BlacklistEditState::initialize_menu(); + BlacklistEditState::refresh_menu(); +} + +BlacklistEditState::~BlacklistEditState() +{ + sm_slidePanel->clear_elements(); + sm_slidePanel->reset(); +} + +std::shared_ptr BlacklistEditState::create() { return std::make_shared(); } + +std::shared_ptr BlacklistEditState::create_and_push() +{ + auto newState = std::make_shared(); + StateManager::push_state(newState); + return newState; +} + +void BlacklistEditState::update() +{ + const bool hasFocus = BaseState::has_focus(); + const bool aPressed = input::button_pressed(HidNpadButton_A); + const bool bPressed = input::button_pressed(HidNpadButton_B); + + sm_slidePanel->update(hasFocus); + + if (aPressed) { BlacklistEditState::remove_from_blacklist(); } + else if (bPressed) { sm_slidePanel->close(); } + else if (sm_slidePanel->is_closed()) { BaseState::deactivate(); } +} + +void BlacklistEditState::render() +{ + const bool hasFocus = BaseState::has_focus(); + sm_slidePanel->clear_target(); + sm_slidePanel->render(sdl::Texture::Null, hasFocus); +} + +void BlacklistEditState::initialize_static_members() +{ + if (sm_slidePanel) { return; } + sm_slidePanel = std::make_unique(480, ui::SlideOutPanel::Side::Right); +} + +void BlacklistEditState::load_blacklist() { config::get_blacklisted_titles(m_blacklist); } + +void BlacklistEditState::initialize_menu() +{ + m_blacklistMenu = std::make_shared(8, 8, 460, 22, 720); + sm_slidePanel->push_new_element(m_blacklistMenu); +} + +void BlacklistEditState::refresh_menu() +{ + m_blacklistMenu->reset(); + + config::get_blacklisted_titles(m_blacklist); + for (const uint64_t &applicationID : m_blacklist) + { + data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + if (error::is_null(titleInfo)) { continue; } + + const char *title = titleInfo->get_title(); + m_blacklistMenu->add_option(title); + } +} + +void BlacklistEditState::remove_from_blacklist() +{ + const int selected = m_blacklistMenu->get_selected(); + const uint64_t applicationID = m_blacklist[selected]; + config::add_remove_blacklist(applicationID); + + data::UserList userList{}; + data::get_users(userList); + for (data::User *user : userList) { user->load_user_data(); } + + MainMenuState::refresh_view_states(); + BlacklistEditState::refresh_menu(); +} diff --git a/source/appstates/ExtrasMenuState.cpp b/source/appstates/ExtrasMenuState.cpp index 0d9ac26..d804641 100644 --- a/source/appstates/ExtrasMenuState.cpp +++ b/source/appstates/ExtrasMenuState.cpp @@ -29,11 +29,8 @@ namespace } // namespace ExtrasMenuState::ExtrasMenuState() - : m_extrasMenu{32, 8, 1000, 24, 555} - , m_renderTarget{sdl::TextureManager::create_load_texture(SECONDARY_TARGET, - 1080, - 555, - SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET)} + : m_extrasMenu(32, 8, 1000, 24, 555) + , m_renderTarget(sdl::TextureManager::create_load_texture(SECONDARY_TARGET, 1080, 555, SDL_TEXTUREACCESS_TARGET)) { ExtrasMenuState::initialize_menu(); } @@ -63,8 +60,8 @@ void ExtrasMenuState::render() const bool hasFocus = BaseState::has_focus(); m_renderTarget->clear(colors::TRANSPARENT); - m_extrasMenu.render(m_renderTarget->get(), hasFocus); - m_renderTarget->render(NULL, 201, 91); + m_extrasMenu.render(m_renderTarget, hasFocus); + m_renderTarget->render(sdl::Texture::Null, 201, 91); } void ExtrasMenuState::initialize_menu() diff --git a/source/appstates/FadeInState.cpp b/source/appstates/FadeInState.cpp deleted file mode 100644 index b1cbb88..0000000 --- a/source/appstates/FadeInState.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "appstates/FadeInState.hpp" - -#include "StateManager.hpp" -#include "sdl.hpp" - -FadeInState::FadeInState(std::shared_ptr nextState) - : m_nextState{nextState} -{ - m_fadeTimer.start(1); -} - -std::shared_ptr FadeInState::create(std::shared_ptr nextState) -{ - return std::make_shared(nextState); -} - -std::shared_ptr FadeInState::create_and_push(std::shared_ptr nextState) -{ - auto newState = FadeInState::create(nextState); - StateManager::push_state(newState); - return newState; -} - -void FadeInState::update() -{ - if (m_alpha == 0x00) - { - StateManager::push_state(m_nextState); - BaseState::deactivate(); - } - else if (m_fadeTimer.is_triggered()) { m_alpha -= 15; } -} - -void FadeInState::render() -{ - m_nextState->render(); - const uint32_t rawColor = 0x000000 | m_alpha; - const sdl::Color fadeColor{rawColor}; - sdl::render_rect_fill(nullptr, 0, 0, 1280, 720, fadeColor); -} diff --git a/source/appstates/FadeState.cpp b/source/appstates/FadeState.cpp new file mode 100644 index 0000000..254bde2 --- /dev/null +++ b/source/appstates/FadeState.cpp @@ -0,0 +1,89 @@ +#include "appstates/FadeState.hpp" + +#include "StateManager.hpp" +#include "logger.hpp" +#include "mathutil.hpp" +#include "sdl.hpp" + +namespace +{ + constexpr uint64_t TICKS_TIMER_TRIGGER = 1; +} + +FadeState::FadeState(sdl::Color baseColor, uint8_t startAlpha, uint8_t endAlpha, std::shared_ptr nextState) + : m_baseColor(baseColor) + , m_alpha(startAlpha) + , m_endAlpha(endAlpha) + , m_nextState(nextState) +{ + m_direction = m_endAlpha < m_alpha ? FadeState::Direction::In : FadeState::Direction::Out; + + FadeState::find_divisor(); + m_fadeTimer.start(TICKS_TIMER_TRIGGER); +} + +std::shared_ptr FadeState::create(sdl::Color baseColor, + uint8_t startAlpha, + uint8_t endAlpha, + std::shared_ptr nextState) +{ + return std::make_shared(baseColor, startAlpha, endAlpha, nextState); +} + +std::shared_ptr FadeState::create_and_push(sdl::Color baseColor, + uint8_t startAlpha, + uint8_t endAlpha, + std::shared_ptr nextState) +{ + auto newState = std::make_shared(baseColor, startAlpha, endAlpha, nextState); + StateManager::push_state(newState); + return newState; +} + +void FadeState::update() +{ + if (m_alpha == m_endAlpha) + { + FadeState::completed(); + return; + } + + switch (m_direction) + { + case Direction::In: FadeState::decrease_alpha(); break; + case Direction::Out: FadeState::increase_alpha(); break; + } +} + +void FadeState::render() +{ + const uint32_t rawColor = (m_baseColor.raw & 0xFFFFFF00) | m_alpha; + const sdl::Color fadeColor{rawColor}; + + sdl::render_rect_fill(sdl::Texture::Null, 0, 0, 1280, 720, fadeColor); +} + +void FadeState::find_divisor() +{ + m_divisor = math::Util::absolute_distance(m_alpha, m_endAlpha); + + // Going to loop and try to find the highest divisible number. To do: Maybe not brute force this? + for (uint8_t i = 48; i > 0; i--) + { + if (m_divisor % i == 0) + { + m_divisor = i; + break; + } + } +} + +void FadeState::decrease_alpha() { m_alpha -= m_divisor; } + +void FadeState::increase_alpha() { m_alpha += m_divisor; } + +void FadeState::completed() +{ + if (m_nextState) { StateManager::push_state(m_nextState); } + BaseState::deactivate(); +} diff --git a/source/appstates/MainMenuState.cpp b/source/appstates/MainMenuState.cpp index 9b59fbe..4e2dc75 100644 --- a/source/appstates/MainMenuState.cpp +++ b/source/appstates/MainMenuState.cpp @@ -25,17 +25,14 @@ namespace } MainMenuState::MainMenuState() - : m_renderTarget{sdl::TextureManager::create_load_texture("mainMenuTarget", - 200, - 555, - SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET)} - , m_background{sdl::TextureManager::create_load_texture("mainBackground", "romfs:/Textures/MenuBackground.png")} - , m_settingsIcon{sdl::TextureManager::create_load_texture("settingsIcon", "romfs:/Textures/SettingsIcon.png")} - , m_extrasIcon{sdl::TextureManager::create_load_texture("extrasIcon", "romfs:/Textures/ExtrasIcon.png")} - , m_mainMenu{50, 15, 555} - , m_controlGuide{strings::get_by_name(strings::names::CONTROL_GUIDES, 0)} - , m_controlGuideX{static_cast(1220 - sdl::text::get_width(22, m_controlGuide))} - , m_dataStruct{std::make_shared()} + : m_renderTarget(sdl::TextureManager::create_load_texture("mainMenuTarget", 200, 555, SDL_TEXTUREACCESS_TARGET)) + , m_background(sdl::TextureManager::create_load_texture("mainBackground", "romfs:/Textures/MenuBackground.png")) + , m_settingsIcon(sdl::TextureManager::create_load_texture("settingsIcon", "romfs:/Textures/SettingsIcon.png")) + , m_extrasIcon(sdl::TextureManager::create_load_texture("extrasIcon", "romfs:/Textures/ExtrasIcon.png")) + , m_mainMenu(50, 15, 555) + , m_controlGuide(strings::get_by_name(strings::names::CONTROL_GUIDES, 0)) + , m_controlGuideX(1220 - sdl::text::get_width(22, m_controlGuide)) + , m_dataStruct(std::make_shared()) { MainMenuState::initialize_settings_extras(); MainMenuState::initialize_menu(); @@ -74,16 +71,16 @@ void MainMenuState::render() const bool hasFocus = BaseState::has_focus(); const int selected = m_mainMenu.get_selected(); - m_background->render(m_renderTarget->get(), 0, 0); - m_mainMenu.render(m_renderTarget->get(), hasFocus); - m_renderTarget->render(NULL, 0, 91); + m_background->render(m_renderTarget, 0, 0); + m_mainMenu.render(m_renderTarget, hasFocus); + m_renderTarget->render(sdl::Texture::Null, 0, 91); if (hasFocus) { BaseState *target = sm_states.at(selected).get(); target->render(); - sdl::text::render(NULL, m_controlGuideX, 673, 22, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_controlGuide); + sdl::text::render(sdl::Texture::Null, m_controlGuideX, 673, 22, sdl::text::NO_WRAP, colors::WHITE, m_controlGuide); } } diff --git a/source/appstates/ProgressState.cpp b/source/appstates/ProgressState.cpp index c3eac9a..3cb3182 100644 --- a/source/appstates/ProgressState.cpp +++ b/source/appstates/ProgressState.cpp @@ -1,43 +1,70 @@ #include "appstates/ProgressState.hpp" +#include "appstates/FadeState.hpp" #include "colors.hpp" #include "input.hpp" #include "sdl.hpp" #include "strings.hpp" #include "stringutil.hpp" #include "ui/PopMessageManager.hpp" -#include "ui/render_functions.hpp" #include +namespace +{ + constexpr int COORD_BAR_X = 312; + constexpr int COORD_BAR_Y = 462; + + constexpr int COORD_TEXT_Y = 468; + + constexpr int COORD_DISPLAY_CENTER = 640; + constexpr double SIZE_BAR_WIDTH = 656.0f; + constexpr int SIZE_FONT_SIZE = 18; +} + +ProgressState::~ProgressState() { FadeState::create_and_push(colors::DIM_BACKGROUND, 0x88, 0x00, nullptr); } + void ProgressState::update() { - static constexpr double SIZE_BAR_WIDTH = 656.0f; - sys::ProgressTask *task = static_cast(m_task.get()); const double current = task->get_progress(); // Base routine. BaseTask::update(); - m_progressBarWidth = std::ceil(SIZE_BAR_WIDTH * current); - m_progress = std::ceil(current * 100); - m_percentageString = stringutil::get_formatted_string("%u", m_progress); - m_percentageX = 640 - (sdl::text::get_width(18, m_percentageString.c_str())); + m_progressBarWidth = std::round(SIZE_BAR_WIDTH * current); + m_progress = std::round(current * 100); + m_percentageString = stringutil::get_formatted_string("%u%%", m_progress); + const int percentageWidth = sdl::text::get_width(18, m_percentageString.c_str()); + m_percentageX = COORD_DISPLAY_CENTER - percentageWidth; } void ProgressState::render() { + const bool hasFocus = BaseState::has_focus(); + const int barWidth = static_cast(SIZE_BAR_WIDTH); const std::string status = m_task->get_status(); - const char *percentage = m_percentageString.c_str(); - sdl::render_rect_fill(NULL, 0, 0, 1280, 720, colors::DIM_BACKGROUND); + sdl::render_rect_fill(sdl::Texture::Null, 0, 0, 1280, 720, colors::DIM_BACKGROUND); + sm_dialog->render(sdl::Texture::Null, hasFocus); + sdl::text::render(sdl::Texture::Null, 312, 288, 18, 656, colors::WHITE, status); - ui::render_dialog_box(NULL, 280, 262, 720, 256); - sdl::text::render(NULL, 312, 288, 18, 648, colors::WHITE, status.c_str()); - sdl::render_rect_fill(NULL, 312, 462, 656, 32, colors::BLACK); - sdl::render_rect_fill(NULL, 312, 462, m_progressBarWidth, 32, colors::GREEN); - sdl::text::render(NULL, m_percentageX, 468, 18, sdl::text::NO_TEXT_WRAP, colors::WHITE, "%s%%", percentage); + sdl::render_rect_fill(sdl::Texture::Null, COORD_BAR_X, COORD_BAR_Y, barWidth, 32, colors::BLACK); + sdl::render_rect_fill(sdl::Texture::Null, COORD_BAR_X, COORD_BAR_Y, m_progressBarWidth, 32, colors::GREEN); + sdl::text::render(sdl::Texture::Null, + m_percentageX, + COORD_TEXT_Y, + SIZE_FONT_SIZE, + sdl::text::NO_WRAP, + colors::WHITE, + m_percentageString); BaseTask::render_loading_glyph(); } + +void ProgressState::initialize_static_members() +{ + if (sm_dialog) { return; } + + sm_dialog = ui::DialogBox::create(280, 262, 720, 256); +} diff --git a/source/appstates/SaveCreateState.cpp b/source/appstates/SaveCreateState.cpp index 49eb0f7..f781a71 100644 --- a/source/appstates/SaveCreateState.cpp +++ b/source/appstates/SaveCreateState.cpp @@ -22,15 +22,21 @@ static bool compare_info(data::TitleInfo *infoA, data::TitleInfo *infoB); SaveCreateState::SaveCreateState(data::User *user, TitleSelectCommon *titleSelect) - : m_user{user} - , m_titleSelect{titleSelect} - , m_saveMenu{8, 8, 624, 22, 720} + : m_user(user) + , m_titleSelect(titleSelect) + , m_saveMenu(ui::Menu::create(8, 8, 624, 22, 720)) { SaveCreateState::initialize_static_members(); SaveCreateState::initialize_title_info_vector(); SaveCreateState::initialize_menu(); } +SaveCreateState::~SaveCreateState() +{ + sm_slidePanel->clear_elements(); + sm_slidePanel->reset(); +} + std::shared_ptr SaveCreateState::create(data::User *user, TitleSelectCommon *titleSelect) { return std::make_shared(user, titleSelect); @@ -47,7 +53,6 @@ void SaveCreateState::update() { const bool hasFocus = BaseState::has_focus(); - m_saveMenu.update(hasFocus); sm_slidePanel->update(hasFocus); const bool aPressed = input::button_pressed(HidNpadButton_A); @@ -63,11 +68,7 @@ void SaveCreateState::update() if (aPressed) { SaveCreateState::create_save_data_for(); } else if (bPressed) { sm_slidePanel->close(); } - else if (panelClosed) - { - sm_slidePanel->reset(); - BaseState::deactivate(); - } + else if (panelClosed) { BaseState::deactivate(); } } void SaveCreateState::render() @@ -76,8 +77,7 @@ void SaveCreateState::render() // Clear slide target, render menu, render slide to frame buffer. sm_slidePanel->clear_target(); - m_saveMenu.render(sm_slidePanel->get_target(), hasFocus); - sm_slidePanel->render(NULL, hasFocus); + sm_slidePanel->render(sdl::Texture::Null, hasFocus); } void SaveCreateState::refresh_required() { m_refreshRequired.store(true); } @@ -100,13 +100,14 @@ void SaveCreateState::initialize_menu() for (data::TitleInfo *titleInfo : m_titleInfoVector) { const std::string_view title = titleInfo->get_title(); - m_saveMenu.add_option(title); + m_saveMenu->add_option(title); } + sm_slidePanel->push_new_element(m_saveMenu); } void SaveCreateState::create_save_data_for() { - const int selected = m_saveMenu.get_selected(); + const int selected = m_saveMenu->get_selected(); data::TitleInfo *titleInfo = m_titleInfoVector[selected]; auto createTask = TaskState::create(tasks::savecreate::create_save_data_for, m_user, titleInfo, this); diff --git a/source/appstates/SettingsState.cpp b/source/appstates/SettingsState.cpp index 81094e6..e73a35e 100644 --- a/source/appstates/SettingsState.cpp +++ b/source/appstates/SettingsState.cpp @@ -1,5 +1,6 @@ #include "appstates/SettingsState.hpp" +#include "appstates/BlacklistEditState.hpp" #include "appstates/MainMenuState.hpp" #include "colors.hpp" #include "config.hpp" @@ -20,6 +21,16 @@ namespace constexpr std::string_view CONFIG_KEY_NULL = "NULL"; + enum + { + CHANGE_WORK_DIR = 0, + EDIT_BLACKLIST = 1, + CYCLE_ZIP = 14, + CYCLE_SORT_TYPE = 15, + TOGGLE_JKSM = 16, + CYCLE_SCALING = 19 + }; + // This is needed to be able to get and set keys by index. Anything "NULL" isn't a key that can be easily toggled. constexpr std::array CONFIG_KEY_ARRAY = {CONFIG_KEY_NULL, CONFIG_KEY_NULL, @@ -44,13 +55,10 @@ namespace } // namespace SettingsState::SettingsState() - : m_settingsMenu{32, 8, 1000, 24, 555} - , m_controlGuide{strings::get_by_name(strings::names::CONTROL_GUIDES, 3)} - , m_controlGuideX{static_cast(1220 - sdl::text::get_width(22, m_controlGuide))} - , m_renderTarget{sdl::TextureManager::create_load_texture(SECONDARY_TARGET, - 1080, - 555, - SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET)} + : m_settingsMenu(32, 8, 1000, 24, 555) + , m_controlGuide(strings::get_by_name(strings::names::CONTROL_GUIDES, 3)) + , m_controlGuideX(1220 - sdl::text::get_width(22, m_controlGuide)) + , m_renderTarget(sdl::TextureManager::create_load_texture(SECONDARY_TARGET, 1080, 555, SDL_TEXTUREACCESS_TARGET)) { SettingsState::load_settings_menu(); SettingsState::load_extra_strings(); @@ -75,10 +83,13 @@ void SettingsState::render() const bool hasFocus = BaseState::has_focus(); m_renderTarget->clear(colors::TRANSPARENT); - m_settingsMenu.render(m_renderTarget->get(), hasFocus); - m_renderTarget->render(NULL, 201, 91); + m_settingsMenu.render(m_renderTarget, hasFocus); + m_renderTarget->render(sdl::Texture::Null, 201, 91); - if (hasFocus) { sdl::text::render(NULL, m_controlGuideX, 673, 22, sdl::text::NO_TEXT_WRAP, colors::WHITE, m_controlGuide); } + if (hasFocus) + { + sdl::text::render(sdl::Texture::Null, m_controlGuideX, 673, 22, sdl::text::NO_WRAP, colors::WHITE, m_controlGuide); + } } void SettingsState::load_settings_menu() @@ -132,16 +143,34 @@ void SettingsState::update_menu_options() } } +void SettingsState::change_working_directory() {} + +void SettingsState::create_push_blacklist_edit() +{ + const bool isEmpty = config::blacklist_is_empty(); + if (isEmpty) + { + const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; + const char *popEmpty = strings::get_by_name(strings::names::SETTINGS_POPS, 0); + ui::PopMessageManager::push_message(popTicks, popEmpty); + return; + } + + BlacklistEditState::create_and_push(); +} + void SettingsState::toggle_options() { const int selected = m_settingsMenu.get_selected(); switch (selected) { - case 14: SettingsState::cycle_zip_level(); break; - case 15: SettingsState::cycle_sort_type(); break; - case 16: SettingsState::toggle_jksm_mode(); break; - case 19: SettingsState::cycle_anim_scaling(); break; - default: config::toggle_by_key(CONFIG_KEY_ARRAY[selected]); + case CHANGE_WORK_DIR: SettingsState::change_working_directory(); break; + case EDIT_BLACKLIST: SettingsState::create_push_blacklist_edit(); break; + case CYCLE_ZIP: SettingsState::cycle_zip_level(); break; + case CYCLE_SORT_TYPE: SettingsState::cycle_sort_type(); break; + case TOGGLE_JKSM: SettingsState::toggle_jksm_mode(); break; + case CYCLE_SCALING: SettingsState::cycle_anim_scaling(); break; + default: config::toggle_by_key(CONFIG_KEY_ARRAY[selected]); break; } config::save(); SettingsState::update_menu_options(); diff --git a/source/appstates/TaskState.cpp b/source/appstates/TaskState.cpp index eb78840..ff1b982 100644 --- a/source/appstates/TaskState.cpp +++ b/source/appstates/TaskState.cpp @@ -1,11 +1,14 @@ #include "appstates/TaskState.hpp" +#include "appstates/FadeState.hpp" #include "colors.hpp" #include "input.hpp" #include "sdl.hpp" #include "strings.hpp" #include "ui/PopMessageManager.hpp" +TaskState::~TaskState() { FadeState::create_and_push(colors::DIM_BACKGROUND, 0x88, 0x00, nullptr); } + void TaskState::update() { BaseTask::update(); } void TaskState::render() @@ -13,8 +16,8 @@ void TaskState::render() const std::string status = m_task->get_status(); const int statusX = 640 - (sdl::text::get_width(24, status.c_str()) / 2); - sdl::render_rect_fill(NULL, 0, 0, 1280, 720, colors::DIM_BACKGROUND); - sdl::text::render(NULL, statusX, 351, 24, sdl::text::NO_TEXT_WRAP, colors::WHITE, status.c_str()); + sdl::render_rect_fill(sdl::Texture::Null, 0, 0, 1280, 720, colors::DIM_BACKGROUND); + sdl::text::render(sdl::Texture::Null, statusX, 351, 24, sdl::text::NO_WRAP, colors::WHITE, status); BaseTask::render_loading_glyph(); } diff --git a/source/appstates/TextTitleSelectState.cpp b/source/appstates/TextTitleSelectState.cpp index 1c46954..fc706d6 100644 --- a/source/appstates/TextTitleSelectState.cpp +++ b/source/appstates/TextTitleSelectState.cpp @@ -21,13 +21,10 @@ namespace } // namespace TextTitleSelectState::TextTitleSelectState(data::User *user) - : TitleSelectCommon{} - , m_user{user} - , m_titleSelectMenu{32, 8, 1000, 20, 555} - , m_renderTarget{sdl::TextureManager::create_load_texture(SECONDARY_TARGET, - 1080, - 555, - SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET)} + : TitleSelectCommon() + , m_user(user) + , m_titleSelectMenu(32, 8, 1000, 20, 555) + , m_renderTarget(sdl::TextureManager::create_load_texture(SECONDARY_TARGET, 1080, 555, SDL_TEXTUREACCESS_TARGET)) { TextTitleSelectState::refresh(); } @@ -63,9 +60,9 @@ void TextTitleSelectState::update() void TextTitleSelectState::render() { m_renderTarget->clear(colors::TRANSPARENT); - m_titleSelectMenu.render(m_renderTarget->get(), BaseState::has_focus()); + m_titleSelectMenu.render(m_renderTarget, BaseState::has_focus()); TitleSelectCommon::render_control_guide(); - m_renderTarget->render(NULL, 201, 91); + m_renderTarget->render(sdl::Texture::Null, 201, 91); } void TextTitleSelectState::refresh() @@ -121,5 +118,14 @@ void TextTitleSelectState::add_remove_favorite() data::get_users(list); for (data::User *user : list) { user->sort_data(); } + const int count = m_user->get_total_data_entries(); + int i{}; + for (i = 0; i < count; i++) + { + const uint64_t appIDAt = m_user->get_application_id_at(i); + if (appIDAt == applicationID) { break; } + } + m_titleSelectMenu.set_selected(i); + MainMenuState::refresh_view_states(); } diff --git a/source/appstates/TitleInfoState.cpp b/source/appstates/TitleInfoState.cpp index 58033e2..5e738eb 100644 --- a/source/appstates/TitleInfoState.cpp +++ b/source/appstates/TitleInfoState.cpp @@ -26,9 +26,9 @@ namespace } // namespace TitleInfoState::TitleInfoState(data::User *user, data::TitleInfo *titleInfo) - : m_user{user} - , m_titleInfo{titleInfo} - , m_icon{m_titleInfo->get_icon()} + : m_user(user) + , m_titleInfo(titleInfo) + , m_icon(m_titleInfo->get_icon()) { TitleInfoState::initialize_static_members(); TitleInfoState::create_info_scrolls(); @@ -72,11 +72,11 @@ void TitleInfoState::render() { const bool hasFocus = BaseState::has_focus(); sm_slidePanel->clear_target(); - SDL_Texture *panelTarget = sm_slidePanel->get_target(); + sdl::SharedTexture &panelTarget = sm_slidePanel->get_target(); m_icon->render_stretched(panelTarget, 88, 8, 304, 304); - sm_slidePanel->render(NULL, hasFocus); + sm_slidePanel->render(sdl::Texture::Null, hasFocus); } void TitleInfoState::initialize_static_members() diff --git a/source/appstates/TitleOptionState.cpp b/source/appstates/TitleOptionState.cpp index 83c840a..a5dc0b2 100644 --- a/source/appstates/TitleOptionState.cpp +++ b/source/appstates/TitleOptionState.cpp @@ -43,15 +43,21 @@ namespace } // namespace TitleOptionState::TitleOptionState(data::User *user, data::TitleInfo *titleInfo, TitleSelectCommon *titleSelect) - : m_user{user} - , m_titleInfo{titleInfo} - , m_titleSelect{titleSelect} - , m_dataStruct{std::make_shared()} + : m_user(user) + , m_titleInfo(titleInfo) + , m_titleSelect(titleSelect) + , m_dataStruct(std::make_shared()) { TitleOptionState::initialize_static_members(); TitleOptionState::initialize_data_struct(); } +TitleOptionState::~TitleOptionState() +{ + sm_slidePanel->reset(); + sm_titleOptionMenu->set_selected(0); +} + std::shared_ptr TitleOptionState::create(data::User *user, data::TitleInfo *titleInfo, TitleSelectCommon *titleSelect) @@ -71,6 +77,11 @@ std::shared_ptr TitleOptionState::create_and_push(data::User * void TitleOptionState::update() { const bool hasFocus = BaseState::has_focus(); + + sm_slidePanel->update(hasFocus); + const bool isOpen = sm_slidePanel->is_open(); + if (!isOpen) { return; } + const bool aPressed = input::button_pressed(HidNpadButton_A); const bool bPressed = input::button_pressed(HidNpadButton_B); const int selected = sm_titleOptionMenu->get_selected(); @@ -86,7 +97,6 @@ void TitleOptionState::update() } if (m_exitRequired) { sm_slidePanel->close(); } - sm_slidePanel->update(hasFocus); if (aPressed) { switch (selected) @@ -104,14 +114,7 @@ void TitleOptionState::update() } } else if (bPressed) { sm_slidePanel->close(); } - else if (sm_slidePanel->is_closed()) - { - // Reset static members. - sm_slidePanel->reset(); - sm_titleOptionMenu->set_selected(0); - // Deactivate and allow state to be purged. - BaseState::deactivate(); - } + else if (sm_slidePanel->is_closed()) { BaseState::deactivate(); } } void TitleOptionState::render() @@ -119,7 +122,7 @@ void TitleOptionState::render() const bool hasFocus = BaseState::has_focus(); sm_slidePanel->clear_target(); - sm_slidePanel->render(NULL, hasFocus); + sm_slidePanel->render(sdl::Texture::Null, hasFocus); } void TitleOptionState::close_on_update() { m_exitRequired = true; } @@ -207,7 +210,7 @@ void TitleOptionState::change_output_directory() } const uint64_t applicationID = m_titleInfo->get_application_id(); - m_titleInfo->set_path_safe_title(pathBuffer.data(), SIZE_PATH_BUFFER); + m_titleInfo->set_path_safe_title(pathBuffer.data()); config::add_custom_path(applicationID, pathBuffer.data()); const char *popSuccessFormat = strings::get_by_name(strings::names::TITLEOPTION_POPS, 8); diff --git a/source/appstates/TitleSelectCommon.cpp b/source/appstates/TitleSelectCommon.cpp index 1493c55..6b928f4 100644 --- a/source/appstates/TitleSelectCommon.cpp +++ b/source/appstates/TitleSelectCommon.cpp @@ -18,6 +18,6 @@ void TitleSelectCommon::render_control_guide() if (hasFocus) { - sdl::text::render(NULL, sm_controlGuideX, 673, 22, sdl::text::NO_TEXT_WRAP, colors::WHITE, sm_controlGuide); + sdl::text::render(sdl::Texture::Null, sm_controlGuideX, 673, 22, sdl::text::NO_WRAP, colors::WHITE, sm_controlGuide); } } diff --git a/source/appstates/TitleSelectState.cpp b/source/appstates/TitleSelectState.cpp index 3b5bf08..5aa1cb0 100644 --- a/source/appstates/TitleSelectState.cpp +++ b/source/appstates/TitleSelectState.cpp @@ -24,10 +24,7 @@ namespace TitleSelectState::TitleSelectState(data::User *user) : TitleSelectCommon() , m_user(user) - , m_renderTarget(sdl::TextureManager::create_load_texture(SECONDARY_TARGET, - 1080, - 555, - SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET)) + , m_renderTarget(sdl::TextureManager::create_load_texture(SECONDARY_TARGET, 1080, 555, SDL_TEXTUREACCESS_TARGET)) , m_titleView(m_user) {}; std::shared_ptr TitleSelectState::create(data::User *user) @@ -65,9 +62,9 @@ void TitleSelectState::render() const bool hasFocus = BaseState::has_focus(); m_renderTarget->clear(colors::TRANSPARENT); - m_titleView.render(m_renderTarget->get(), hasFocus); + m_titleView.render(m_renderTarget, hasFocus); TitleSelectCommon::render_control_guide(); - m_renderTarget->render(NULL, 201, 91); + m_renderTarget->render(sdl::Texture::Null, 201, 91); } void TitleSelectState::refresh() { m_titleView.refresh(); } @@ -122,5 +119,15 @@ void TitleSelectState::add_remove_favorite() data::get_users(userList); for (data::User *user : userList) { user->sort_data(); } + // This is dirty, but it's the only way to pull it off without rewriting tons of code. + const int count = m_user->get_total_data_entries(); + int i{}; + for (i = 0; i < count; i++) + { + const uint64_t appIDAt = m_user->get_application_id_at(i); + if (appIDAt == applicationID) { break; } + } + m_titleView.set_selected(i); + MainMenuState::refresh_view_states(); } diff --git a/source/appstates/UserOptionState.cpp b/source/appstates/UserOptionState.cpp index 474cfc8..cba090a 100644 --- a/source/appstates/UserOptionState.cpp +++ b/source/appstates/UserOptionState.cpp @@ -37,10 +37,10 @@ namespace } // namespace UserOptionState::UserOptionState(data::User *user, TitleSelectCommon *titleSelect) - : m_user{user} - , m_titleSelect{titleSelect} - , m_userOptionMenu{8, 8, 460, 22, 720} - , m_dataStruct{std::make_shared()} + : m_user(user) + , m_titleSelect(titleSelect) + , m_userOptionMenu(8, 8, 460, 22, 720) + , m_dataStruct(std::make_shared()) { UserOptionState::create_menu_panel(); UserOptionState::load_menu_strings(); @@ -62,11 +62,14 @@ std::shared_ptr UserOptionState::create_and_push(data::User *us void UserOptionState::update() { const bool hasFocus = BaseState::has_focus(); + sm_menuPanel->update(hasFocus); + + const bool isOpen = sm_menuPanel->is_open(); + if (!isOpen) { return; } + const bool aPressed = input::button_pressed(HidNpadButton_A); const bool bPressed = input::button_pressed(HidNpadButton_B); - sm_menuPanel->update(hasFocus); - // See if this needs to be done. if (m_refreshRequired) { @@ -77,7 +80,9 @@ void UserOptionState::update() if (aPressed) { - switch (m_userOptionMenu.get_selected()) + const int selected = m_userOptionMenu.get_selected(); + + switch (selected) { case BACKUP_ALL: UserOptionState::backup_all(); break; case CREATE_SAVE: UserOptionState::create_save_create(); break; @@ -99,11 +104,12 @@ void UserOptionState::render() { // Render target user's title selection screen. m_titleSelect->render(); + sdl::SharedTexture &panelTarget = sm_menuPanel->get_target(); // Render panel. sm_menuPanel->clear_target(); - m_userOptionMenu.render(sm_menuPanel->get_target(), BaseState::has_focus()); - sm_menuPanel->render(NULL, BaseState::has_focus()); + m_userOptionMenu.render(panelTarget, BaseState::has_focus()); + sm_menuPanel->render(sdl::Texture::Null, BaseState::has_focus()); } void UserOptionState::refresh_required() { m_refreshRequired = true; } diff --git a/source/config.cpp b/source/config.cpp index 525aa92..de36782 100644 --- a/source/config.cpp +++ b/source/config.cpp @@ -211,6 +211,8 @@ void config::add_remove_favorite(uint64_t applicationID) auto findTitle = std::find(s_favorites.begin(), s_favorites.end(), applicationID); if (findTitle == s_favorites.end()) { s_favorites.push_back(applicationID); } else { s_favorites.erase(findTitle); } + + config::save(); } bool config::is_favorite(uint64_t applicationID) @@ -223,6 +225,14 @@ void config::add_remove_blacklist(uint64_t applicationID) auto findTitle = std::find(s_blacklist.begin(), s_blacklist.end(), applicationID); if (findTitle == s_blacklist.end()) { s_blacklist.push_back(applicationID); } else { s_blacklist.erase(findTitle); } + + config::save(); +} + +void config::get_blacklisted_titles(std::vector &listOut) +{ + listOut.clear(); + listOut.assign(s_blacklist.begin(), s_blacklist.end()); } bool config::is_blacklisted(uint64_t applicationID) @@ -230,6 +240,8 @@ bool config::is_blacklisted(uint64_t applicationID) return std::find(s_blacklist.begin(), s_blacklist.end(), applicationID) != s_blacklist.end(); } +bool config::blacklist_is_empty() { return s_blacklist.size() <= 0; } + void config::add_custom_path(uint64_t applicationID, std::string_view customPath) { s_pathMap[applicationID] = customPath.data(); diff --git a/source/data/TitleInfo.cpp b/source/data/TitleInfo.cpp index 2d09279..ae8cda0 100644 --- a/source/data/TitleInfo.cpp +++ b/source/data/TitleInfo.cpp @@ -44,7 +44,7 @@ data::TitleInfo::TitleInfo(uint64_t applicationID) m_hasData = true; TitleInfo::get_create_path_safe_title(); - m_icon = sdl::TextureManager::create_load_texture(entry->name, m_data->icon, iconSize); + m_icon = sdl::TextureManager::create_load_texture(entry->name, data->icon, iconSize); } } @@ -183,11 +183,13 @@ bool data::TitleInfo::has_save_data_type(uint8_t saveType) const sdl::SharedTexture data::TitleInfo::get_icon() const { return m_icon; } -void data::TitleInfo::set_path_safe_title(const char *newPathSafe, size_t newPathLength) +void data::TitleInfo::set_path_safe_title(const char *newPathSafe) { - if (newPathLength >= TitleInfo::SIZE_PATH_SAFE) { return; } + const int length = std::char_traits::length(newPathSafe); + if (length >= TitleInfo::SIZE_PATH_SAFE) { return; } + std::memset(m_pathSafeTitle, 0x00, TitleInfo::SIZE_PATH_SAFE); - std::memcpy(m_pathSafeTitle, newPathSafe, newPathLength); + std::memcpy(m_pathSafeTitle, newPathSafe, length); } void data::TitleInfo::get_create_path_safe_title() diff --git a/source/data/User.cpp b/source/data/User.cpp index 8f90ddc..0cf0c21 100644 --- a/source/data/User.cpp +++ b/source/data/User.cpp @@ -4,7 +4,7 @@ #include "config.hpp" #include "data/data.hpp" #include "error.hpp" -#include "fs/save_mount.hpp" +#include "fs/fs.hpp" #include "gfxutil.hpp" #include "logger.hpp" #include "sdl.hpp" @@ -182,10 +182,14 @@ void data::User::load_user_data() const bool isBlacklisted = config::is_blacklisted(applicationID); const bool systemFilter = (!accountSys && isAccountUser && isSystemSave); - const bool mounted = !isBlacklisted && !systemFilter && enforceMount && - fslib::open_save_data_with_save_info(fs::DEFAULT_SAVE_MOUNT, saveInfo); + + bool mounted{}; + if (!isBlacklisted && !systemFilter && enforceMount) + { + fs::ScopedSaveMount saveMount{fs::DEFAULT_SAVE_MOUNT, &saveInfo, false}; + mounted = saveMount.is_open(); + } if (isBlacklisted || systemFilter || (enforceMount && !mounted)) { continue; } - if (mounted) { fslib::close_file_system(fs::DEFAULT_SAVE_MOUNT); } const bool titleFound = data::title_exists_in_map(applicationID); if (!titleFound) { data::load_title_to_map(applicationID); } diff --git a/source/data/data.cpp b/source/data/data.cpp index c58826b..13c26ed 100644 --- a/source/data/data.cpp +++ b/source/data/data.cpp @@ -9,16 +9,15 @@ #include #include +#include #include #include +#include #include #include namespace { - // This is easer to read imo - using UserIDPair = std::pair; - /// @brief Struct used for reading the cache from file. // clang-format off typedef struct @@ -28,11 +27,10 @@ namespace } CacheEntry; // clang-format on - // User vector to preserve order. - std::vector s_userVector; + std::vector s_users{}; // Map of Title info paired with its title/application - std::unordered_map s_titleInfoMap; + std::unordered_map s_titleinfo; /// @brief Path used for cacheing title information since NS got slow on 20.0+ constexpr std::string_view PATH_CACHE_PATH = "sdmc:/config/JKSV/cache.bin"; @@ -68,54 +66,50 @@ bool data::initialize(bool clearCache) const bool cacheClearFailed = clearCache && cacheExists && error::fslib(fslib::delete_file(cachePath)); if (clearCache && cacheClearFailed) { return false; } - const bool needsUsers = s_userVector.empty(); - const bool usersLoaded = needsUsers && load_create_user_accounts(); - if (needsUsers && !usersLoaded) { return false; } + const bool usersLoaded = s_users.empty() && load_create_user_accounts(); + if (!usersLoaded && s_users.empty()) { return false; } - const bool cacheRead = read_cache_file(); - if (!cacheRead) + if (!read_cache_file()) { - s_titleInfoMap.clear(); + s_titleinfo.clear(); load_application_records(); import_svi_files(); } - for (auto &[accountID, user] : s_userVector) { user.load_user_data(); } + for (data::User &user : s_users) { user.load_user_data(); } - const bool needsCacheBuild = !fslib::file_exists(cachePath); - if (needsCacheBuild) { create_cache_file(); } + const bool needsCache = !fslib::file_exists(cachePath); + if (needsCache) { create_cache_file(); } return true; } void data::get_users(data::UserList &userList) { - userList.clear(); - for (auto &[accountID, userData] : s_userVector) { userList.push_back(&userData); } + for (data::User &user : s_users) { userList.push_back(&user); } } data::TitleInfo *data::get_title_info_by_id(uint64_t applicationID) { - auto findTitle = s_titleInfoMap.find(applicationID); - if (findTitle == s_titleInfoMap.end()) { return nullptr; } + auto findTitle = s_titleinfo.find(applicationID); + if (findTitle == s_titleinfo.end()) { return nullptr; } return &findTitle->second; } -void data::load_title_to_map(uint64_t applicationID) { s_titleInfoMap.emplace(applicationID, applicationID); } +void data::load_title_to_map(uint64_t applicationID) { s_titleinfo.emplace(applicationID, applicationID); } -bool data::title_exists_in_map(uint64_t applicationID) { return s_titleInfoMap.find(applicationID) != s_titleInfoMap.end(); } +bool data::title_exists_in_map(uint64_t applicationID) { return s_titleinfo.find(applicationID) != s_titleinfo.end(); } -std::unordered_map &data::get_title_info_map() { return s_titleInfoMap; } - -void data::get_title_info_by_type(FsSaveDataType saveType, std::vector &vectorOut) +void data::get_title_info_list(data::TitleInfoList &listOut) { - // Clear vector JIC - vectorOut.clear(); + for (auto &[applicationID, titleInfo] : s_titleinfo) { listOut.push_back(&titleInfo); } +} - // Loop and push pointers - for (auto &[applicationID, titleInfo] : s_titleInfoMap) +void data::get_title_info_by_type(FsSaveDataType saveType, data::TitleInfoList &listOut) +{ + for (auto &[applicationID, titleInfo] : s_titleinfo) { - if (titleInfo.has_save_data_type(saveType)) { vectorOut.push_back(&titleInfo); } + if (titleInfo.has_save_data_type(saveType)) { listOut.push_back(&titleInfo); } } } @@ -133,21 +127,11 @@ static bool load_create_user_accounts() if (accountError || noAccounts) { return false; } // Loop and load the account data. - for (int i = 0; i < total; i++) - { - auto userPair = std::make_pair(accounts[i], std::move(data::User(accounts[i], FsSaveDataType_Account))); - s_userVector.push_back(std::move(userPair)); - } - - // Create and push the system type users. Path safe names are hard coded to English for these. - auto devicePair = std::make_pair(ID_DEVICE_USER, data::User(ID_DEVICE_USER, deviceName, "Device", FsSaveDataType_Device)); - auto bcatPair = std::make_pair(ID_BCAT_USER, data::User(ID_BCAT_USER, bcatName, "BCAT", FsSaveDataType_Bcat)); - auto cachePair = std::make_pair(ID_CACHE_USER, data::User(ID_CACHE_USER, cacheName, "Cache", FsSaveDataType_Cache)); - auto systemPair = std::make_pair(ID_SYSTEM_USER, data::User(ID_SYSTEM_USER, systemName, "System", FsSaveDataType_System)); - s_userVector.push_back(std::move(devicePair)); - s_userVector.push_back(std::move(bcatPair)); - s_userVector.push_back(std::move(cachePair)); - s_userVector.push_back(std::move(systemPair)); + for (int i = 0; i < total; i++) { s_users.emplace_back(accounts[i], FsSaveDataType_Account); } + s_users.emplace_back(ID_DEVICE_USER, deviceName, "Device", FsSaveDataType_Device); + s_users.emplace_back(ID_BCAT_USER, bcatName, "BCAT", FsSaveDataType_Bcat); + s_users.emplace_back(ID_CACHE_USER, cacheName, "Cache", FsSaveDataType_Cache); + s_users.emplace_back(ID_SYSTEM_USER, systemName, "System", FsSaveDataType_System); return true; } @@ -162,7 +146,7 @@ static void load_application_records() do { listError = error::libnx(nsListApplicationRecord(&record, 1, offset++, &count)) || count <= 0; if (listError) { break; } - s_titleInfoMap.emplace(record.application_id, record.application_id); + s_titleinfo.emplace(record.application_id, record.application_id); } while (!listError); } @@ -192,7 +176,7 @@ static void import_svi_files() if (!idReadGood || !dataReadGood) { continue; } data::TitleInfo newInfo{applicationID, controlData}; - s_titleInfoMap.emplace(applicationID, std::move(newInfo)); + s_titleinfo.emplace(applicationID, std::move(newInfo)); } } @@ -209,8 +193,8 @@ static bool read_cache_file() if (!countRead) { return false; } auto entryBuffer = std::make_unique(titleCount); // I've read there might not be any point in error checking. - const bool cacheRead = - cache.read(entryBuffer.get(), SIZE_CACHE_ENTRY * titleCount) == static_cast(SIZE_CACHE_ENTRY * titleCount); + const int64_t cacheSize = SIZE_CACHE_ENTRY * titleCount; + const bool cacheRead = cache.read(entryBuffer.get(), cacheSize) == cacheSize; if (!cacheRead) { return false; } // Loop through the cache entries and emplace them to the map. @@ -219,7 +203,7 @@ static bool read_cache_file() CacheEntry &entry = entryBuffer[i]; data::TitleInfo newInfo{entry.applicationID, entry.data}; - s_titleInfoMap.emplace(entry.applicationID, std::move(newInfo)); + s_titleinfo.emplace(entry.applicationID, std::move(newInfo)); } return true; } @@ -238,7 +222,7 @@ static void create_cache_file() const bool countWrite = cache.write(&titleCount, SIZE_UNSIGNED) == SIZE_UNSIGNED; if (!countWrite) { return; } - for (auto &[applicationID, titleInfo] : s_titleInfoMap) + for (auto &[applicationID, titleInfo] : s_titleinfo) { if (!titleInfo.has_control_data()) { continue; } diff --git a/source/error.cpp b/source/error.cpp index 748195f..1442c2f 100644 --- a/source/error.cpp +++ b/source/error.cpp @@ -44,7 +44,7 @@ bool error::is_null(const void *pointer, const std::source_location &location) std::string_view file{}, function{}; prep_locations(file, function, location); - logger::log("%s::%s::%u::%u::%s", file.data(), function.data(), location.line(), location.column(), "nullptr received!"); + logger::log("%s::%s::%u::%u::nullptr!", file.data(), function.data(), location.line(), location.column()); return true; } diff --git a/source/fs/ScopedSaveMount.cpp b/source/fs/ScopedSaveMount.cpp index d3f0c53..7bb6cd5 100644 --- a/source/fs/ScopedSaveMount.cpp +++ b/source/fs/ScopedSaveMount.cpp @@ -3,11 +3,12 @@ #include "error.hpp" #include "fslib.hpp" -fs::ScopedSaveMount::ScopedSaveMount(std::string_view mount, const FsSaveDataInfo *saveInfo) +fs::ScopedSaveMount::ScopedSaveMount(std::string_view mount, const FsSaveDataInfo *saveInfo, bool log) : m_mountPoint(mount) + , m_log(log) { - const bool mountError = error::fslib(fslib::open_save_data_with_save_info(m_mountPoint, *saveInfo)); - m_isOpen = !mountError; + if (m_log) { m_isOpen = !error::fslib(fslib::open_save_data_with_save_info(m_mountPoint, *saveInfo)); } + else { m_isOpen = fslib::open_save_data_with_save_info(m_mountPoint, *saveInfo); } } fs::ScopedSaveMount::ScopedSaveMount(ScopedSaveMount &&scopedSaveMount) { *this = std::move(scopedSaveMount); } @@ -20,6 +21,10 @@ fs::ScopedSaveMount &fs::ScopedSaveMount::operator=(ScopedSaveMount &&scopedSave return *this; } -fs::ScopedSaveMount::~ScopedSaveMount() { error::fslib(fslib::close_file_system(m_mountPoint)); } +fs::ScopedSaveMount::~ScopedSaveMount() +{ + if (m_log) { error::fslib(fslib::close_file_system(m_mountPoint)); } + else { fslib::close_file_system(m_mountPoint); } +} bool fs::ScopedSaveMount::is_open() const { return m_isOpen; } diff --git a/source/gfxutil.cpp b/source/gfxutil.cpp index af25703..7ab0ad4 100644 --- a/source/gfxutil.cpp +++ b/source/gfxutil.cpp @@ -15,15 +15,14 @@ sdl::SharedTexture gfxutil::create_generic_icon(std::string_view text, sdl::Color foreground) { // Create base icon texture. - sdl::SharedTexture icon = - sdl::TextureManager::create_load_texture(text, 256, 256, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); + sdl::SharedTexture icon = sdl::TextureManager::create_load_texture(text, 256, 256, SDL_TEXTUREACCESS_TARGET); // Get the centered X and Y coordinates. - const int textX = (SIZE_ICON_WIDTH / 2) - (sdl::text::get_width(fontSize, text.data()) / 2); + const int textX = (SIZE_ICON_WIDTH / 2) - (sdl::text::get_width(fontSize, text) / 2); const int textY = (SIZE_ICON_HEIGHT / 2) - (fontSize / 2); icon->clear(background); - sdl::text::render(icon->get(), textX, textY, fontSize, sdl::text::NO_TEXT_WRAP, foreground, text.data()); + sdl::text::render(icon, textX, textY, fontSize, sdl::text::NO_WRAP, foreground, text); return icon; } diff --git a/source/logger.cpp b/source/logger.cpp index f57574c..5b6cf1f 100644 --- a/source/logger.cpp +++ b/source/logger.cpp @@ -3,6 +3,7 @@ #include "config.hpp" #include "fslib.hpp" +#include #include #include #include @@ -10,35 +11,42 @@ namespace { - /// @brief This is the path to the log file. - fslib::Path s_logFilePath{}; + constexpr const char *PATH_JKSV_LOG = "sdmc:/config/JKSV/JKSV.log"; /// @brief This is the buffer size for log strings. constexpr size_t VA_BUFFER_SIZE = 0x1000; + + constexpr int64_t SIZE_LOG_LIMIT = 0x10000; } // namespace void logger::initialize() { - // Create log path and empty the log for this run. - s_logFilePath = "sdmc:/config/JKSV/JKSV.log"; - - // Just opening it like this to nuke and restart. - fslib::File LogFile(s_logFilePath, FsOpenMode_Create | FsOpenMode_Write); + // Can't really log errors for the log before it exists? + const fslib::Path logPath{PATH_JKSV_LOG}; + const bool exists = fslib::file_exists(logPath); + if (!exists) { fslib::create_file(logPath); } } void logger::log(const char *format, ...) { static std::mutex logLock{}; - char vaBuffer[VA_BUFFER_SIZE] = {0}; - - std::va_list vaList; + std::array vaBuffer = {}; + std::va_list vaList{}; va_start(vaList, format); - vsnprintf(vaBuffer, VA_BUFFER_SIZE, format, vaList); + vsnprintf(vaBuffer.data(), VA_BUFFER_SIZE, format, vaList); va_end(vaList); std::lock_guard logGuard(logLock); - fslib::File logFile(s_logFilePath, FsOpenMode_Append); - logFile << vaBuffer << "\n"; + const fslib::Path logPath{PATH_JKSV_LOG}; + fslib::File logFile(logPath, FsOpenMode_Append); + if (logFile.is_open() && logFile.get_size() >= SIZE_LOG_LIMIT) + { + logFile.close(); + logFile.open(logPath, FsOpenMode_Create | FsOpenMode_Write); + } + + if (!logFile.is_open()) { return; } + logFile << vaBuffer.data() << "\n"; logFile.flush(); } diff --git a/source/remote/Storage.cpp b/source/remote/Storage.cpp index 29296dd..fbba859 100644 --- a/source/remote/Storage.cpp +++ b/source/remote/Storage.cpp @@ -25,19 +25,29 @@ remote::Item *remote::Storage::get_directory_by_name(std::string_view name) return &(*findDirectory); } -remote::Storage::DirectoryListing remote::Storage::get_directory_listing() +void remote::Storage::get_directory_listing(remote::Storage::DirectoryListing &listOut) { - remote::Storage::DirectoryListing listing{}; + listOut.clear(); auto current = m_list.begin(); - while ((current = std::find_if(current, - m_list.end(), - [&](const Item &item) { return item.get_parent_id() == this->m_parent; })) != m_list.end()) + while ((current = Storage::find_by_parent_id(current, m_parent)) != m_list.end()) { - listing.push_back(&(*current)); + listOut.push_back(&(*current)); + ++current; + } +} + +void remote::Storage::get_directory_listing_with_parent(const remote::Item *item, remote::Storage::DirectoryListing &listOut) +{ + listOut.clear(); + + const std::string_view parentId = item->get_id(); + auto current = m_list.begin(); + while ((current = Storage::find_by_parent_id(current, parentId)) != m_list.end()) + { + listOut.push_back(&(*current)); ++current; } - return listing; } bool remote::Storage::file_exists(std::string_view name) { return Storage::find_file_by_name(name) != m_list.end(); } @@ -55,16 +65,24 @@ std::string_view remote::Storage::get_prefix() const { return m_prefix; } remote::Storage::List::iterator remote::Storage::find_directory_by_name(std::string_view name) { - return std::find_if(m_list.begin(), - m_list.end(), - [&](const Item &item) - { return item.is_directory() && item.get_parent_id() == this->m_parent && item.get_name() == name; }); + auto is_match = [&](const Item &item) + { return item.is_directory() && item.get_parent_id() == m_parent && item.get_name() == name; }; + + return std::find_if(m_list.begin(), m_list.end(), is_match); } remote::Storage::List::iterator remote::Storage::find_file_by_name(std::string_view name) { - return std::find_if(m_list.begin(), - m_list.end(), - [&](const Item &item) - { return !item.is_directory() && item.get_parent_id() == this->m_parent && item.get_name() == name; }); + auto is_match = [&](const Item &item) + { return !item.is_directory() && item.get_parent_id() == m_parent && item.get_name() == name; }; + + return std::find_if(m_list.begin(), m_list.end(), is_match); +} + +remote::Storage::List::iterator remote::Storage::find_by_parent_id(remote::Storage::List::iterator start, + std::string_view parentID) +{ + auto is_match = [&](const Item &item) { return item.get_parent_id() == parentID; }; + + return std::find_if(start, m_list.end(), is_match); } diff --git a/source/remote/WebDav.cpp b/source/remote/WebDav.cpp index 8bb8bf9..38c2fb1 100644 --- a/source/remote/WebDav.cpp +++ b/source/remote/WebDav.cpp @@ -97,7 +97,8 @@ bool remote::WebDav::create_directory(std::string_view name) if (!curl::perform(m_curl)) { return false; } - if (curl::get_response_code(m_curl) != 201) + const long code = curl::get_response_code(m_curl); + if (code != 201) { logger::log(STRING_CREATE_DIR_ERROR, name.data()); return false; @@ -275,10 +276,18 @@ bool remote::WebDav::rename_item(remote::Item *item, std::string_view newName) if (!curl::perform(m_curl)) { return false; } const long code = curl::get_response_code(m_curl); - if (code != 403 || code != 409) { return false; } + if (code != 201 && code != 204) { return false; } std::string newId{}; - if (item->is_directory()) { newId = m_parent + escapedName + "/"; } + if (item->is_directory()) + { + newId = m_parent + escapedName + "/"; + + // Need to make sure the parents match too. + remote::Storage::DirectoryListing dirListing{}; + Storage::get_directory_listing_with_parent(item, dirListing); + for (remote::Item *item : dirListing) { item->set_parent_id(newId); } + } else { newId = m_parent + escapedName; } item->set_name(newName); diff --git a/source/system/Timer.cpp b/source/system/Timer.cpp index d7666b0..f23a776 100644 --- a/source/system/Timer.cpp +++ b/source/system/Timer.cpp @@ -15,7 +15,8 @@ void sys::Timer::start(uint64_t triggerTicks) bool sys::Timer::is_triggered() { const uint64_t currentTicks = SDL_GetTicks64(); - const bool triggered = (currentTicks - m_startingTicks) >= m_triggerTicks; + const bool started = m_startingTicks != 0 && m_triggerTicks != 0; + const bool triggered = started && (currentTicks - m_startingTicks) >= m_triggerTicks; if (!triggered) { return false; } m_startingTicks = currentTicks; diff --git a/source/tasks/backup.cpp b/source/tasks/backup.cpp index 2af9ac5..56eab46 100644 --- a/source/tasks/backup.cpp +++ b/source/tasks/backup.cpp @@ -51,6 +51,10 @@ void tasks::backup::create_new_backup_local(sys::ProgressTask *task, } else { + const bool needsDir = !fslib::directory_exists(target); + const bool createError = needsDir && error::fslib(fslib::create_directory(target)); + if (needsDir && createError) { TASK_FINISH_RETURN(task); } + write_meta_file(target, saveInfo); auto scopedMount = create_scoped_mount(saveInfo); fs::copy_directory(fs::DEFAULT_SAVE_ROOT, target, task); @@ -189,10 +193,7 @@ void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuStat const fslib::Path &target = taskData->path; BackupMenuState *spawningState = taskData->spawningState; remote::Storage *remote = remote::get_remote_storage(); - if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState) || error::is_null(remote)) - { - TASK_FINISH_RETURN(task); - } + if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } const uint64_t applicationID = titleInfo->get_application_id(); const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); @@ -209,7 +210,6 @@ void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuStat const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; if (autoBackup) { - fslib::Path autoTarget{}; const size_t lastSlash = target.find_last_of('/'); if (lastSlash == target.NOT_FOUND) { @@ -218,8 +218,10 @@ void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuStat TASK_FINISH_RETURN(task); } - const char *safeNickname = user->get_path_safe_nickname(); - autoTarget = target.sub_path(lastSlash) / "AUTO - " + safeNickname + " - " + stringutil::get_date_string(); + const char *safeNickname = user->get_path_safe_nickname(); + const std::string dateString = stringutil::get_date_string(); + const std::string autoName = stringutil::get_formatted_string("AUTO - %s - %s", safeNickname, dateString.c_str()); + fslib::Path autoTarget = target.sub_path(lastSlash) / autoName; if (exportZip) { autoTarget += ".zip"; }; tasks::backup::create_new_backup_local(task, user, titleInfo, autoTarget, spawningState, false); diff --git a/source/tasks/titleoptions.cpp b/source/tasks/titleoptions.cpp index b8a3b48..29f1e4e 100644 --- a/source/tasks/titleoptions.cpp +++ b/source/tasks/titleoptions.cpp @@ -88,7 +88,8 @@ void tasks::titleoptions::delete_all_remote_backups_for_title(sys::Task *task, T remote::Item *workDir = remote->get_directory_by_name(remoteTitle); remote->change_directory(workDir); - remote::Storage::DirectoryListing remoteListing = remote->get_directory_listing(); + remote::Storage::DirectoryListing remoteListing{}; + remote->get_directory_listing(remoteListing); { const char *statusFormat = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 0); diff --git a/source/tasks/useroptions.cpp b/source/tasks/useroptions.cpp index 78c49a3..efae071 100644 --- a/source/tasks/useroptions.cpp +++ b/source/tasks/useroptions.cpp @@ -102,16 +102,17 @@ void tasks::useroptions::create_all_save_data_for_user(sys::Task *task, UserOpti UserOptionState *spawningState = taskData->spawningState; if (error::is_null(user) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } - auto &titleInfoMap = data::get_title_info_map(); + data::TitleInfoList infoList{}; + data::get_title_info_list(infoList); const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; const char *statusFormat = strings::get_by_name(strings::names::USEROPTION_STATUS, 0); const char *popFailure = strings::get_by_name(strings::names::SAVECREATE_POPS, 1); const uint8_t saveType = user->get_account_save_type(); - for (auto &[applicationID, titleInfo] : titleInfoMap) + for (data::TitleInfo *titleInfo : infoList) { - const char *title = titleInfo.get_title(); - const bool hasSaveType = titleInfo.has_save_data_type(saveType); + const char *title = titleInfo->get_title(); + const bool hasSaveType = titleInfo->has_save_data_type(saveType); if (!hasSaveType) { continue; } { @@ -119,7 +120,7 @@ void tasks::useroptions::create_all_save_data_for_user(sys::Task *task, UserOpti task->set_status(status); } - const bool saveCreated = fs::create_save_data_for(user, &titleInfo); + const bool saveCreated = fs::create_save_data_for(user, titleInfo); if (!saveCreated) { const std::string popMessage = stringutil::get_formatted_string(popFailure, title); diff --git a/source/ui/BoundingBox.cpp b/source/ui/BoundingBox.cpp new file mode 100644 index 0000000..ea7bc2d --- /dev/null +++ b/source/ui/BoundingBox.cpp @@ -0,0 +1,70 @@ +#include "ui/BoundingBox.hpp" + +namespace +{ + constexpr int CORNER_WIDTH = 8; + constexpr int CORNER_HEIGHT = 8; + + constexpr int RECT_WIDTH = 4; + constexpr int RECT_HEIGHT = 4; +} + +ui::BoundingBox::BoundingBox(int x, int y, int width, int height) + : m_x(x) + , m_y(y) + , m_width(width) + , m_height(height) +{ + BoundingBox::initialize_static_members(); +} + +std::shared_ptr ui::BoundingBox::create(int x, int y, int width, int height) +{ + return std::make_shared(x, y, width, height); +} + +void ui::BoundingBox::update(bool hasFocus) { m_colorMod.update(); } + +void ui::BoundingBox::render(sdl::SharedTexture &target, bool hasFocus) +{ + sm_corners->set_color_mod(m_colorMod); + + const int rightX = (m_x + m_width) - CORNER_WIDTH; + const int rightRectX = (m_x + m_width) - RECT_WIDTH; + + const int midX = m_x + CORNER_WIDTH; + const int midY = m_y + CORNER_HEIGHT; + const int midWidth = m_width - (CORNER_WIDTH * 2); + const int midHeight = m_height - (CORNER_HEIGHT * 2); + const int bottomY = (m_y + m_height) - CORNER_HEIGHT; + const int bottomRectY = (m_y + m_height) - RECT_HEIGHT; + + sm_corners->render_part(target, m_x, m_y, 0, 0, CORNER_WIDTH, CORNER_HEIGHT); + sdl::render_rect_fill(target, midX, m_y, midWidth, RECT_HEIGHT, m_colorMod); + sm_corners->render_part(target, rightX, m_y, CORNER_HEIGHT, 0, CORNER_WIDTH, CORNER_HEIGHT); + // Middle + sdl::render_rect_fill(target, m_x, midY, RECT_WIDTH, midHeight, m_colorMod); + sdl::render_rect_fill(target, rightRectX, midY, RECT_WIDTH, midHeight, m_colorMod); + // Bottom + sm_corners->render_part(target, m_x, bottomY, 0, CORNER_HEIGHT, CORNER_WIDTH, CORNER_HEIGHT); + sdl::render_rect_fill(target, midX, bottomRectY, midWidth, RECT_HEIGHT, m_colorMod); + sm_corners->render_part(target, rightX, bottomY, CORNER_WIDTH, CORNER_HEIGHT, CORNER_WIDTH, CORNER_HEIGHT); +} + +void ui::BoundingBox::set_xy(int x, int y) +{ + if (x != BoundingBox::NO_SET) { m_x = x; } + if (y != BoundingBox::NO_SET) { m_y = y; } +} + +void ui::BoundingBox::set_width_height(int width, int height) +{ + if (width != BoundingBox::NO_SET) { m_width = width; } + if (height != BoundingBox::NO_SET) { m_height = height; } +} + +void ui::BoundingBox::initialize_static_members() +{ + if (sm_corners) { return; } + sm_corners = sdl::TextureManager::create_load_texture("menuCorners", "romfs:/Textures/MenuBounding.png"); +} diff --git a/source/ui/DialogBox.cpp b/source/ui/DialogBox.cpp new file mode 100644 index 0000000..26067b5 --- /dev/null +++ b/source/ui/DialogBox.cpp @@ -0,0 +1,69 @@ +#include "ui/DialogBox.hpp" + +#include "colors.hpp" + +namespace +{ + constexpr int CORNER_WIDTH = 16; + constexpr int CORNER_HEIGHT = 16; +} + +ui::DialogBox::DialogBox(int x, int y, int width, int height) + : m_x(x) + , m_y(y) + , m_width(width) + , m_height(height) +{ + ui::DialogBox::initialize_static_members(); +} + +std::shared_ptr ui::DialogBox::create(int x, int y, int width, int height) +{ + return std::make_shared(x, y, width, height); +} + +void ui::DialogBox::render(sdl::SharedTexture &target, bool hasFocus) +{ + // Top + sm_corners->render_part(target, m_x, m_y, 0, 0, CORNER_WIDTH, CORNER_HEIGHT); + sdl::render_rect_fill(target, m_x + CORNER_WIDTH, m_y, m_width - (CORNER_WIDTH * 2), CORNER_HEIGHT, colors::DIALOG_BOX); + sm_corners->render_part(target, (m_x + m_width) - CORNER_WIDTH, m_y, CORNER_WIDTH, 0, CORNER_WIDTH, CORNER_HEIGHT); + + // Middle + sdl::render_rect_fill(target, m_x, m_y + CORNER_HEIGHT, m_width, m_height - (CORNER_HEIGHT * 2), colors::DIALOG_BOX); + + // Bottom + sm_corners->render_part(target, m_x, (m_y + m_height) - CORNER_HEIGHT, 0, CORNER_HEIGHT, CORNER_WIDTH, CORNER_HEIGHT); + sdl::render_rect_fill(target, + m_x + CORNER_WIDTH, + (m_y + m_height) - CORNER_HEIGHT, + m_width - (CORNER_WIDTH * 2), + CORNER_HEIGHT, + colors::DIALOG_BOX); + sm_corners->render_part(target, + (m_x + m_width) - CORNER_WIDTH, + (m_y + m_height) - CORNER_HEIGHT, + CORNER_WIDTH, + CORNER_HEIGHT, + CORNER_WIDTH, + CORNER_HEIGHT); +} + +void ui::DialogBox::set_xy(int x, int y) +{ + if (x != DialogBox::NO_SET) { m_x = x; } + if (y != DialogBox::NO_SET) { m_y = y; } +} + +void ui::DialogBox::set_width_height(int width, int height) +{ + if (width != DialogBox::NO_SET) { m_width = width; } + if (height != DialogBox::NO_SET) { m_height = height; } +} + +void ui::DialogBox::initialize_static_members() +{ + if (sm_corners) { return; } + + sm_corners = sdl::TextureManager::create_load_texture("dialogCorners", "romfs:/Textures/DialogCorners.png"); +} diff --git a/source/ui/IconMenu.cpp b/source/ui/IconMenu.cpp index c1f6d77..95a9f76 100644 --- a/source/ui/IconMenu.cpp +++ b/source/ui/IconMenu.cpp @@ -1,17 +1,32 @@ #include "ui/IconMenu.hpp" #include "colors.hpp" -#include "ui/render_functions.hpp" -ui::IconMenu::IconMenu(int x, int y, int rendertargetHeight) - : Menu(x, y, 152, 80, rendertargetHeight) {}; +namespace +{ + constexpr int ICON_RENDER_WIDTH = 128; + constexpr int ICON_RENDER_HEIGHT = 128; + + constexpr int BOUND_WIDTH = 152; + constexpr int BOUND_HEIGHT = 146; +} + +ui::IconMenu::IconMenu(int x, int y, int renderTargetHeight) + : Menu(x, y, 152, 80, renderTargetHeight) +{ + // This needs to be overriden from the base state. + m_boundingBox->set_width_height(152, 146); +} + +std::shared_ptr ui::IconMenu::create(int x, int y, int renderTargetHeight) +{ + return std::make_shared(x, y, renderTargetHeight); +} void ui::IconMenu::update(bool hasFocus) { Menu::update(hasFocus); } -void ui::IconMenu::render(SDL_Texture *target, bool hasFocus) +void ui::IconMenu::render(sdl::SharedTexture &target, bool hasFocus) { - if (hasFocus) { m_colorMod.update(); } - const int optionCount = m_options.size(); for (int i = 0, tempY = m_y; i < optionCount; i++, tempY += m_optionHeight) { @@ -19,10 +34,15 @@ void ui::IconMenu::render(SDL_Texture *target, bool hasFocus) m_optionTarget->clear(colors::TRANSPARENT); if (i == m_selected) { - if (hasFocus) { ui::render_bounding_box(target, m_x - 8, tempY - 8, 152, 146, m_colorMod); } - sdl::render_rect_fill(m_optionTarget->get(), 0, 0, 4, 130, {0x00FFC5FF}); + if (hasFocus) + { + m_boundingBox->set_xy(m_x - 8, tempY - 8); + m_boundingBox->render(target, hasFocus); + } + // This is always rendered. + sdl::render_rect_fill(m_optionTarget, 0, 0, 4, 130, colors::BLUE_GREEN); } - m_options.at(i)->render_stretched(m_optionTarget->get(), 8, 1, 128, 128); + m_options[i]->render_stretched(m_optionTarget, 8, 1, ICON_RENDER_WIDTH, ICON_RENDER_HEIGHT); m_optionTarget->render(target, m_x, tempY); } } diff --git a/source/ui/Menu.cpp b/source/ui/Menu.cpp index 757c004..171a4a2 100644 --- a/source/ui/Menu.cpp +++ b/source/ui/Menu.cpp @@ -4,94 +4,57 @@ #include "config.hpp" #include "input.hpp" #include "mathutil.hpp" -#include "ui/render_functions.hpp" +#include "ui/BoundingBox.hpp" #include ui::Menu::Menu(int x, int y, int width, int fontSize, int renderTargetHeight) : m_x(x) , m_y(y) - , m_optionHeight(std::ceil(static_cast(fontSize) * 1.8f)) + , m_optionHeight(std::round(static_cast(fontSize) * 1.8f)) , m_originalY(y) , m_targetY(y) , m_width(width) , m_fontSize(fontSize) - , m_textY((m_optionHeight / 2) - (m_fontSize / 2) - 1) // This seems to be the best alignment. + , m_textY((m_optionHeight / 2) - (m_fontSize / 2)) // This seems to be the best alignment. , m_renderTargetHeight(renderTargetHeight) - , m_optionScroll("temp", 16, 0, m_width - 6, m_optionHeight, m_fontSize, colors::BLUE_GREEN, colors::TRANSPARENT) + , m_optionScroll( + ui::TextScroll::create("temp", 16, 0, m_width, m_optionHeight, m_fontSize, colors::BLUE_GREEN, colors::TRANSPARENT)) { // Create render target for options static int MENU_ID = 0; std::string menuTargetName = "MENU_" + std::to_string(MENU_ID++); - m_optionTarget = sdl::TextureManager::create_load_texture(menuTargetName, - m_width, - m_optionHeight, - SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); + m_optionTarget = + sdl::TextureManager::create_load_texture(menuTargetName, m_width, m_optionHeight, SDL_TEXTUREACCESS_TARGET); + + // Outside the initializer list because I'm tired and don't wanna deal with the headache. + m_boundingBox = ui::BoundingBox::create(0, 0, m_width + 12, m_optionHeight + 12); // Calculate around how many options can be shown on the render target at once. m_maxDisplayOptions = (renderTargetHeight - m_originalY) / m_optionHeight; m_scrollLength = std::floor(static_cast(m_maxDisplayOptions) / 2.0f); } +std::shared_ptr ui::Menu::create(int x, int y, int width, int fontSize, int renderTargetHeight) +{ + return std::make_shared(x, y, width, fontSize, renderTargetHeight); +} + void ui::Menu::update(bool hasFocus) { if (m_options.empty()) { return; } - // Need to task care of updating this somehow for the settings menu. - const std::string_view scrollText = m_optionScroll.get_text(); - if (scrollText != m_options[m_selected]) { m_optionScroll.set_text(m_options[m_selected], false); } + m_boundingBox->update(hasFocus); + m_optionScroll->update(hasFocus); - m_optionScroll.update(hasFocus); - - const bool upPressed = input::button_pressed(HidNpadButton_AnyUp); - const bool downPressed = input::button_pressed(HidNpadButton_AnyDown); - const bool leftPressed = input::button_pressed(HidNpadButton_AnyLeft); - const bool rightPressed = input::button_pressed(HidNpadButton_AnyRight); - const bool lShoulderPressed = input::button_pressed(HidNpadButton_L); - const bool rShoulderPressed = input::button_pressed(HidNpadButton_R); - const int optionsSize = m_options.size(); - const int prevSelected = m_selected; - - if (upPressed) { --m_selected; } - else if (downPressed) { ++m_selected; } - else if (leftPressed) { m_selected -= m_scrollLength; } - else if (rightPressed) { m_selected += m_scrollLength; } - else if (lShoulderPressed) { m_selected -= m_scrollLength * 3; } - else if (rShoulderPressed) { m_selected += m_scrollLength * 3; } - - if (m_selected < 0) { m_selected = 0; } - else if (m_selected >= optionsSize) { m_selected = optionsSize - 1; } - - // This needs updating. - if (m_selected != prevSelected) { m_optionScroll.set_text(m_options[m_selected], false); } - - // Don't bother continuing further if there's no reason to scroll. - if (optionsSize <= m_maxDisplayOptions) { return; } - - // These are to make things slightly easier to read down here. - const int endScrollPoint = optionsSize - (m_maxDisplayOptions - m_scrollLength); - const int scrolledItems = m_selected - m_scrollLength; - const double scaling = config::get_animation_scaling(); - - if (m_selected < m_scrollLength) { m_targetY = m_originalY; } // Don't bother. There's no point. - else if (m_selected >= endScrollPoint) { m_targetY = m_originalY - (optionsSize - m_maxDisplayOptions) * m_optionHeight; } - else if (m_selected >= m_scrollLength) { m_targetY = m_originalY - (scrolledItems * m_optionHeight); } - - if (m_y != m_targetY) - { - m_y += std::round((m_targetY - m_y) / scaling); - - const int distance = math::Util::get_absolute_distance(m_y, m_targetY); - if (distance <= 2) { m_y = m_targetY; } - } + Menu::handle_input(); + Menu::update_scrolling(); + Menu::update_scroll_text(); } -void ui::Menu::render(SDL_Texture *target, bool hasFocus) +void ui::Menu::render(sdl::SharedTexture &target, bool hasFocus) { if (m_options.empty()) { return; } - SDL_Texture *optionTarget = m_optionTarget->get(); - - m_colorMod.update(); // I hate doing this. const int optionSize = m_options.size(); @@ -104,15 +67,15 @@ void ui::Menu::render(SDL_Texture *target, bool hasFocus) if (i == m_selected) { - if (hasFocus) { ui::render_bounding_box(target, m_x - 4, tempY - 4, m_width + 8, m_optionHeight + 8, m_colorMod); } - sdl::render_rect_fill(optionTarget, 8, 8, 4, m_optionHeight - 16, colors::BLUE_GREEN); - m_optionScroll.render(optionTarget, hasFocus); - } - else - { - const char *option = m_options[i].c_str(); - sdl::text::render(optionTarget, 24, m_textY, m_fontSize, sdl::text::NO_TEXT_WRAP, colors::WHITE, option); + if (hasFocus) + { + m_boundingBox->set_xy(m_x - 4, tempY - 5); + m_boundingBox->render(target, hasFocus); + } + sdl::render_rect_fill(m_optionTarget, 8, 8, 4, m_optionHeight - 16, colors::BLUE_GREEN); + m_optionScroll->render(m_optionTarget, hasFocus); } + else { sdl::text::render(m_optionTarget, 24, m_textY, m_fontSize, sdl::text::NO_WRAP, colors::WHITE, m_options[i]); } // render target to target m_optionTarget->render(target, m_x, tempY); } @@ -121,7 +84,7 @@ void ui::Menu::render(SDL_Texture *target, bool hasFocus) void ui::Menu::add_option(std::string_view newOption) { // This is needed. The initialization is just a temporary one. - if (m_options.empty()) { m_optionScroll.set_text(newOption, false); } + if (m_options.empty()) { m_optionScroll->set_text(newOption, false); } m_options.push_back(newOption.data()); } @@ -134,7 +97,11 @@ void ui::Menu::edit_option(int index, std::string_view newOption) int ui::Menu::get_selected() const { return m_selected; } -void ui::Menu::set_selected(int selected) { m_selected = selected; } +void ui::Menu::set_selected(int selected) +{ + m_selected = selected; + Menu::update_scroll_text(); +} void ui::Menu::set_width(int width) { m_width = width; } @@ -144,3 +111,53 @@ void ui::Menu::reset() m_y = m_originalY; m_options.clear(); } + +void ui::Menu::update_scroll_text() +{ + const std::string_view text = m_optionScroll->get_text(); + const std::string_view option = m_options[m_selected]; + if (text != option) { m_optionScroll->set_text(option, false); } +} + +void ui::Menu::handle_input() +{ + const bool upPressed = input::button_pressed(HidNpadButton_AnyUp); + const bool downPressed = input::button_pressed(HidNpadButton_AnyDown); + const bool leftPressed = input::button_pressed(HidNpadButton_AnyLeft); + const bool rightPressed = input::button_pressed(HidNpadButton_AnyRight); + const bool lShoulderPressed = input::button_pressed(HidNpadButton_L); + const bool rShoulderPressed = input::button_pressed(HidNpadButton_R); + const int optionsSize = m_options.size(); + + if (upPressed) { --m_selected; } + else if (downPressed) { ++m_selected; } + else if (leftPressed) { m_selected -= m_scrollLength; } + else if (rightPressed) { m_selected += m_scrollLength; } + else if (lShoulderPressed) { m_selected -= m_scrollLength * 3; } + else if (rShoulderPressed) { m_selected += m_scrollLength * 3; } + + if (m_selected < 0) { m_selected = 0; } + else if (m_selected >= optionsSize) { m_selected = optionsSize - 1; } +} + +void ui::Menu::update_scrolling() +{ + const int optionsSize = m_options.size(); + if (optionsSize <= m_maxDisplayOptions) { return; } + + const int endScrollPoint = optionsSize - (m_maxDisplayOptions - m_scrollLength); + const int scrolledItems = m_selected - m_scrollLength; + const double scaling = config::get_animation_scaling(); + + if (m_selected < m_scrollLength) { m_targetY = m_originalY; } // Don't bother. There's no point. + else if (m_selected >= endScrollPoint) { m_targetY = m_originalY - (optionsSize - m_maxDisplayOptions) * m_optionHeight; } + else if (m_selected >= m_scrollLength) { m_targetY = m_originalY - (scrolledItems * m_optionHeight); } + + if (m_y != m_targetY) + { + m_y += std::round((m_targetY - m_y) / scaling); + + const int distance = math::Util::absolute_distance(m_y, m_targetY); + if (distance <= 2) { m_y = m_targetY; } + } +} diff --git a/source/ui/PopMessage.cpp b/source/ui/PopMessage.cpp new file mode 100644 index 0000000..64ebb40 --- /dev/null +++ b/source/ui/PopMessage.cpp @@ -0,0 +1,86 @@ +#include "ui/PopMessage.hpp" + +#include "colors.hpp" +#include "config.hpp" +#include "mathutil.hpp" +#include "sdl.hpp" + +ui::PopMessage::PopMessage(int ticks, std::string_view message) + : m_ticks(ticks) + , m_message(message) + , m_y(PopMessage::START_Y) + , m_width(PopMessage::START_WIDTH) + , m_dialog(ui::DialogBox::create(PopMessage::PERMA_X, m_y - 6, PopMessage::START_WIDTH, PopMessage::PERMA_HEIGHT)) +{ + const int messageWidth = sdl::text::get_width(22, m_message); + m_targetWidth = messageWidth + 32; +} + +void ui::PopMessage::update(double targetY) +{ + update_y(targetY); + update_width(); + update_text_offset(); + if (m_displayTimer.is_triggered()) { m_finished = true; } +} + +void ui::PopMessage::render() +{ + m_dialog->render(sdl::Texture::Null, false); + if (!m_expanded) { return; } + sdl::text::render(sdl::Texture::Null, + PopMessage::PERMA_X + 16, + m_y + 4, + 22, + sdl::text::NO_WRAP, + colors::WHITE, + m_message.substr(0, m_substrOffset)); +} + +bool ui::PopMessage::finished() const { return m_finished; } + +void ui::PopMessage::update_y(double targetY) +{ + if (m_y == targetY) { return; } + + const double scaling = config::get_animation_scaling(); + const double increase = (targetY - m_y) / scaling; + m_y += increase; + m_dialog->set_xy(m_dialog->NO_SET, m_y - 6); +} + +void ui::PopMessage::update_width() +{ + if (m_expanded) { return; } + + const int gap = math::Util::absolute_distance(m_targetWidth, m_width); + if (gap <= 4) + { + m_typeTimer.start(5); + m_width = m_targetWidth; + m_expanded = true; + m_dialog->set_width_height(m_width, m_dialog->NO_SET); + return; + } + + const double scaling = config::get_animation_scaling(); + const int expand = static_cast(gap) / scaling; + m_width += expand; + m_dialog->set_width_height(m_width, m_dialog->NO_SET); +} + +void ui::PopMessage::update_text_offset() +{ + const int messageLength = m_message.length(); + if (!m_expanded || m_substrOffset >= messageLength) { return; } + + // This is slightly more technical than I originally thought, but I liked the effect so. + uint32_t codepoint{}; + const char *message = m_message.c_str(); + const uint8_t *targetPoint = reinterpret_cast(&message[m_substrOffset]); + const ssize_t unitCount = decode_utf8(&codepoint, targetPoint); + if (unitCount <= 0) { return; } + + m_substrOffset += unitCount; + if (m_substrOffset >= messageLength) { m_displayTimer.start(m_ticks); } +} diff --git a/source/ui/PopMessageManager.cpp b/source/ui/PopMessageManager.cpp index 49244ab..a2a3e58 100644 --- a/source/ui/PopMessageManager.cpp +++ b/source/ui/PopMessageManager.cpp @@ -4,7 +4,7 @@ #include "config.hpp" #include "logger.hpp" #include "sdl.hpp" -#include "ui/render_functions.hpp" +#include "ui/PopMessage.hpp" #include @@ -12,7 +12,6 @@ namespace { // Size of the buffer for va strings. constexpr int VA_BUFFER_SIZE = 0x200; - } // namespace void ui::PopMessageManager::update() @@ -32,36 +31,24 @@ void ui::PopMessageManager::update() if (!messageQueue.empty()) { // Loop through the queue and process it so we don't wind up with black characters. - for (auto &[displayTicks, currentMessage] : messageQueue) - { - const size_t messageWidth = sdl::text::get_width(32, currentMessage.c_str()) + 32; - const ui::PopMessage newMessage = {.y = 720, - .targetY = 720, - .width = messageWidth, - .message = std::move(currentMessage), - .timer = sys::Timer{static_cast(displayTicks)}}; - - messages.push_back(std::move(newMessage)); - } + for (auto &[displayTicks, currentMessage] : messageQueue) { messages.emplace_back(displayTicks, currentMessage); } messageQueue.clear(); } } // Update all the messages. // This is the first Y position a message should be displayed at.; - double currentY = COORD_INIT_Y; - const double animationScaling = config::get_animation_scaling(); + double currentY = COORD_INIT_Y; std::lock_guard messageGuard{messageMutex}; for (auto message = messages.begin(); message != messages.end();) { - if (message->timer.is_triggered()) + if (message->finished()) { message = messages.erase(message); continue; } + message->update(currentY); - if (message->targetY != currentY) { message->targetY = currentY; } - else if (message->y != message->targetY) { message->y += (message->targetY - message->y) / animationScaling; } currentY -= 56; ++message; } @@ -74,11 +61,7 @@ void ui::PopMessageManager::render() std::mutex &messageMutex = manager.m_messageMutex; std::lock_guard messageGuard{messageMutex}; - for (const auto &message : messages) - { - ui::render_dialog_box(nullptr, 20, message.y - 6, message.width, 52); - sdl::text::render(nullptr, 36, message.y, 32, sdl::text::NO_TEXT_WRAP, colors::WHITE, message.message.c_str()); - } + for (auto &message : messages) { message.render(); } } void ui::PopMessageManager::push_message(int displayTicks, std::string_view message) diff --git a/source/ui/SlideOutPanel.cpp b/source/ui/SlideOutPanel.cpp index 9e7109d..9c0ff46 100644 --- a/source/ui/SlideOutPanel.cpp +++ b/source/ui/SlideOutPanel.cpp @@ -13,17 +13,14 @@ namespace } ui::SlideOutPanel::SlideOutPanel(int width, Side side) - : m_x{side == Side::Left ? static_cast(-width) : static_cast(SCREEN_WIDTH)} - , m_width{width} - , m_targetX{side == Side::Left ? 0.0f : static_cast(SCREEN_WIDTH) - m_width} - , m_side{side} - , m_scaling{config::get_animation_scaling()} + : m_x(side == Side::Left ? static_cast(-width) : static_cast(SCREEN_WIDTH)) + , m_width(width) + , m_targetX(side == Side::Left ? 0.0f : static_cast(SCREEN_WIDTH) - m_width) + , m_side(side) { - static constexpr int sdlFlags = SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET; - static int targetID = 0; std::string targetName = "panelTarget_" + std::to_string(targetID++); - m_renderTarget = sdl::TextureManager::create_load_texture(targetName, width, 720, sdlFlags); + m_renderTarget = sdl::TextureManager::create_load_texture(targetName, width, 720, SDL_TEXTUREACCESS_TARGET); } void ui::SlideOutPanel::update(bool hasFocus) @@ -40,11 +37,11 @@ void ui::SlideOutPanel::update(bool hasFocus) } } -void ui::SlideOutPanel::render(SDL_Texture *Target, bool hasFocus) +void ui::SlideOutPanel::render(sdl::SharedTexture &target, bool hasFocus) { - for (auto ¤tElement : m_elements) { currentElement->render(m_renderTarget->get(), hasFocus); } + for (auto ¤tElement : m_elements) { currentElement->render(m_renderTarget, hasFocus); } - m_renderTarget->render(NULL, m_x, 0); + m_renderTarget->render(target, m_x, 0); } void ui::SlideOutPanel::clear_target() { m_renderTarget->clear(colors::SLIDE_PANEL_CLEAR); } @@ -77,14 +74,16 @@ void ui::SlideOutPanel::push_new_element(std::shared_ptr newElement void ui::SlideOutPanel::clear_elements() { m_elements.clear(); } -SDL_Texture *ui::SlideOutPanel::get_target() { return m_renderTarget->get(); } +sdl::SharedTexture &ui::SlideOutPanel::get_target() { return m_renderTarget; } void ui::SlideOutPanel::slide_out_left() { - m_x -= std::round(m_x / m_scaling); + const double scaling = config::get_animation_scaling(); + + m_x -= std::round(m_x / scaling); // This is a workaround for the floating points never lining up quite right. - const int distance = math::Util::get_absolute_distance(m_x, m_targetX); + const int distance = math::Util::absolute_distance(m_x, m_targetX); if (distance <= 2) { m_x = m_targetX; @@ -94,12 +93,13 @@ void ui::SlideOutPanel::slide_out_left() void ui::SlideOutPanel::slide_out_right() { + const double scaling = config::get_animation_scaling(); const double screenWidth = static_cast(SCREEN_WIDTH); const double width = static_cast(m_width); - const double pixels = (screenWidth - width - m_x) / m_scaling; + const double pixels = (screenWidth - width - m_x) / scaling; m_x += std::round(pixels); - const int distance = math::Util::get_absolute_distance(m_x, m_targetX); + const int distance = math::Util::absolute_distance(m_x, m_targetX); if (distance <= 2) { m_x = m_targetX; diff --git a/source/ui/TextScroll.cpp b/source/ui/TextScroll.cpp index 0830419..3a3a96b 100644 --- a/source/ui/TextScroll.cpp +++ b/source/ui/TextScroll.cpp @@ -21,18 +21,31 @@ ui::TextScroll::TextScroll(std::string_view text, sdl::Color clearColor, bool center) { - TextScroll::create(text, x, y, width, height, fontSize, textColor, clearColor, center); + TextScroll::initialize(text, x, y, width, height, fontSize, textColor, clearColor, center); } -void ui::TextScroll::create(std::string_view text, - int x, - int y, - int width, - int height, - int fontSize, - sdl::Color textColor, - sdl::Color clearColor, - bool center) +std::shared_ptr ui::TextScroll::create(std::string_view text, + int x, + int y, + int width, + int height, + int fontSize, + sdl::Color textColor, + sdl::Color clearColor, + bool center) +{ + return std::make_shared(text, x, y, width, height, fontSize, textColor, clearColor, center); +} + +void ui::TextScroll::initialize(std::string_view text, + int x, + int y, + int width, + int height, + int fontSize, + sdl::Color textColor, + sdl::Color clearColor, + bool center) { static int TARGET_ID{}; @@ -48,10 +61,8 @@ void ui::TextScroll::create(std::string_view text, { const std::string targetName = "textScroll_" + std::to_string(TARGET_ID++); - m_renderTarget = sdl::TextureManager::create_load_texture(targetName, - m_targetWidth, - m_targetHeight, - SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); + m_renderTarget = + sdl::TextureManager::create_load_texture(targetName, m_targetWidth, m_targetHeight, SDL_TEXTUREACCESS_TARGET); } TextScroll::set_text(text, center); @@ -112,26 +123,25 @@ void ui::TextScroll::set_xy(int x, int y) m_renderY = y; } -void ui::TextScroll::render(SDL_Texture *target, bool hasFocus) +void ui::TextScroll::render(sdl::SharedTexture &target, bool hasFocus) { m_renderTarget->clear(m_clearColor); - SDL_Texture *renderTarget = m_renderTarget->get(); if (!m_textScrolling) { - sdl::text::render(renderTarget, m_textX, m_textY, m_fontSize, sdl::text::NO_TEXT_WRAP, m_textColor, m_text.c_str()); + sdl::text::render(m_renderTarget, m_textX, m_textY, m_fontSize, sdl::text::NO_WRAP, m_textColor, m_text); } else { // We're going to render text twice so it looks like it's scrolling and doesn't end. Ever. - sdl::text::render(renderTarget, m_textX, m_textY, m_fontSize, sdl::text::NO_TEXT_WRAP, m_textColor, m_text.c_str()); - sdl::text::render(renderTarget, + sdl::text::render(m_renderTarget, m_textX, m_textY, m_fontSize, sdl::text::NO_WRAP, m_textColor, m_text); + sdl::text::render(m_renderTarget, m_textX + m_textWidth + 8, m_textY, m_fontSize, - sdl::text::NO_TEXT_WRAP, + sdl::text::NO_WRAP, m_textColor, - m_text.c_str()); + m_text); } m_renderTarget->render(target, m_renderX, m_renderY); } diff --git a/source/ui/TitleTile.cpp b/source/ui/TitleTile.cpp index 487aa1a..3be004d 100644 --- a/source/ui/TitleTile.cpp +++ b/source/ui/TitleTile.cpp @@ -29,16 +29,15 @@ void ui::TitleTile::update(int selected) } } -void ui::TitleTile::render(SDL_Texture *target, int x, int y) +void ui::TitleTile::render(sdl::SharedTexture &target, int x, int y) { + static constexpr std::string_view HEART_CHAR = "\uE017"; + const int renderX = x - ((m_renderWidth - 128) / 2); const int renderY = y - ((m_renderHeight - 128) / 2); m_icon->render_stretched(target, renderX, renderY, m_renderWidth, m_renderHeight); - if (m_isFavorite) - { - sdl::text::render(target, renderX + 2, renderY + 2, 28, sdl::text::NO_TEXT_WRAP, colors::PINK, "\uE017"); - } + if (m_isFavorite) { sdl::text::render(target, renderX + 2, renderY + 2, 28, sdl::text::NO_WRAP, colors::PINK, HEART_CHAR); } } void ui::TitleTile::reset() diff --git a/source/ui/TitleView.cpp b/source/ui/TitleView.cpp index 58bdbf1..9caa59d 100644 --- a/source/ui/TitleView.cpp +++ b/source/ui/TitleView.cpp @@ -3,7 +3,6 @@ #include "colors.hpp" #include "config.hpp" #include "input.hpp" -#include "ui/render_functions.hpp" #include @@ -14,6 +13,7 @@ namespace ui::TitleView::TitleView(data::User *user) : m_user(user) + , m_bounding(ui::BoundingBox::create(0, 0, 188, 188)) { TitleView::refresh(); } @@ -22,13 +22,13 @@ void ui::TitleView::update(bool hasFocus) { if (m_titleTiles.empty()) { return; } - m_colorMod.update(); + m_bounding->update(hasFocus); TitleView::handle_input(); TitleView::handle_scrolling(); TitleView::update_tiles(); } -void ui::TitleView::render(SDL_Texture *target, bool hasFocus) +void ui::TitleView::render(sdl::SharedTexture &target, bool hasFocus) { static constexpr int TILE_SPACE_VERT = 144; static constexpr int TILE_SPACE_HOR = 144; @@ -55,8 +55,9 @@ void ui::TitleView::render(SDL_Texture *target, bool hasFocus) if (hasFocus) { - sdl::render_rect_fill(target, m_selectedX - 29, m_selectedY - 29, 187, 187, colors::CLEAR_COLOR); - ui::render_bounding_box(target, m_selectedX - 30, m_selectedY - 30, 188, 188, m_colorMod); + m_bounding->set_xy(m_selectedX - 30, m_selectedY - 30); + sdl::render_rect_fill(target, m_selectedX - 28, m_selectedY - 28, 184, 184, colors::CLEAR_COLOR); + m_bounding->render(target, hasFocus); } ui::TitleTile &selectedTile = m_titleTiles[m_selected]; @@ -65,6 +66,13 @@ void ui::TitleView::render(SDL_Texture *target, bool hasFocus) int ui::TitleView::get_selected() const { return m_selected; } +void ui::TitleView::set_selected(int selected) +{ + const int tilesCount = m_titleTiles.size(); + if (selected < 0 || selected >= tilesCount) { return; } + m_selected = selected; +} + void ui::TitleView::refresh() { m_titleTiles.clear(); diff --git a/source/ui/render_functions.cpp b/source/ui/render_functions.cpp deleted file mode 100644 index 386c33f..0000000 --- a/source/ui/render_functions.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "ui/render_functions.hpp" - -#include "colors.hpp" - -namespace -{ - sdl::SharedTexture s_dialogCorners{}; - sdl::SharedTexture s_menuBoundingCorners{}; -} // namespace - -void ui::render_dialog_box(SDL_Texture *target, int x, int y, int width, int height) -{ - if (!s_dialogCorners) - { - s_dialogCorners = sdl::TextureManager::create_load_texture("DialogCorners", "romfs:/Textures/DialogCorners.png"); - } - - // Top - s_dialogCorners->render_part(target, x, y, 0, 0, 16, 16); - sdl::render_rect_fill(target, x + 16, y, width - 32, 16, colors::DIALOG_BOX); - s_dialogCorners->render_part(target, (x + width) - 16, y, 16, 0, 16, 16); - - // Middle - sdl::render_rect_fill(NULL, x, y + 16, width, height - 32, colors::DIALOG_BOX); - - // Bottom - s_dialogCorners->render_part(target, x, (y + height) - 16, 0, 16, 16, 16); - sdl::render_rect_fill(NULL, x + 16, (y + height) - 16, width - 32, 16, colors::DIALOG_BOX); - s_dialogCorners->render_part(NULL, (x + width) - 16, (y + height) - 16, 16, 16, 16, 16); -} - -void ui::render_bounding_box(SDL_Texture *target, int x, int y, int width, int height, const ui::ColorMod &colorMod) -{ - if (!s_menuBoundingCorners) - { - s_menuBoundingCorners = - sdl::TextureManager::create_load_texture("MenuBoundingCorners", "romfs:/Textures/MenuBounding.png"); - } - - // This shouldn't fail, but I don't really care if it does. - s_menuBoundingCorners->set_color_mod(colorMod); - - // Top - s_menuBoundingCorners->render_part(target, x, y, 0, 0, 8, 8); - sdl::render_rect_fill(target, x + 8, y, width - 16, 4, colorMod); - s_menuBoundingCorners->render_part(target, (x + width) - 8, y, 8, 0, 8, 8); - // Middle - sdl::render_rect_fill(target, x, y + 8, 4, height - 16, colorMod); - sdl::render_rect_fill(target, (x + width) - 4, y + 8, 4, height - 16, colorMod); - // Bottom - s_menuBoundingCorners->render_part(target, x, (y + height) - 8, 0, 8, 8, 8); - sdl::render_rect_fill(target, x + 8, (y + height) - 4, width - 16, 4, colorMod); - s_menuBoundingCorners->render_part(target, (x + width) - 8, (y + height) - 8, 8, 8, 8, 8); -}