Fixes and revisions

This commit is contained in:
J-D-K 2024-06-04 13:36:04 -04:00
parent f30faad231
commit e7210002e9
121 changed files with 267 additions and 157 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
GD_INSTRUCTIONS.MD Normal file → Executable file
View File

0
JKSV.lst Normal file → Executable file
View File

0
LICENSE Normal file → Executable file
View File

0
Makefile Normal file → Executable file
View File

0
README.MD Normal file → Executable file
View File

0
icon.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

0
iconAssets/JKSV_icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

0
iconAssets/JKSV_icon.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

0
inc/appStates/appState.hpp Normal file → Executable file
View File

4
inc/appStates/backupMenuState.hpp Normal file → Executable file
View File

@ -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<ui::slidePanel> m_BackupPanel;
// Width of panel/text
int m_PanelWidth;
// Slide in/out panel
std::unique_ptr<ui::slidePanel> m_BackupPanel;
// Folder listing
std::unique_ptr<fs::directoryListing> m_BackupListing;
// Listing to make sure there is a save

1
inc/appStates/confirmState.hpp Normal file → Executable file
View File

@ -1,6 +1,7 @@
#pragma once
#include <memory>
#include <string>
#include <switch.h>
#include "appStates/appState.hpp"
#include "system/timer.hpp"
#include "system/task.hpp"

0
inc/appStates/mainMenuState.hpp Normal file → Executable file
View File

2
inc/appStates/progressState.hpp Normal file → Executable file
View File

@ -10,7 +10,7 @@
class progressState : public appState
{
public:
progressState(sys::taskFunction function, std::shared_ptr<sys::progressArgs> args, const uint64_t &maxValue);
progressState(sys::taskFunction threadFunction, std::shared_ptr<sys::progressArgs> args, const uint64_t &maxValue);
~progressState();
void update(void);
void render(void);

17
inc/appStates/taskState.hpp Normal file → Executable file
View File

@ -1,17 +1,32 @@
#pragma once
#include <memory>
#include <switch.h>
#include "appStates/appState.hpp"
#include "system/timer.hpp"
#include "system/task.hpp"
class taskState : public appState
{
public:
taskState(sys::taskFunction function, std::shared_ptr<sys::taskArgs> args);
taskState(sys::taskFunction threadFunction, std::shared_ptr<sys::taskArgs> 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<sys::task> m_Task;
// What frame of the glyph array we're on
int m_GlyphFrame = 0;
// Timer for updating loading glyph
std::unique_ptr<sys::timer> m_LoadingGlyphTimer;
// Bool for adding subtracting from color modifier
bool m_ColorModifier = true;
// Color modification for glyph
uint8_t m_LoadingGlyphColorMod = 0x00;
};

0
inc/appStates/titleOptionState.hpp Normal file → Executable file
View File

0
inc/appStates/titleSelectionState.hpp Normal file → Executable file
View File

0
inc/config.hpp Normal file → Executable file
View File

0
inc/data/data.hpp Normal file → Executable file
View File

0
inc/data/titleInfo.hpp Normal file → Executable file
View File

0
inc/data/user.hpp Normal file → Executable file
View File

0
inc/data/userSaveInfo.hpp Normal file → Executable file
View File

3
inc/filesystem/directoryListing.hpp Normal file → Executable file
View File

@ -1,4 +1,5 @@
#pragma once
#include <filesystem>
#include <string>
#include <vector>
@ -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<std::string> m_DirectoryList;
std::vector<std::filesystem::directory_entry> m_DirectoryList;
};
}

0
inc/filesystem/fileParser.hpp Normal file → Executable file
View File

2
inc/filesystem/filesystem.hpp Normal file → Executable file
View File

@ -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);
}

2
inc/filesystem/io.hpp Normal file → Executable file
View File

@ -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<threadStruct> sharedStruct);
void writeThreadFunction(const std::string &destination, std::shared_ptr<threadStruct> sharedStruct);

0
inc/filesystem/zip.hpp Normal file → Executable file
View File

0
inc/graphics/colors.hpp Normal file → Executable file
View File

0
inc/graphics/graphics.hpp Normal file → Executable file
View File

0
inc/graphics/systemFont.hpp Normal file → Executable file
View File

0
inc/graphics/textureNames.hpp Normal file → Executable file
View File

0
inc/jksv.hpp Normal file → Executable file
View File

0
inc/log.hpp Normal file → Executable file
View File

0
inc/stringUtil.hpp Normal file → Executable file
View File

4
inc/system/input.hpp Normal file → Executable file
View File

@ -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);
}

0
inc/system/progressArgs.hpp Normal file → Executable file
View File

12
inc/system/task.hpp Normal file → Executable file
View File

@ -12,15 +12,15 @@ namespace sys
{
class task;
using taskFunction = std::function<void(task *, std::shared_ptr<sys::taskArgs>)>;
using taskFunction = std::function<void(sys::task *, std::shared_ptr<sys::taskArgs>)>;
class task
{
public:
// taskFunction is
task(taskFunction function, std::shared_ptr<taskArgs> args);
// taskFunction is
task(sys::taskFunction threadFunction, std::shared_ptr<taskArgs> 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<std::thread> m_Thread;
// Status string
std::string m_ThreadStatus;

0
inc/system/taskArgs.hpp Normal file → Executable file
View File

0
inc/system/timer.hpp Normal file → Executable file
View File

0
inc/ui/iconMenu.hpp Normal file → Executable file
View File

2
inc/ui/menu.hpp Normal file → Executable file
View File

@ -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);

0
inc/ui/popMessage.hpp Normal file → Executable file
View File

0
inc/ui/progressBar.hpp Normal file → Executable file
View File

0
inc/ui/slidePanel.hpp Normal file → Executable file
View File

0
inc/ui/strings.hpp Normal file → Executable file
View File

0
inc/ui/titleSelection.hpp Normal file → Executable file
View File

0
inc/ui/titleTile.hpp Normal file → Executable file
View File

0
inc/ui/ui.hpp Normal file → Executable file
View File

0
romfs/icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

0
romfs/img/dialogDark/dialogBottomLeft.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

0
romfs/img/dialogDark/dialogBottomRight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 267 B

0
romfs/img/dialogDark/dialogTopLeft.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

0
romfs/img/dialogDark/dialogTopRight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

0
romfs/img/icn/icnDefault.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

0
romfs/img/icn/icnDrk.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
romfs/img/icn/icon.msk Normal file → Executable file
View File

0
romfs/img/icn/iconWhite.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

0
romfs/img/menu/backgroundDark.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 158 KiB

0
romfs/img/menu/backgroundLight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

0
romfs/img/menu/selectionBottomLeft.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

0
romfs/img/menu/selectionBottomRight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

0
romfs/img/menu/selectionTopLeft.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

0
romfs/img/menu/selectionTopRight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

0
romfs/img/tboxLght/progBarCoverLeftLight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 257 B

0
romfs/img/tboxLght/progBarCoverRightLight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 253 B

0
romfs/img/tboxLght/tboxCornerBotLeft.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 273 B

0
romfs/img/tboxLght/tboxCornerBotRight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 266 B

0
romfs/img/tboxLght/tboxCornerTopLeft.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 279 B

0
romfs/img/tboxLght/tboxCornerTopRight.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 285 B

After

Width:  |  Height:  |  Size: 285 B

0
romfs/lang/de.txt Normal file → Executable file
View File

0
romfs/lang/en-GB.txt Normal file → Executable file
View File

0
romfs/lang/en-US.txt Normal file → Executable file
View File

0
romfs/lang/es-419.txt Normal file → Executable file
View File

0
romfs/lang/es.txt Normal file → Executable file
View File

0
romfs/lang/fr-CA.txt Normal file → Executable file
View File

0
romfs/lang/fr.txt Normal file → Executable file
View File

0
romfs/lang/it.txt Normal file → Executable file
View File

0
romfs/lang/ja.txt Normal file → Executable file
View File

0
romfs/lang/ko.txt Normal file → Executable file
View File

0
romfs/lang/nl.txt Normal file → Executable file
View File

0
romfs/lang/pt-BR.txt Normal file → Executable file
View File

0
romfs/lang/pt.txt Normal file → Executable file
View File

0
romfs/lang/ru.txt Normal file → Executable file
View File

0
romfs/lang/zh-CN.txt Normal file → Executable file
View File

0
romfs/lang/zh-TW.txt Normal file → Executable file
View File

0
src/appStates/appState.cpp Normal file → Executable file
View File

77
src/appStates/backupMenuState.cpp Normal file → Executable file
View File

@ -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<sys::taskArgs> args)
static void createNewBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
{
// Make sure we weren't passed nullptr
if (args == nullptr)
@ -98,7 +106,7 @@ void createNewBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
}
// Overwrites a backup already on SD
void overwriteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
static void overwriteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
{
// Bail if no args present
if (args == nullptr)
@ -107,6 +115,9 @@ void overwriteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
return;
}
// Error code for filesystem
std::error_code errorCode;
// Set status, cast args to type
task->setThreadStatus("REPLACE THIS LATER");
std::shared_ptr<pathArgs> argsIn = std::static_pointer_cast<pathArgs>(args);
@ -119,12 +130,12 @@ void overwriteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> 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<sys::taskArgs> 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<sys::taskArgs> args)
static void restoreBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
{
if (args == nullptr)
{
@ -149,6 +160,9 @@ void restoreBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
return;
}
// Error code for later
std::error_code errorCode;
// Set status, cast args
task->setThreadStatus("REPLACE THIS LATER");
std::shared_ptr<pathArgs> argsIn = std::static_pointer_cast<pathArgs>(args);
@ -166,7 +180,7 @@ void restoreBackup(sys::task *task, std::shared_ptr<sys::taskArgs> 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<sys::taskArgs> args)
// Close zip
unzClose(unzip);
}
task->finished();
}
void deleteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
static void deleteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
{
if (args == nullptr)
{
@ -193,6 +209,9 @@ void deleteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> 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<sys::taskArgs> 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<sys::taskArgs> 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<ui::slidePanel>(BACKUP_PANEL_NAME, m_PanelWidth + 64, ui::slidePanelSide::PANEL_SIDE_RIGHT)),
m_BackupListing(std::make_unique<fs::directoryListing>(m_OutputBasePath)),
m_SaveListing(std::make_unique<fs::directoryListing>(fs::DEFAULT_SAVE_MOUNT_DEVICE)),
m_BackupMenu(std::make_unique<ui::menu>(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<ui::slidePanel>("backupMenuPanel", m_PanelWidth + 64, ui::slidePanelSide::PANEL_SIDE_RIGHT);
// The menu of backups
m_BackupMenu = std::make_unique<ui::menu>(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<fs::directoryListing>(m_OutputBasePath);
// Directory listing of save
m_SaveListing = std::make_unique<fs::directoryListing>(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));

15
src/appStates/confirmState.cpp Normal file → Executable file
View File

@ -8,14 +8,13 @@
static const int HOLD_TICKS = 1000;
confirmState::confirmState(const std::string &message, sys::taskFunction onConfirmation, std::shared_ptr<sys::taskArgs> args) : m_Message(message), m_OnConfirmation(onConfirmation), m_Args(args)
{
// Init timer
m_HoldTimer = std::make_unique<sys::timer>(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<sys::taskArgs> 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<sys::timer>(HOLD_TICKS)),
m_OnConfirmation(onConfirmation),
m_Args(args) { }
confirmState::~confirmState() { }

29
src/appStates/mainMenuState.cpp Normal file → Executable file
View File

@ -1,3 +1,4 @@
#include <chrono>
#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<sys::taskArgs> 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<ui::iconMenu>(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<ui::iconMenu>(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() {}

4
src/appStates/progressState.cpp Normal file → Executable file
View File

@ -1,8 +1,8 @@
#include "appStates/progressState.hpp"
progressState::progressState(sys::taskFunction function, std::shared_ptr<sys::progressArgs> args, const uint64_t &maxValue)
progressState::progressState(sys::taskFunction threadFunction, std::shared_ptr<sys::progressArgs> args, const uint64_t &maxValue)
{
m_Task = std::make_unique<sys::task>(function, args);
m_Task = std::make_unique<sys::task>(threadFunction, args);
m_ProgressBar = std::make_unique<ui::progressBar>(maxValue);
}

40
src/appStates/taskState.cpp Normal file → Executable file
View File

@ -1,10 +1,20 @@
#include "appStates/taskState.hpp"
#include "graphics/graphics.hpp"
#include "log.hpp"
taskState::taskState(sys::taskFunction function, std::shared_ptr<sys::taskArgs> 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<sys::task>(function, args);
}
"\ue020", "\ue021", "\ue022", "\ue023",
"\ue024", "\ue025", "\ue026", "\ue027"
};
taskState::taskState(sys::taskFunction threadFunction, std::shared_ptr<sys::taskArgs> args) :
m_Task(std::make_unique<sys::task>(threadFunction, args)),
m_LoadingGlyphTimer(std::make_unique<sys::timer>(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));
}

53
src/appStates/titleOptionState.cpp Normal file → Executable file
View File

@ -1,4 +1,5 @@
#include <memory>
#include <filesystem>
#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<sys::taskArgs> 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<titleOptsArgs> argsIn = std::static_pointer_cast<titleOptsArgs>(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<sys::taskArgs> 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<ui::slidePanel>(PANEL_RENDER_TARGET_NAME, PANEL_WIDTH, ui::PANEL_SIDE_RIGHT)),
m_OptionsMenu(std::make_unique<ui::menu>(MENU_X, MENU_Y, MENU_WIDTH, MENU_FONT_SIZE, MENU_SCROLL_LENGTH))
{
// Slide out panel
m_SlidePanel = std::make_unique<ui::slidePanel>("titleOptionPanel", 410, ui::PANEL_SIDE_RIGHT);
// Menu
m_OptionsMenu = std::make_unique<ui::menu>(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<titleOptsArgs> args = std::make_shared<titleOptsArgs>();
args->currentUserSaveInfo = m_CurrentUserSaveInfo;
args->currentTitleInfo = m_CurrentTitleInfo;
// Confirm state
std::unique_ptr<appState> confirmReset = std::make_unique<confirmState>(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))

20
src/appStates/titleSelectionState.cpp Normal file → Executable file
View File

@ -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<ui::titleSelection>(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<ui::titleSelection>(m_CurrentUser);
m_RenderTarget = graphics::textureCreate(TITLE_SELECT_RENDER_TARGET, RENDER_TARGET_WIDTH, RENDER_TARGET_HEIGHT, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET);
}
titleSelectionState::~titleSelectionState() {}

0
src/config.cpp Normal file → Executable file
View File

0
src/data/data.cpp Normal file → Executable file
View File

0
src/data/titleInfo.cpp Normal file → Executable file
View File

0
src/data/user.cpp Normal file → Executable file
View File

0
src/data/userSaveInfo.cpp Normal file → Executable file
View File

23
src/filesystem/directoryListing.cpp Normal file → Executable file
View File

@ -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());
}

0
src/filesystem/fileParser.cpp Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More