diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/GD_INSTRUCTIONS.MD b/GD_INSTRUCTIONS.MD old mode 100644 new mode 100755 diff --git a/JKSV.lst b/JKSV.lst old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 diff --git a/README.MD b/README.MD old mode 100644 new mode 100755 diff --git a/icon.jpg b/icon.jpg old mode 100644 new mode 100755 diff --git a/iconAssets/JKSV_icon.png b/iconAssets/JKSV_icon.png old mode 100644 new mode 100755 diff --git a/iconAssets/JKSV_icon.svg b/iconAssets/JKSV_icon.svg old mode 100644 new mode 100755 diff --git a/inc/appStates/appState.hpp b/inc/appStates/appState.hpp old mode 100644 new mode 100755 diff --git a/inc/appStates/backupMenuState.hpp b/inc/appStates/backupMenuState.hpp old mode 100644 new mode 100755 index fd2962b..f9e41ac --- a/inc/appStates/backupMenuState.hpp +++ b/inc/appStates/backupMenuState.hpp @@ -29,10 +29,10 @@ class backupMenuState : public appState std::string m_BackupMenuControlGuide; // Base path for output std::string m_OutputBasePath; - // Slide in/out panel - std::unique_ptr m_BackupPanel; // Width of panel/text int m_PanelWidth; + // Slide in/out panel + std::unique_ptr m_BackupPanel; // Folder listing std::unique_ptr m_BackupListing; // Listing to make sure there is a save diff --git a/inc/appStates/confirmState.hpp b/inc/appStates/confirmState.hpp old mode 100644 new mode 100755 index 481d304..4123ea0 --- a/inc/appStates/confirmState.hpp +++ b/inc/appStates/confirmState.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "appStates/appState.hpp" #include "system/timer.hpp" #include "system/task.hpp" diff --git a/inc/appStates/mainMenuState.hpp b/inc/appStates/mainMenuState.hpp old mode 100644 new mode 100755 diff --git a/inc/appStates/progressState.hpp b/inc/appStates/progressState.hpp old mode 100644 new mode 100755 index 1cfa55e..e5fc60c --- a/inc/appStates/progressState.hpp +++ b/inc/appStates/progressState.hpp @@ -10,7 +10,7 @@ class progressState : public appState { public: - progressState(sys::taskFunction function, std::shared_ptr args, const uint64_t &maxValue); + progressState(sys::taskFunction threadFunction, std::shared_ptr args, const uint64_t &maxValue); ~progressState(); void update(void); void render(void); diff --git a/inc/appStates/taskState.hpp b/inc/appStates/taskState.hpp old mode 100644 new mode 100755 index 7150c2f..3b0f89e --- a/inc/appStates/taskState.hpp +++ b/inc/appStates/taskState.hpp @@ -1,17 +1,32 @@ #pragma once +#include #include #include "appStates/appState.hpp" +#include "system/timer.hpp" #include "system/task.hpp" class taskState : public appState { public: - taskState(sys::taskFunction function, std::shared_ptr args); + taskState(sys::taskFunction threadFunction, std::shared_ptr args); ~taskState(); void update(void); void render(void); + // This is so progressState can inherit this function + void renderLoadingGlyph(void); + protected: + // Task that is created and runs std::unique_ptr m_Task; + // What frame of the glyph array we're on + int m_GlyphFrame = 0; + // Timer for updating loading glyph + std::unique_ptr m_LoadingGlyphTimer; + // Bool for adding subtracting from color modifier + bool m_ColorModifier = true; + // Color modification for glyph + uint8_t m_LoadingGlyphColorMod = 0x00; + }; diff --git a/inc/appStates/titleOptionState.hpp b/inc/appStates/titleOptionState.hpp old mode 100644 new mode 100755 diff --git a/inc/appStates/titleSelectionState.hpp b/inc/appStates/titleSelectionState.hpp old mode 100644 new mode 100755 diff --git a/inc/config.hpp b/inc/config.hpp old mode 100644 new mode 100755 diff --git a/inc/data/data.hpp b/inc/data/data.hpp old mode 100644 new mode 100755 diff --git a/inc/data/titleInfo.hpp b/inc/data/titleInfo.hpp old mode 100644 new mode 100755 diff --git a/inc/data/user.hpp b/inc/data/user.hpp old mode 100644 new mode 100755 diff --git a/inc/data/userSaveInfo.hpp b/inc/data/userSaveInfo.hpp old mode 100644 new mode 100755 diff --git a/inc/filesystem/directoryListing.hpp b/inc/filesystem/directoryListing.hpp old mode 100644 new mode 100755 index 2d784e4..a0e3fcc --- a/inc/filesystem/directoryListing.hpp +++ b/inc/filesystem/directoryListing.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include @@ -28,6 +29,6 @@ namespace fs // Stores the path to the directory passed std::string m_DirectoryPath; // Stores the names of items from list - std::vector m_DirectoryList; + std::vector m_DirectoryList; }; } \ No newline at end of file diff --git a/inc/filesystem/fileParser.hpp b/inc/filesystem/fileParser.hpp old mode 100644 new mode 100755 diff --git a/inc/filesystem/filesystem.hpp b/inc/filesystem/filesystem.hpp old mode 100644 new mode 100755 index 15748b8..91803ca --- a/inc/filesystem/filesystem.hpp +++ b/inc/filesystem/filesystem.hpp @@ -17,6 +17,4 @@ namespace fs void unmountSaveData(void); // Commits to default save path void commitSaveData(void); - // Erases current save data from device - void eraseSaveData(void); } \ No newline at end of file diff --git a/inc/filesystem/io.hpp b/inc/filesystem/io.hpp old mode 100644 new mode 100755 index b3a337c..c981a51 --- a/inc/filesystem/io.hpp +++ b/inc/filesystem/io.hpp @@ -43,8 +43,6 @@ namespace fs void copyDirectory(const std::string &source, const std::string &destination); // Recursively copies source to destination void copyDirectoryCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize); - // std::filesystem::remove all crashes switch? Had to write my own... - void deleteDirectoryRecursively(const std::string &target); // These are functions for threaded copying that other parts of JKSV can use. void readThreadFunction(const std::string &source, std::shared_ptr sharedStruct); void writeThreadFunction(const std::string &destination, std::shared_ptr sharedStruct); diff --git a/inc/filesystem/zip.hpp b/inc/filesystem/zip.hpp old mode 100644 new mode 100755 diff --git a/inc/graphics/colors.hpp b/inc/graphics/colors.hpp old mode 100644 new mode 100755 diff --git a/inc/graphics/graphics.hpp b/inc/graphics/graphics.hpp old mode 100644 new mode 100755 diff --git a/inc/graphics/systemFont.hpp b/inc/graphics/systemFont.hpp old mode 100644 new mode 100755 diff --git a/inc/graphics/textureNames.hpp b/inc/graphics/textureNames.hpp old mode 100644 new mode 100755 diff --git a/inc/jksv.hpp b/inc/jksv.hpp old mode 100644 new mode 100755 diff --git a/inc/log.hpp b/inc/log.hpp old mode 100644 new mode 100755 diff --git a/inc/stringUtil.hpp b/inc/stringUtil.hpp old mode 100644 new mode 100755 diff --git a/inc/system/input.hpp b/inc/system/input.hpp old mode 100644 new mode 100755 index 0b5a40b..fd82aaf --- a/inc/system/input.hpp +++ b/inc/system/input.hpp @@ -17,6 +17,10 @@ namespace sys bool buttonHeld(const HidNpadButton &button); bool buttonReleased(const HidNpadButton &button); + uint64_t buttonsDown(void); + uint64_t buttonsHeld(void); + uint64_t buttonsReleased(void); + // Gets input and returns C++ string std::string getString(const std::string &defaultText, const std::string &headerText, const size_t &maximumLength); } diff --git a/inc/system/progressArgs.hpp b/inc/system/progressArgs.hpp old mode 100644 new mode 100755 diff --git a/inc/system/task.hpp b/inc/system/task.hpp old mode 100644 new mode 100755 index 1ae0024..88bd915 --- a/inc/system/task.hpp +++ b/inc/system/task.hpp @@ -12,15 +12,15 @@ namespace sys { class task; - using taskFunction = std::function)>; + using taskFunction = std::function)>; class task { public: - // taskFunction is - task(taskFunction function, std::shared_ptr args); + // taskFunction is + task(sys::taskFunction threadFunction, std::shared_ptr args); ~task(); - // Returns status string of task. + // Returns status string of task. std::string getThreadStatus(void); // Sets status of task void setThreadStatus(const std::string &newStatus); @@ -28,9 +28,9 @@ namespace sys void finished(void); // Returns if task bool isRunning(void); - + private: - // Thread + // Thread. Orignally used C++ threads, but without control they choked the main thread. std::unique_ptr m_Thread; // Status string std::string m_ThreadStatus; diff --git a/inc/system/taskArgs.hpp b/inc/system/taskArgs.hpp old mode 100644 new mode 100755 diff --git a/inc/system/timer.hpp b/inc/system/timer.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/iconMenu.hpp b/inc/ui/iconMenu.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/menu.hpp b/inc/ui/menu.hpp old mode 100644 new mode 100755 index 597121d..aa713bf --- a/inc/ui/menu.hpp +++ b/inc/ui/menu.hpp @@ -24,6 +24,8 @@ namespace ui void updateColorPulse(void); // Returns currently selected option int getSelected(void) const; + // Sets selected option to newSelected + void setSelected(const int &newSelected); // Clears all options from menu void clearMenu(void); diff --git a/inc/ui/popMessage.hpp b/inc/ui/popMessage.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/progressBar.hpp b/inc/ui/progressBar.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/slidePanel.hpp b/inc/ui/slidePanel.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/strings.hpp b/inc/ui/strings.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/titleSelection.hpp b/inc/ui/titleSelection.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/titleTile.hpp b/inc/ui/titleTile.hpp old mode 100644 new mode 100755 diff --git a/inc/ui/ui.hpp b/inc/ui/ui.hpp old mode 100644 new mode 100755 diff --git a/romfs/icon.png b/romfs/icon.png old mode 100644 new mode 100755 diff --git a/romfs/img/dialogDark/dialogBottomLeft.png b/romfs/img/dialogDark/dialogBottomLeft.png old mode 100644 new mode 100755 diff --git a/romfs/img/dialogDark/dialogBottomRight.png b/romfs/img/dialogDark/dialogBottomRight.png old mode 100644 new mode 100755 diff --git a/romfs/img/dialogDark/dialogTopLeft.png b/romfs/img/dialogDark/dialogTopLeft.png old mode 100644 new mode 100755 diff --git a/romfs/img/dialogDark/dialogTopRight.png b/romfs/img/dialogDark/dialogTopRight.png old mode 100644 new mode 100755 diff --git a/romfs/img/icn/icnDefault.png b/romfs/img/icn/icnDefault.png old mode 100644 new mode 100755 diff --git a/romfs/img/icn/icnDrk.png b/romfs/img/icn/icnDrk.png old mode 100644 new mode 100755 diff --git a/romfs/img/icn/icon.msk b/romfs/img/icn/icon.msk old mode 100644 new mode 100755 diff --git a/romfs/img/icn/iconWhite.png b/romfs/img/icn/iconWhite.png old mode 100644 new mode 100755 diff --git a/romfs/img/menu/backgroundDark.png b/romfs/img/menu/backgroundDark.png old mode 100644 new mode 100755 diff --git a/romfs/img/menu/backgroundLight.png b/romfs/img/menu/backgroundLight.png old mode 100644 new mode 100755 diff --git a/romfs/img/menu/selectionBottomLeft.png b/romfs/img/menu/selectionBottomLeft.png old mode 100644 new mode 100755 diff --git a/romfs/img/menu/selectionBottomRight.png b/romfs/img/menu/selectionBottomRight.png old mode 100644 new mode 100755 diff --git a/romfs/img/menu/selectionTopLeft.png b/romfs/img/menu/selectionTopLeft.png old mode 100644 new mode 100755 diff --git a/romfs/img/menu/selectionTopRight.png b/romfs/img/menu/selectionTopRight.png old mode 100644 new mode 100755 diff --git a/romfs/img/tboxLght/progBarCoverLeftLight.png b/romfs/img/tboxLght/progBarCoverLeftLight.png old mode 100644 new mode 100755 diff --git a/romfs/img/tboxLght/progBarCoverRightLight.png b/romfs/img/tboxLght/progBarCoverRightLight.png old mode 100644 new mode 100755 diff --git a/romfs/img/tboxLght/tboxCornerBotLeft.png b/romfs/img/tboxLght/tboxCornerBotLeft.png old mode 100644 new mode 100755 diff --git a/romfs/img/tboxLght/tboxCornerBotRight.png b/romfs/img/tboxLght/tboxCornerBotRight.png old mode 100644 new mode 100755 diff --git a/romfs/img/tboxLght/tboxCornerTopLeft.png b/romfs/img/tboxLght/tboxCornerTopLeft.png old mode 100644 new mode 100755 diff --git a/romfs/img/tboxLght/tboxCornerTopRight.png b/romfs/img/tboxLght/tboxCornerTopRight.png old mode 100644 new mode 100755 diff --git a/romfs/lang/de.txt b/romfs/lang/de.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/en-GB.txt b/romfs/lang/en-GB.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/en-US.txt b/romfs/lang/en-US.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/es-419.txt b/romfs/lang/es-419.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/es.txt b/romfs/lang/es.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/fr-CA.txt b/romfs/lang/fr-CA.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/fr.txt b/romfs/lang/fr.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/it.txt b/romfs/lang/it.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/ja.txt b/romfs/lang/ja.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/ko.txt b/romfs/lang/ko.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/nl.txt b/romfs/lang/nl.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/pt-BR.txt b/romfs/lang/pt-BR.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/pt.txt b/romfs/lang/pt.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/ru.txt b/romfs/lang/ru.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/zh-CN.txt b/romfs/lang/zh-CN.txt old mode 100644 new mode 100755 diff --git a/romfs/lang/zh-TW.txt b/romfs/lang/zh-TW.txt old mode 100644 new mode 100755 diff --git a/src/appStates/appState.cpp b/src/appStates/appState.cpp old mode 100644 new mode 100755 diff --git a/src/appStates/backupMenuState.cpp b/src/appStates/backupMenuState.cpp old mode 100644 new mode 100755 index 71edffa..fdb9df1 --- a/src/appStates/backupMenuState.cpp +++ b/src/appStates/backupMenuState.cpp @@ -14,6 +14,14 @@ #include "jksv.hpp" #include "log.hpp" +// Names of panels, render targets, and coordinates + dimensions of menu +static const char *BACKUP_PANEL_NAME = "backupMenuPanel"; +static const char *BACKUP_MENU_TARGET_NAME = "backupMenuRenderTarget"; +static const int BACKUP_MENU_X = 10; +static const int BACKUP_MENU_Y = 4; +static const int BACKUP_MENU_FONT_SIZE = 18; +static const int BACKUP_MENU_SCROLL_LENGTH = 6; + // This is for backup task struct backupArgs : sys::taskArgs { @@ -37,7 +45,7 @@ struct pathArgs : sys::taskArgs // These are the functions used for tasks // Creates a new backup when new is selected. args must be a backupArgs struct as a shared pointer -void createNewBackup(sys::task *task, std::shared_ptr args) +static void createNewBackup(sys::task *task, std::shared_ptr args) { // Make sure we weren't passed nullptr if (args == nullptr) @@ -98,7 +106,7 @@ void createNewBackup(sys::task *task, std::shared_ptr args) } // Overwrites a backup already on SD -void overwriteBackup(sys::task *task, std::shared_ptr args) +static void overwriteBackup(sys::task *task, std::shared_ptr args) { // Bail if no args present if (args == nullptr) @@ -107,6 +115,9 @@ void overwriteBackup(sys::task *task, std::shared_ptr args) return; } + // Error code for filesystem + std::error_code errorCode; + // Set status, cast args to type task->setThreadStatus("REPLACE THIS LATER"); std::shared_ptr argsIn = std::static_pointer_cast(args); @@ -119,12 +130,12 @@ void overwriteBackup(sys::task *task, std::shared_ptr args) // Delete backup then recreate directory // Add trailing slash first. std::string target = argsIn->destination + "/"; - // std::filesystem::remove_all keeps crashing my switch, so I wrote my own again - fs::io::deleteDirectoryRecursively(target); + // Delete old backup + std::filesystem::remove_all(target, errorCode); // Recreate whole path. std::filesystem::create_directories(argsIn->destination); // Create the new backup in the same folder - fs::io::copyDirectory(fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->destination); + fs::io::copyDirectory(fs::DEFAULT_SAVE_MOUNT_DEVICE, target); } else if (std::filesystem::is_directory(argsIn->destination) == false && fileExtension == "zip") { @@ -141,7 +152,7 @@ void overwriteBackup(sys::task *task, std::shared_ptr args) // Wipes current save for game, then copies backup from SD to filesystem // Note: Needs to be tested better some time -void restoreBackup(sys::task *task, std::shared_ptr args) +static void restoreBackup(sys::task *task, std::shared_ptr args) { if (args == nullptr) { @@ -149,6 +160,9 @@ void restoreBackup(sys::task *task, std::shared_ptr args) return; } + // Error code for later + std::error_code errorCode; + // Set status, cast args task->setThreadStatus("REPLACE THIS LATER"); std::shared_ptr argsIn = std::static_pointer_cast(args); @@ -166,7 +180,7 @@ void restoreBackup(sys::task *task, std::shared_ptr args) if(testListing.getListingCount() > 0) { // Folder isn't empty, erase - fs::eraseSaveData(); + std::filesystem::remove_all(fs::DEFAULT_SAVE_MOUNT_DEVICE, errorCode); // Copy source to save container fs::io::copyDirectoryCommit(source, fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->journalSize); } @@ -183,9 +197,11 @@ void restoreBackup(sys::task *task, std::shared_ptr args) // Close zip unzClose(unzip); } + + task->finished(); } -void deleteBackup(sys::task *task, std::shared_ptr args) +static void deleteBackup(sys::task *task, std::shared_ptr args) { if (args == nullptr) { @@ -193,6 +209,9 @@ void deleteBackup(sys::task *task, std::shared_ptr args) return; } + // Error code for filesystem later + std::error_code errorCode; + // Set thread status task->setThreadStatus(ui::strings::getString(LANG_THREAD_DELETE_FILE, 0)); @@ -201,14 +220,15 @@ void deleteBackup(sys::task *task, std::shared_ptr args) if (std::filesystem::is_directory(argsIn->destination)) { - // Doesn't have trailing slash - std::string target = argsIn->destination + "/"; - fs::io::deleteDirectoryRecursively(target); + logger::log("%s is directory.", argsIn->destination.c_str()); + std::uintmax_t deleted = std::filesystem::remove_all(argsIn->destination, errorCode); + logger::log("Error code: %s, %i - %u", errorCode.message().c_str(), errorCode.value(), deleted); } else { + logger::log("%s is not a directory", argsIn->destination.c_str()); // Just remove it since it's probably a zip file - std::filesystem::remove(argsIn->destination); + std::filesystem::remove(argsIn->destination, errorCode); } // Refresh to reflect changes argsIn->sendingState->loadDirectoryList(); @@ -216,27 +236,23 @@ void deleteBackup(sys::task *task, std::shared_ptr args) task->finished(); } -backupMenuState::backupMenuState(data::user *currentUser, data::userSaveInfo *currentUserSaveInfo, data::titleInfo *currentTitleInfo) : m_CurrentUser(currentUser), m_CurrentUserSaveInfo(currentUserSaveInfo), m_CurrentTitleInfo(currentTitleInfo) +backupMenuState::backupMenuState(data::user *currentUser, data::userSaveInfo *currentUserSaveInfo, data::titleInfo *currentTitleInfo) : +m_CurrentUser(currentUser), +m_CurrentUserSaveInfo(currentUserSaveInfo), +m_CurrentTitleInfo(currentTitleInfo), +m_BackupMenuControlGuide(ui::strings::getString(LANG_FOLDER_GUIDE, 0)), +m_OutputBasePath(config::getWorkingDirectory() + m_CurrentTitleInfo->getPathSafeTitle() + "/"), +m_PanelWidth(graphics::systemFont::getTextWidth(m_BackupMenuControlGuide, 18)), +m_BackupPanel(std::make_unique(BACKUP_PANEL_NAME, m_PanelWidth + 64, ui::slidePanelSide::PANEL_SIDE_RIGHT)), +m_BackupListing(std::make_unique(m_OutputBasePath)), +m_SaveListing(std::make_unique(fs::DEFAULT_SAVE_MOUNT_DEVICE)), +m_BackupMenu(std::make_unique(BACKUP_MENU_X, BACKUP_MENU_Y, m_PanelWidth + 44, BACKUP_MENU_FONT_SIZE, BACKUP_MENU_SCROLL_LENGTH)) { - // This is the path used for all in/output. Create it if it doesn't exist. - m_OutputBasePath = config::getWorkingDirectory() + m_CurrentTitleInfo->getPathSafeTitle() + "/"; + // Make sure path exists std::filesystem::create_directories(m_OutputBasePath); - - // Controls displayed at bottom - m_BackupMenuControlGuide = ui::strings::getString(LANG_FOLDER_GUIDE, 0); - m_PanelWidth = graphics::systemFont::getTextWidth(m_BackupMenuControlGuide, 18); - - // The actual panel - m_BackupPanel = std::make_unique("backupMenuPanel", m_PanelWidth + 64, ui::slidePanelSide::PANEL_SIDE_RIGHT); - // The menu of backups - m_BackupMenu = std::make_unique(10, 4, m_PanelWidth + 44, 18, 6); // Render target that menu is rendered to - m_BackupMenuRenderTarget = graphics::textureCreate("backupMenuRenderTarget", m_PanelWidth + 64, 647, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); - // Directory listing of backups - m_BackupListing = std::make_unique(m_OutputBasePath); - // Directory listing of save - m_SaveListing = std::make_unique(fs::DEFAULT_SAVE_MOUNT_DEVICE); - + m_BackupMenuRenderTarget = graphics::textureCreate(BACKUP_MENU_TARGET_NAME, m_PanelWidth + 64, 647, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); + // Call this just to be sure. backupMenuState::loadDirectoryList(); } @@ -361,6 +377,7 @@ void backupMenuState::loadDirectoryList(void) // Reload list, clear menu m_BackupListing->loadListing(); m_BackupMenu->clearMenu(); + m_BackupMenu->setSelected(0); int listingCount = m_BackupListing->getListingCount(); m_BackupMenu->addOpt(ui::strings::getString(LANG_FOLDER_MENU_NEW, 0)); diff --git a/src/appStates/confirmState.cpp b/src/appStates/confirmState.cpp old mode 100644 new mode 100755 index 9a2a615..59774be --- a/src/appStates/confirmState.cpp +++ b/src/appStates/confirmState.cpp @@ -8,14 +8,13 @@ static const int HOLD_TICKS = 1000; -confirmState::confirmState(const std::string &message, sys::taskFunction onConfirmation, std::shared_ptr args) : m_Message(message), m_OnConfirmation(onConfirmation), m_Args(args) -{ - // Init timer - m_HoldTimer = std::make_unique(HOLD_TICKS); - // Get Text for yes and no - m_Yes = ui::strings::getString(LANG_DIALOG_YES, 0); - m_No = ui::strings::getString(LANG_DIALOG_NO, 0); -} +confirmState::confirmState(const std::string &message, sys::taskFunction onConfirmation, std::shared_ptr args) : +m_Message(message), +m_Yes(ui::strings::getString(LANG_DIALOG_YES, 0)), +m_No(ui::strings::getString(LANG_DIALOG_NO, 0)), +m_HoldTimer(std::make_unique(HOLD_TICKS)), +m_OnConfirmation(onConfirmation), +m_Args(args) { } confirmState::~confirmState() { } diff --git a/src/appStates/mainMenuState.cpp b/src/appStates/mainMenuState.cpp old mode 100644 new mode 100755 index 8d925a6..6ee642e --- a/src/appStates/mainMenuState.cpp +++ b/src/appStates/mainMenuState.cpp @@ -1,3 +1,4 @@ +#include #include "jksv.hpp" #include "appStates/mainMenuState.hpp" #include "appStates/titleSelectionState.hpp" @@ -10,26 +11,34 @@ #include "stringUtil.hpp" #include "log.hpp" +// Main menu coordinates and dimensions +static const int MAIN_MENU_X = 50; +static const int MAIN_MENU_Y = 16; +static const int MAIN_MENU_SCROLL_LENGTH = 1; + +// Texture names +static const char *MAIN_MENU_RENDER_TARGET = "mainMenuRenderTarget"; +static const char *MAIN_MENU_SETTINGS = "mainMenuSettings"; +static const char *MAIN_MENU_EXTRAS = "mainMenuExtras"; + // Tasks -static void backupAllUserSaves(sys::task *task, std::shared_ptr args) +static void backupAllUserSaves(void *in) { } -mainMenuState::mainMenuState(void) +mainMenuState::mainMenuState(void) : +m_MainControlGuide(ui::strings::getString(LANG_USER_GUIDE, 0)), +m_MainControlGuideX(1220 - graphics::systemFont::getTextWidth(m_MainControlGuide, 18)), +m_MainMenu(std::make_unique(MAIN_MENU_X, MAIN_MENU_Y, MAIN_MENU_SCROLL_LENGTH)) { - // Setup control guide - m_MainControlGuide = ui::strings::getString(LANG_USER_GUIDE, 0); - m_MainControlGuideX = 1220 - graphics::systemFont::getTextWidth(m_MainControlGuide, 18); - // Render target - m_RenderTarget = graphics::textureCreate("mainMenuRenderTarget", 200, 555, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); + m_RenderTarget = graphics::textureCreate(MAIN_MENU_RENDER_TARGET, 200, 555, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); // Load gradient for behind menu m_MenuBackgroundTexture = graphics::textureLoadFromFile(TEXTURE_MENU_BACKGROUND, "romfs:/img/menu/backgroundDark.png"); // Setup menu - m_MainMenu = std::make_unique(50, 16, 1); m_UserEnd = data::getTotalUsers(); for (int i = 0; i < m_UserEnd; i++) { @@ -40,8 +49,8 @@ mainMenuState::mainMenuState(void) // Settings & extras std::string settingsString = ui::strings::getString(LANG_MAIN_MENU_SETTINGS, 0); std::string extrasString = ui::strings::getString(LANG_MAIN_MENU_EXTRAS, 0); - m_MainMenu->addOpt(graphics::createIcon("mainMenuSettings", settingsString, 42)); - m_MainMenu->addOpt(graphics::createIcon("mainMenuExtras", extrasString, 42)); + m_MainMenu->addOpt(graphics::createIcon(MAIN_MENU_SETTINGS, settingsString, 42)); + m_MainMenu->addOpt(graphics::createIcon(MAIN_MENU_EXTRAS, extrasString, 42)); } mainMenuState::~mainMenuState() {} diff --git a/src/appStates/progressState.cpp b/src/appStates/progressState.cpp old mode 100644 new mode 100755 index a4e8a20..3391d14 --- a/src/appStates/progressState.cpp +++ b/src/appStates/progressState.cpp @@ -1,8 +1,8 @@ #include "appStates/progressState.hpp" -progressState::progressState(sys::taskFunction function, std::shared_ptr args, const uint64_t &maxValue) +progressState::progressState(sys::taskFunction threadFunction, std::shared_ptr args, const uint64_t &maxValue) { - m_Task = std::make_unique(function, args); + m_Task = std::make_unique(threadFunction, args); m_ProgressBar = std::make_unique(maxValue); } diff --git a/src/appStates/taskState.cpp b/src/appStates/taskState.cpp old mode 100644 new mode 100755 index dbc0cf8..701015e --- a/src/appStates/taskState.cpp +++ b/src/appStates/taskState.cpp @@ -1,10 +1,20 @@ #include "appStates/taskState.hpp" #include "graphics/graphics.hpp" +#include "log.hpp" -taskState::taskState(sys::taskFunction function, std::shared_ptr args) +// Time in ticks before changing glyph frames +static const int GLYPH_CHANGE_TICKS = 50; + +// These are the actual glyphs +static const std::string s_LoadGlyphArray[8] = { - m_Task = std::make_unique(function, args); -} + "\ue020", "\ue021", "\ue022", "\ue023", + "\ue024", "\ue025", "\ue026", "\ue027" +}; + +taskState::taskState(sys::taskFunction threadFunction, std::shared_ptr args) : +m_Task(std::make_unique(threadFunction, args)), +m_LoadingGlyphTimer(std::make_unique(GLYPH_CHANGE_TICKS)) { } taskState::~taskState() { } @@ -21,8 +31,32 @@ void taskState::render(void) // Get thread status and calculate centered text std::string taskStatus = m_Task->getThreadStatus(); int taskStatusX = 640 - (graphics::systemFont::getTextWidth(taskStatus, 24) / 2); + + // Render glyph in bottom left corner + renderLoadingGlyph(); // Dim background and render text to screen graphics::renderRect(NULL, 0, 0, 1280, 720, COLOR_DIM_BACKGROUND); graphics::systemFont::renderText(taskStatus, NULL, taskStatusX, 348, 24, COLOR_WHITE); +} + +void taskState::renderLoadingGlyph(void) +{ + // If timer is triggered, update glyph frame + if(m_LoadingGlyphTimer->triggered() && ++m_GlyphFrame == 8) + { + m_GlyphFrame = 0; + } + + // If true, we're adding, false subtracting + if(m_ColorModifier && (m_LoadingGlyphColorMod += 6) >= 0x72) + { + m_ColorModifier = false; + } + else if(m_ColorModifier && (m_LoadingGlyphColorMod -= 3) <= 0x00) + { + m_ColorModifier = true; + } + + graphics::systemFont::renderText(s_LoadGlyphArray[m_GlyphFrame], NULL, 56, 673, 32, createColor(0x00, (0x88 + m_LoadingGlyphColorMod), (0xC5 + (m_LoadingGlyphColorMod / 2)), 0xFF)); } \ No newline at end of file diff --git a/src/appStates/titleOptionState.cpp b/src/appStates/titleOptionState.cpp old mode 100644 new mode 100755 index a946076..217d6c7 --- a/src/appStates/titleOptionState.cpp +++ b/src/appStates/titleOptionState.cpp @@ -1,4 +1,5 @@ #include +#include #include "appStates/titleOptionState.hpp" #include "appStates/confirmState.hpp" #include "data/data.hpp" @@ -6,9 +7,21 @@ #include "ui/ui.hpp" #include "system/task.hpp" #include "system/input.hpp" +#include "stringUtil.hpp" #include "jksv.hpp" #include "log.hpp" +// Texture/target names +const char *PANEL_RENDER_TARGET_NAME = "titleOptionPanel"; + +// Dimensions and coordinates for panel and menu +static const int PANEL_WIDTH = 410; +static const int MENU_X = 10; +static const int MENU_Y = 32; +static const int MENU_WIDTH = 390; +static const int MENU_FONT_SIZE = 20; +static const int MENU_SCROLL_LENGTH = 7; + enum { TITLE_INFO, @@ -39,28 +52,28 @@ void resetSaveData(sys::task *task, std::shared_ptr args) task->finished(); return; } - logger::log("Arg check"); + + // Error code for filesystem + std::error_code errorCode; // Set status task->setThreadStatus(ui::strings::getString(LANG_THREAD_RESET_SAVE_DATA, 0)); - logger::log("Set status"); // Cast args std::shared_ptr argsIn = std::static_pointer_cast(args); - logger::log("Cast pointer"); if(fs::mountSaveData(argsIn->currentUserSaveInfo->getSaveDataInfo())) { - logger::log("Save mounted"); - // This does everything this needs - fs::eraseSaveData(); - logger::log("Erase Save Data"); + // Erase save data in container + // To do: remove_all keeps failing if the folder has sub dirs. Maybe I should just stick with my own? + std::filesystem::remove_all(fs::DEFAULT_SAVE_MOUNT_DEVICE, errorCode); + // Commit changes + fs::commitSaveData(); // Close fs::unmountSaveData(); - logger::log("unmount"); // Display success - ui::popMessage::newMessage(ui::strings::getString(LANG_SAVEDATA_RESET_SUCCESS, 0), ui::popMessage::POPMESSAGE_DEFAULT_TICKS); - logger::log("POP"); + std::string successMessage = stringUtil::getFormattedString(ui::strings::getCString(LANG_SAVEDATA_RESET_SUCCESS, 0), argsIn->currentTitleInfo->getTitle().c_str()); + ui::popMessage::newMessage(successMessage, ui::popMessage::POPMESSAGE_DEFAULT_TICKS); } else { @@ -71,12 +84,13 @@ void resetSaveData(sys::task *task, std::shared_ptr args) task->finished(); } -titleOptionState::titleOptionState(data::user *currentUser, data::userSaveInfo *currentUserSaveInfo, data::titleInfo *currentTitleInfo) : m_CurrentUser(currentUser), m_CurrentUserSaveInfo(currentUserSaveInfo), m_CurrentTitleInfo(currentTitleInfo) +titleOptionState::titleOptionState(data::user *currentUser, data::userSaveInfo *currentUserSaveInfo, data::titleInfo *currentTitleInfo) : +m_CurrentUser(currentUser), +m_CurrentUserSaveInfo(currentUserSaveInfo), +m_CurrentTitleInfo(currentTitleInfo), +m_SlidePanel(std::make_unique(PANEL_RENDER_TARGET_NAME, PANEL_WIDTH, ui::PANEL_SIDE_RIGHT)), +m_OptionsMenu(std::make_unique(MENU_X, MENU_Y, MENU_WIDTH, MENU_FONT_SIZE, MENU_SCROLL_LENGTH)) { - // Slide out panel - m_SlidePanel = std::make_unique("titleOptionPanel", 410, ui::PANEL_SIDE_RIGHT); - // Menu - m_OptionsMenu = std::make_unique(10, 32, 390, 20, 7); // Setup menu for(int i = 0; i < 9; i++) { @@ -105,6 +119,7 @@ void titleOptionState::update(void) // Data to send std::shared_ptr args = std::make_shared(); args->currentUserSaveInfo = m_CurrentUserSaveInfo; + args->currentTitleInfo = m_CurrentTitleInfo; // Confirm state std::unique_ptr confirmReset = std::make_unique(confirmationString, resetSaveData, args); @@ -115,10 +130,10 @@ void titleOptionState::update(void) break; default: - { - ui::popMessage::newMessage("Not implemented yet...", ui::popMessage::POPMESSAGE_DEFAULT_TICKS); - } - break; + { + ui::popMessage::newMessage("Not implemented yet...", ui::popMessage::POPMESSAGE_DEFAULT_TICKS); + } + break; } } else if(sys::input::buttonDown(HidNpadButton_B)) diff --git a/src/appStates/titleSelectionState.cpp b/src/appStates/titleSelectionState.cpp old mode 100644 new mode 100755 index 21db7c6..c0bfa74 --- a/src/appStates/titleSelectionState.cpp +++ b/src/appStates/titleSelectionState.cpp @@ -9,18 +9,20 @@ #include "log.hpp" #include "jksv.hpp" +// Texture names +const char *TITLE_SELECT_RENDER_TARGET = "titleSelectionRenderTarget"; -titleSelectionState::titleSelectionState(data::user *currentUser) : m_CurrentUser(currentUser) +// Render target dimensions +static const int RENDER_TARGET_WIDTH = 1080; +static const int RENDER_TARGET_HEIGHT = 555; + +titleSelectionState::titleSelectionState(data::user *currentUser) : +m_CurrentUser(currentUser), +m_TitleSelection(std::make_unique(m_CurrentUser)), +m_TitleControlGuide(ui::strings::getString(LANG_TITLE_GUIDE, 0)) { - // Setup control string - m_TitleControlGuide = ui::strings::getString(LANG_TITLE_GUIDE, 0); - m_TitleControlGuideX = 1220 - graphics::systemFont::getTextWidth(m_TitleControlGuide, 18); - // Render target to render everything too - m_RenderTarget = graphics::textureCreate("titleSelectionRenderTarget", 1080, 555, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); - - // Icon - m_TitleSelection = std::make_unique(m_CurrentUser); + m_RenderTarget = graphics::textureCreate(TITLE_SELECT_RENDER_TARGET, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET); } titleSelectionState::~titleSelectionState() {} diff --git a/src/config.cpp b/src/config.cpp old mode 100644 new mode 100755 diff --git a/src/data/data.cpp b/src/data/data.cpp old mode 100644 new mode 100755 diff --git a/src/data/titleInfo.cpp b/src/data/titleInfo.cpp old mode 100644 new mode 100755 diff --git a/src/data/user.cpp b/src/data/user.cpp old mode 100644 new mode 100755 diff --git a/src/data/userSaveInfo.cpp b/src/data/userSaveInfo.cpp old mode 100644 new mode 100755 diff --git a/src/filesystem/directoryListing.cpp b/src/filesystem/directoryListing.cpp old mode 100644 new mode 100755 index 659c849..bb6949b --- a/src/filesystem/directoryListing.cpp +++ b/src/filesystem/directoryListing.cpp @@ -14,9 +14,12 @@ void fs::directoryListing::loadListing(void) // Clear vector first JIC reload m_DirectoryList.clear(); - for(const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(m_DirectoryPath)) + // Error code + std::error_code errorCode; + + for(const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(m_DirectoryPath, errorCode)) { - m_DirectoryList.push_back(entry.path().string()); + m_DirectoryList.push_back(entry); } } @@ -27,26 +30,30 @@ int fs::directoryListing::getListingCount(void) const bool fs::directoryListing::itemAtIsDirectory(const int &index) const { - return std::filesystem::is_directory(m_DirectoryList.at(index)); + return m_DirectoryList.at(index).is_directory(); } std::string fs::directoryListing::getFullPathToItemAt(const int &index) const { - return m_DirectoryList.at(index); + return m_DirectoryList.at(index).path().string(); } std::string fs::directoryListing::getItemAt(const int &index) const { - size_t lastSlash = m_DirectoryList.at(index).find_last_of('/') + 1; - return m_DirectoryList.at(index).substr(lastSlash, m_DirectoryList.at(index).npos); + // Get string first + std::string itemString = m_DirectoryList.at(index).path().string(); + // Find last slash + size_t lastSlash = itemString.find_last_of('/') + 1; + // Return sub string + return itemString.substr(lastSlash, itemString.npos); } std::string fs::directoryListing::getFilenameAt(const int &index) const { - return stringUtil::getFilenameFromString(m_DirectoryList.at(index)); + return stringUtil::getFilenameFromString(m_DirectoryList.at(index).path().string()); } std::string fs::directoryListing::getExtensionAt(const int &index) const { - return stringUtil::getExtensionFromString(m_DirectoryList.at(index)); + return stringUtil::getExtensionFromString(m_DirectoryList.at(index).path().string()); } \ No newline at end of file diff --git a/src/filesystem/fileParser.cpp b/src/filesystem/fileParser.cpp old mode 100644 new mode 100755 diff --git a/src/filesystem/filesystem.cpp b/src/filesystem/filesystem.cpp old mode 100644 new mode 100755 index a21def5..a929fa8 --- a/src/filesystem/filesystem.cpp +++ b/src/filesystem/filesystem.cpp @@ -100,13 +100,13 @@ void fs::unmountSaveData(void) void fs::commitSaveData(void) { - fsdevCommitDevice(DEFAULT_SAVE_MOUNT_DEVICE); + Result commitError = fsdevCommitDevice(fs::DEFAULT_SAVE_MOUNT_DEVICE); + if(R_SUCCEEDED(commitError)) + { + logger::log("Commit succeeded."); + } + else + { + logger::log("Commit failed. %X", commitError); + } } - -void fs::eraseSaveData(void) -{ - // Delete root of save container - fs::io::deleteDirectoryRecursively(fs::DEFAULT_SAVE_MOUNT_DEVICE); - // Commit changes - fs::commitSaveData(); -} \ No newline at end of file diff --git a/src/filesystem/io.cpp b/src/filesystem/io.cpp old mode 100644 new mode 100755 index 92e7adc..5a50a10 --- a/src/filesystem/io.cpp +++ b/src/filesystem/io.cpp @@ -101,8 +101,15 @@ void fs::io::writeThreadFunction(const std::string &destination, std::shared_ptr bytesWritten += localBuffer.size(); journalCount += localBuffer.size(); } + + // Close destination first + destinationFile.close(); + // One last commit just in case - fs::commitSaveData(); + if(sharedStruct->commitWrite) + { + fs::commitSaveData(); + } } int fs::io::getFileSize(const std::string &filePath) @@ -211,39 +218,10 @@ void fs::io::copyDirectoryCommit(const std::string &source, const std::string &d std::string fullSource = source + list.getItemAt(i); std::string fullDestination = destination + list.getItemAt(i); + logger::log("%s, %s", fullSource.c_str(), fullDestination.c_str()); + // Copy it and commit it to save fs::io::copyFileCommit(fullSource, fullDestination, journalSize); } } } - -void fs::io::deleteDirectoryRecursively(const std::string &target) -{ - // Get directory listing - fs::directoryListing listing(target); - // Get item count - int listingCount = listing.getListingCount(); - // Error code to stop from throwing exceptions on failure to delete. - std::error_code errorCode; - - // Loop through - for(int i = 0; i < listingCount; i++) - { - if(listing.itemAtIsDirectory(i)) - { - // New target path - std::string newTarget = listing.getFullPathToItemAt(i) + "/"; - // Call self to continue - fs::io::deleteDirectoryRecursively(newTarget); - // Delete directory - std::filesystem::remove(listing.getFullPathToItemAt(i), errorCode); - } - else - { - // Just delete file - std::filesystem::remove(listing.getFullPathToItemAt(i), errorCode); - } - } - // Finally delete last directory - std::filesystem::remove(target, errorCode); -} \ No newline at end of file diff --git a/src/filesystem/zip.cpp b/src/filesystem/zip.cpp old mode 100644 new mode 100755 diff --git a/src/graphics/graphics.cpp b/src/graphics/graphics.cpp old mode 100644 new mode 100755 diff --git a/src/graphics/systemFont.cpp b/src/graphics/systemFont.cpp old mode 100644 new mode 100755 diff --git a/src/jksv.cpp b/src/jksv.cpp old mode 100644 new mode 100755 diff --git a/src/log.cpp b/src/log.cpp old mode 100644 new mode 100755 diff --git a/src/main.cpp b/src/main.cpp old mode 100644 new mode 100755 diff --git a/src/stringUtil.cpp b/src/stringUtil.cpp old mode 100644 new mode 100755 diff --git a/src/system/input.cpp b/src/system/input.cpp old mode 100644 new mode 100755 index 99da27b..af4e978 --- a/src/system/input.cpp +++ b/src/system/input.cpp @@ -35,6 +35,21 @@ bool sys::input::buttonReleased(const HidNpadButton &button) return padGetButtonsUp(&s_PadState) & button; } +uint64_t sys::input::buttonsDown(void) +{ + return padGetButtonsDown(&s_PadState); +} + +uint64_t sys::input::buttonsHeld(void) +{ + return padGetButtons(&s_PadState); +} + +uint64_t sys::input::buttonsReleased(void) +{ + return padGetButtonsUp(&s_PadState); +} + std::string sys::input::getString(const std::string &defaultText, const std::string &headerText, const size_t &maximumLength) { // Keyboard config diff --git a/src/system/task.cpp b/src/system/task.cpp old mode 100644 new mode 100755 index 4a831d8..97ebf81 --- a/src/system/task.cpp +++ b/src/system/task.cpp @@ -1,33 +1,41 @@ #include "system/task.hpp" +#include "log.hpp" -#define THREAD_STACK_SIZE 0x400000 -#define THREAD_PRIORITY 0x2B -#define THREAD_CPU_ID 1 +static const size_t THREAD_STACK_SIZE = 0x80000; +static const int THREAD_PRIORITY = 0x2B; +static const int THREAD_CPU_ID = 1; -sys::task::task(taskFunction function, std::shared_ptr args) +sys::task::task(sys::taskFunction threadFunction, std::shared_ptr args) { - m_Thread = std::make_unique(function, this, args); + // Spawn thread + m_Thread = std::make_unique(threadFunction, this, args); + + // Let's just hope it's running + m_IsRunning = true; } sys::task::~task() { + // Wait for thread to finish. m_Thread->join(); } std::string sys::task::getThreadStatus(void) { // Like this to prevent corruption - std::string status; + std::string threadStatus; + m_StatusMutex.lock(); - status.assign(m_ThreadStatus); + threadStatus = m_ThreadStatus; m_StatusMutex.unlock(); - return status; + + return threadStatus; } void sys::task::setThreadStatus(const std::string &newStatus) { m_StatusMutex.lock(); - m_ThreadStatus.assign(newStatus); + m_ThreadStatus = newStatus; m_StatusMutex.unlock(); } @@ -40,9 +48,11 @@ void sys::task::finished(void) bool sys::task::isRunning(void) { - bool running = false; + bool threadRunning = false; + m_RunningMutex.lock(); - running = m_IsRunning; + threadRunning = m_IsRunning; m_RunningMutex.unlock(); - return running; + + return threadRunning; } \ No newline at end of file diff --git a/src/system/timer.cpp b/src/system/timer.cpp old mode 100644 new mode 100755 diff --git a/src/ui/iconMenu.cpp b/src/ui/iconMenu.cpp old mode 100644 new mode 100755 diff --git a/src/ui/menu.cpp b/src/ui/menu.cpp old mode 100644 new mode 100755 index c5d9e7e..10a994f --- a/src/ui/menu.cpp +++ b/src/ui/menu.cpp @@ -103,6 +103,11 @@ int ui::menu::getSelected(void) const return m_Selected; } +void ui::menu::setSelected(const int &newSelected) +{ + m_Selected = newSelected; +} + void ui::menu::clearMenu(void) { m_MenuOptions.clear(); diff --git a/src/ui/popMessage.cpp b/src/ui/popMessage.cpp old mode 100644 new mode 100755 diff --git a/src/ui/progressBar.cpp b/src/ui/progressBar.cpp old mode 100644 new mode 100755 diff --git a/src/ui/slidePanel.cpp b/src/ui/slidePanel.cpp old mode 100644 new mode 100755 diff --git a/src/ui/strings.cpp b/src/ui/strings.cpp old mode 100644 new mode 100755 diff --git a/src/ui/titleSelection.cpp b/src/ui/titleSelection.cpp old mode 100644 new mode 100755 diff --git a/src/ui/titleTile.cpp b/src/ui/titleTile.cpp old mode 100644 new mode 100755 diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp old mode 100644 new mode 100755