mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
First(?) readme update, thread race fix
This commit is contained in:
parent
093b1bc178
commit
2fbfe5b62e
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
build/
|
||||
.vscode/
|
||||
*.cbp
|
||||
*.layout
|
||||
2
Makefile
2
Makefile
|
|
@ -38,7 +38,7 @@ INCLUDES := inc inc/ui inc/fs
|
|||
EXEFS_SRC := exefs_src
|
||||
APP_TITLE := JKSV
|
||||
APP_AUTHOR := JK
|
||||
APP_VERSION := 10.12.2021
|
||||
APP_VERSION := 11.15.2021
|
||||
ROMFS := romfs
|
||||
ICON := icon.jpg
|
||||
|
||||
|
|
|
|||
91
README.MD
91
README.MD
|
|
@ -1,54 +1,66 @@
|
|||
# JKSV
|
||||
|
||||
Data Dump/Restore tool for Switch.
|
||||
JK's Save Manager Switch Edition.
|
||||
|
||||
<img src="https://i.imgur.com/yLcTPzt.jpg"/>
|
||||
|
||||
## Info
|
||||
JKSV on Switch started as a small project/port to test some things and get familiar with libnx. A list of what it currently can do:
|
||||
1. Dump and restore save data.
|
||||
* This includes the ability to dump and restore to/from any location on SD by pressing minus and using the Advanced Mode.
|
||||
* Save Data can be dumped and restored directly to and from ZIP archives by enabling `Export To ZIP` in the options menus. Folders will still be detected and usable even with this enabled.
|
||||
2. Dump system save data
|
||||
This started as a simple, straight port of my 3DS save manager I publicly released in 2016. Despite not originally wanting to take it too far, I continued working on it for fun when I can. Currently it can:
|
||||
1. Dump and restore account save data.
|
||||
2. Dump and restore device saves shared by all users (Games such as Animal Crossing).
|
||||
3. Dump and restore BCAT Data.
|
||||
4. Dump and restore cache Saves.
|
||||
5. Dump system save data.
|
||||
* Dumping this data is always enabled, but writing back needs to be enabled from the options menu. Writing to this can be very dangerous.
|
||||
3. Open and explore bis storage partitions via the Extras menu
|
||||
* Processes can be terminated from the Extras menu allowing you to open even more of these and explore more.
|
||||
6. Export save data to folders like the orignal or compressed zip files to save space.
|
||||
7. Create save data so the user no longer needs to boot games to import saves.
|
||||
* Titles can be rescanned from the Extras menu. For example, if you insert a game card while JKSV is open, rescanning will load and add it to the save creation menu(s).
|
||||
8. Export and use SVI files to create save data for titles not installed on your system. For games that detect other game saves to unlock content.
|
||||
* SVI files are simply the title ID, NACP, and icon packed into a file. Placing them in `JKSV/svi` will load them as if they are any other game on your switch. They will appear in the save creation menus with the rest.
|
||||
9. Extend save data containers to any size the user wants or automatically if the save cannot fit into the current one.
|
||||
10. Delete save data from the system.
|
||||
11. Reset save data as if the game was never launched.
|
||||
12. Display stats and information about the game/save: Play time, launch count, title ID (TID), save ID(SID)/name of save file on user nand partition, etc.
|
||||
13. Open and explore bis storage partitions via the Extras menu
|
||||
* BIS Storage is opened inside a basic filebrowser. The partition's listing is on the left. Your SD is on the right.
|
||||
* Only copying to SD and file properties work on BIS partitions. Writing to and deleting are disabled unless enabled like system save data.
|
||||
4. Misc Extras:
|
||||
* Ability to remove downloaded firmware updates from NAND. This is located in the extras menu (ZR on User selection)
|
||||
14. Misc Extras:
|
||||
* Ability to remove downloaded firmware updates from NAND. This is located under Extras.
|
||||
* Terminating processes by [ID](https://switchbrew.org/wiki/Title_list#System_Modules). Allowing you to dump normally unopenable system archives.
|
||||
* Mount by System Save [ID](https://switchbrew.org/wiki/Flash_Filesystem#System_Savegames). Normally used when the terminated process makes JKSV unable to rescan titles without the Switch crashing.
|
||||
* Mount and open RomFS of process the homebrew menu takes over (if launched as NRO).
|
||||
* Hold R while opening a game or applet with Atmosphere so the homebrew menu loads. Open JKSV and press minus and select **Mount Process RomFS**. The romfs of the app should appear in the browser along with your SD on the right.
|
||||
|
||||
## Quick Guide
|
||||
**A custom path can be defined by creating "sdmc:/switch/jksv_dir.txt" and typing the path you want to use. For example, `sdmc:/switch/JKSV/` will force JKSV to create its folder in the switch homebrew folder.**
|
||||
1. Main/User Menu
|
||||
* A Selects the currently highlighted user and allows you to browse their titles.
|
||||
* Y Dumps the save data for all users.
|
||||
* X opens the sub menu of options for the currently highlighted user:
|
||||
* Dump All for [X] dumps all of the saves for the highlighted user.
|
||||
* Create save data opens a list of games found on your switch and will allow to create save data for them without needing to start the games.
|
||||
* SVI files located in `JKSV/svi` will also be loaded and added to this list. These are to create save data for games not currently on the system. This is for games that search for other saves to unlock extra content.
|
||||
* Cache saves require a cache index number to be created. This information can be found under information for a cache save when being exported.
|
||||
* Create All Save Data creates save data for every title on your system for the selected user.
|
||||
* Delete All Save Data deletes all save data for the selected user. This is permanant.
|
||||
* Settings and Extras below.
|
||||
|
||||
**Custom "safe titles" can be set by creating a file named `titleDefs.txt` in your JKSV directory. These are the folders on SD in which game saves are stored. For example, creating this file and adding the line `0100BFE00E9CA000 = "The Witcher 3 CE"` will set The Witcher 3 to use `[pathto]/JKSV/The Witcher 3 CE/` directory instead of its title id. These need to be ASCII or they will fail to work.**
|
||||
|
||||
1. User Select
|
||||
* A opens the selected user's save files.
|
||||
* Y Dumps __all__ save data from __all users__, device save data, and BCAT save data. System save data is not included in this.
|
||||
* X Changes the UI mode to a text menu based one for people that prefer 3DS JKSM style text menus instead.
|
||||
* Minus Opens the Options menu.
|
||||
* ZR opens a small menu of extras.
|
||||
|
||||
2. Title Select
|
||||
* A Opens the title for backup and restore.
|
||||
* L and R change the current user.
|
||||
* Y Dumps all saves for the currently selected user.
|
||||
* X adds the selected title to a list of favorites that are pushed to the top of the title list/icons.
|
||||
* Minus adds the selected title to a list of ignored titles.
|
||||
* ZR __ERASES__ The selected title's save from the system. This is the same as going into settings and deleting via data management. __THIS DOES NOT DELETE JKSV's SAVE FOLDERS__.
|
||||
|
||||
3. Backup/Folder Menu
|
||||
* Minus opens file mode. File mode is a basic file browser for moving individual files and folders. This also adds the ability to restore saves from any location on your SD card.
|
||||
* Holding L or R while selecting new with A will automatically name the backup for you without opening the keyboard.
|
||||
* A creates a new backup
|
||||
* JKSV adds some suggestions to the keyboard's dictionary such as: date strings, the current user's name **if it's safe**, and the current title or a generated abbreviation.
|
||||
* Y Restores save data from the selected folder.
|
||||
* X Deletes the selected folder.
|
||||
* ZR __ERASES__ the current save data for the title from __your system__, but leaves the archive on NAND.
|
||||
2. Title/Game Select
|
||||
* A selects and opens the backup menu.
|
||||
* Adding `.zip` to the end of your file name will force zip regardless of whether it's enabled or not.
|
||||
* Y Favorites a title and pushes it to the top of your games.
|
||||
* L and R jump forward down your games.
|
||||
* X opens the title options menu:
|
||||
* Information displays stats about the game for the current user.
|
||||
* Blacklist adds the title to a list that is not displayed.
|
||||
* Change Output Folder changes the folder to which the game's saves are written.
|
||||
* Open in File Mode opens the save in a basic file browser.
|
||||
* Delete All Save Backups deletes all of the backups for the current title.
|
||||
* Reset Save Data wipes the save clean as if it was never run.
|
||||
* Delete Save Data deletes the save data for the title from the system. This is the same as doing it from the Switch's data management setting.
|
||||
* Extend Save Data extends the container for the current title. This is also done automatically if the save being imported is too large for the container.
|
||||
* Different games have different limits. Most games do not need this at all. A few will take advantage of a larger container, others extend theirs at times and will need larger containers than created by default.
|
||||
* Export SVI exports the data needed to create save data for the current title to `JKSV/ncap/[TID].svi`. This is just the title ID, NACP, and icon of the title. These can be used to create save data for games not installed on your system.
|
||||
|
||||
4. File Mode
|
||||
* A opens directories.
|
||||
|
|
@ -60,6 +72,13 @@ JKSV on Switch started as a small project/port to test some things and get famil
|
|||
* Make Dir creates a folder.
|
||||
* Properties gets file size and directory size.
|
||||
* ZL or ZR Change the controlled menu.
|
||||
|
||||
5. Settings
|
||||
* Empty Trash Bin deletes all backups inside the `_TRASH_` folder. The trash bin feature can be disabled further down.
|
||||
* Check For Updates checks github for updates to JKSV. This currently only updates the NRO release. Maybe NSP later.
|
||||
* Set JKSV Save Output Folder allows you to set where JKSV's working directory is. Files and folders should be relocated for you.
|
||||
* Edit Blacklisted Titles allows you to removed titles blacklisted from being shown.
|
||||
* Delete All Save Backups wipes JKSV's folder of all save backups.
|
||||
|
||||
5. Extras
|
||||
* SD To SD Browser opens the filebrowser with your SD open in both panels
|
||||
|
|
@ -75,7 +94,7 @@ JKSV on Switch started as a small project/port to test some things and get famil
|
|||
|
||||
## Building:
|
||||
1. Requires [devkitPro](https://devkitpro.org/) and [libnx](https://github.com/switchbrew/libnx)
|
||||
2. Requires switch-freetype, libpng, zlib, libjpeg-turbo, lib-curl, and lib-json-c
|
||||
2. `dkp-pacman -S switch-curl switch-freetype switch-libjpeg-turbo switch-libjson-c switch-libpng switch-libwebp switch-sdl2 switch-sdl2_gfx switch-sdl2_image switch-zlib`
|
||||
|
||||
## Credits and Thanks:
|
||||
* [shared-font](https://github.com/switchbrew/switch-portlibs-examples) example by yellows8 for loading system font with Freetype. All other font handling code (converting to SDL2, resizing on the fly, checking for glyphs, cache, etc) is my own.
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
#include "gfx.h"
|
||||
|
||||
#define BLD_MON 10
|
||||
#define BLD_DAY 12
|
||||
#define BLD_MON 11
|
||||
#define BLD_DAY 15
|
||||
#define BLD_YEAR 2021
|
||||
|
||||
namespace data
|
||||
|
|
@ -29,7 +29,7 @@ namespace data
|
|||
{
|
||||
NacpStruct nacp;
|
||||
std::string title, safeTitle, author;//Shortcuts sorta.
|
||||
SDL_Texture *icon;
|
||||
SDL_Texture *icon = NULL;
|
||||
bool fav;
|
||||
} titleInfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,156 +1,156 @@
|
|||
author = 0, "NULL"
|
||||
confirmBlacklist = 0, "Are you sure you want to add #%s# to your blacklist?"
|
||||
confirmCopy = 0, "Are you sure you want to copy #%s# to #%s#?"
|
||||
confirmCreateAllSaveData = 0, "Are you sure you would like to create all save data on this system for #%s#? This can take a while depending on how many titles are found."
|
||||
confirmDelete = 0, "Are you sure you want to delete #%s#? *This is permanent*!"
|
||||
confirmDeleteBackupsAll = 0, "Are you sure you would like to delete *all* of your save backups for all of your games?"
|
||||
confirmDeleteBackupsTitle = 0, "Are you sure you would like to delete all save backups for #%s#?"
|
||||
confirmDeleteSaveData = 0, "*WARNING*: This *will* erase the save data for #%s# *from your system*. Are you sure you want to do this?"
|
||||
confirmOverwrite = 0, "Are you sure you want to overwrite #%s#?"
|
||||
confirmResetSaveData = 0, "*WARNING*: This *will* reset the save data for this game as if it was never ran before. Are you sure you want to do this?"
|
||||
confirmRestore = 0, "Are you sure you want to restore #%s#?"
|
||||
confirmBlacklist = 0, "¿Estás seguro que deseas adicionar #%s# a la lista negra?"
|
||||
confirmCopy = 0, "¿Seguro que desea copiar #%s# a #%s#?"
|
||||
confirmCreateAllSaveData = 0, "¿Seguro que desea crear respaldo de todas las partidas guardadas en el sistema para #%s#? ¡Puede tomar un tiempo dependiendo de la cantidad de títulos!"
|
||||
confirmDelete = 0, "¿Seguro que desea borrar #%s#? *¡Es permanente!*"
|
||||
confirmDeleteBackupsAll = 0, "¿Seguro que desea borrar *TODOS* los respaldos de partidas guardadas para todos sus juegos?"
|
||||
confirmDeleteBackupsTitle = 0, "¿Seguro que desea borrar todos los respaldos de partidas guardadas para #%s#?"
|
||||
confirmDeleteSaveData = 0, "*ADVERTENCIA*: Ésto eliminará la partida guardada para #%s# *DE SU SISTEMA*. ¿Está seguro que así lo desea?"
|
||||
confirmOverwrite = 0, "¿Sobre escribir #%s#?"
|
||||
confirmResetSaveData = 0, "*ADVERTENCIA*: Ésto restablecerá la partida guardada para este juego, como si nunca se hubiera ejecutado. ¿Está seguro que es lo que desea?"
|
||||
confirmRestore = 0, "¿Seguro que desea restaurar #%s#?"
|
||||
dialogNo = 0, "No [B]"
|
||||
dialogOK = 0, "OK [A]"
|
||||
dialogYes = 0, "Yes [A]"
|
||||
extrasMenu = 0, "SD to SD Browser"
|
||||
dialogYes = 0, "Si [A]"
|
||||
extrasMenu = 0, "Navegador de SD a SD"
|
||||
extrasMenu = 1, "BIS: ProdInfoF"
|
||||
extrasMenu = 2, "BIS: Safe"
|
||||
extrasMenu = 3, "BIS: System"
|
||||
extrasMenu = 4, "BIS: User"
|
||||
extrasMenu = 5, "Remove Pending Update"
|
||||
extrasMenu = 6, "Terminate Process"
|
||||
extrasMenu = 7, "Mount System Save"
|
||||
extrasMenu = 8, "Rescan Titles"
|
||||
extrasMenu = 9, "Mount Process RomFS"
|
||||
extrasMenu = 10, "Backup JKSV Folder"
|
||||
extrasMenu = 5, "Eliminar actualizaciones pendientes"
|
||||
extrasMenu = 6, "Detener proceso"
|
||||
extrasMenu = 7, "Montar 'System Save'"
|
||||
extrasMenu = 8, "Recargar Lista de Títulos"
|
||||
extrasMenu = 9, "Montar 'Process RomFS'"
|
||||
extrasMenu = 10, "Realizar respaldo de la carpeta de JKSV"
|
||||
extrasMenu = 11, "*[DEV]* Output en-US"
|
||||
fileModeFileProperties = 0, "Path: %s\nSize: %s"
|
||||
fileModeFolderProperties = 0, "Path: %s\nSub Folders: %u\nFile Count: %u\nTotal Size: %s"
|
||||
fileModeMenu = 0, "Copy To "
|
||||
fileModeMenu = 1, "Delete"
|
||||
fileModeMenu = 2, "Rename"
|
||||
fileModeMenu = 3, "Make Dir"
|
||||
fileModeMenu = 4, "Properties"
|
||||
fileModeMenu = 5, "Close"
|
||||
fileModeMenu = 6, "Add to Path Filters"
|
||||
fileModeMenuMkDir = 0, "New"
|
||||
folderMenuNew = 0, "New Backup"
|
||||
helpFolder = 0, "[A] Select [Y] Restore [X] Delete [B] Close"
|
||||
helpSettings = 0, "[A] Toggle [X] Defaults [B] Back"
|
||||
helpTitle = 0, "[A] Select [L][R] Jump [Y] Favorite [X] Title Options [B] Back"
|
||||
helpUser = 0, "[A] Select [X] User Options"
|
||||
holdingText = 0, "(Hold) "
|
||||
holdingText = 1, "(Keep Holding) "
|
||||
holdingText = 2, "(Almost There!) "
|
||||
fileModeFileProperties = 0, "Ruta: %s\nTamaño: %s"
|
||||
fileModeFolderProperties = 0, "Ruta: %s\nSubCarpetas: %u\nCantidad Archivos: %u\nTamaño Total: %s"
|
||||
fileModeMenu = 0, "Copiar a "
|
||||
fileModeMenu = 1, "Borrar"
|
||||
fileModeMenu = 2, "Renombrar"
|
||||
fileModeMenu = 3, "Crear Carpeta"
|
||||
fileModeMenu = 4, "Propiedades"
|
||||
fileModeMenu = 5, "Cerrar"
|
||||
fileModeMenu = 6, "Adicionar a filtros de Carpetas"
|
||||
fileModeMenuMkDir = 0, "Nuevo"
|
||||
folderMenuNew = 0, "Nuevo Respaldo"
|
||||
helpFolder = 0, "[A] Selecionar [Y] Restaurar [X] Borrar [B] Cerrar"
|
||||
helpSettings = 0, "[A] Alternar [X] Predeterminados [B] Atrás"
|
||||
helpTitle = 0, "[A] Seleccionar [L][R] Saltar [Y] Favoritos [X] Opciones de Títulos [B] Atrás"
|
||||
helpUser = 0, "[A] Seleccionar [X] Opciones de Usuario"
|
||||
holdingText = 0, "(Sostenga) "
|
||||
holdingText = 1, "(Siga Sosteniendo) "
|
||||
holdingText = 2, "(¡Ya Casi!) "
|
||||
infoStatus = 0, "TID: "
|
||||
infoStatus = 1, "SID: "
|
||||
infoStatus = 2, "Play Time: "
|
||||
infoStatus = 3, "Total Launches: "
|
||||
infoStatus = 4, "User Count: "
|
||||
infoStatus = 5, "Current User: "
|
||||
infoStatus = 6, "Current Title: "
|
||||
infoStatus = 7, "Safe Title: "
|
||||
infoStatus = 8, "Sort Type: "
|
||||
infoStatus = 9, "Saving the file master..."
|
||||
infoStatus = 10, "Deleting..."
|
||||
infoStatus = 11, "Trash emptied."
|
||||
loadingStartPage = 0, "Loading..."
|
||||
infoStatus = 2, "Tiempo de Juego: "
|
||||
infoStatus = 3, "Veces Ejecutado: "
|
||||
infoStatus = 4, "Conteo de Usuario: "
|
||||
infoStatus = 5, "Usuario Actual: "
|
||||
infoStatus = 6, "Título Actual: "
|
||||
infoStatus = 7, "Título Seguro: "
|
||||
infoStatus = 8, "Organizar por : "
|
||||
infoStatus = 9, "Guardando archivo maestro..."
|
||||
infoStatus = 10, "Borrando..."
|
||||
infoStatus = 11, "Papelera vacía."
|
||||
loadingStartPage = 0, "Cargando..."
|
||||
mainMenuExtras = 0, "Extras"
|
||||
mainMenuSettings = 0, "Settings"
|
||||
onlineErrorConnecting = 0, "Error Connecting!"
|
||||
onlineNoUpdates = 0, "No Updates Available."
|
||||
popAddedToPathFilter = 0, "'#%s#' added to path filters."
|
||||
popCPUBoostEnabled = 0, "CPU Boost Enabled for ZIP."
|
||||
popChangeOutputError = 0, "#%s# contains illegal or non-ASCII characters."
|
||||
popChangeOutputFolder = 0, "#%s# changed to #%s#"
|
||||
popErrorCommittingFile = 0, "Error committing file to save!"
|
||||
popFolderIsEmpty = 0, "Folder is empty!"
|
||||
popProcessShutdown = 0, "#%s# successfully shutdown."
|
||||
popSaveIsEmpty = 0, "Save data is empty!"
|
||||
popZipIsEmpty = 0, "ZIP file is empty!"
|
||||
saveDataBackupDeleted = 0, "#%s# has been deleted."
|
||||
saveDataBackupMovedToTrash = 0, "#%s# has been moved to trash."
|
||||
saveDataCreatedForUser = 0, "Save data created for %s!"
|
||||
saveDataCreationFailed = 0, "Save data creation failed!"
|
||||
saveDataDeleteAllUser = 0, "*ARE YOU SURE YOU WANT TO DELETE ALL SAVE DATA FOR %s?*"
|
||||
saveDataDeleteSuccess = 0, "Save data for #%s# deleted!"
|
||||
saveDataExtendFailed = 0, "Failed to extend save data."
|
||||
saveDataExtendSuccess = 0, "Save data for #%s# extended!"
|
||||
saveDataIndexText = 0, "存檔索引號:"
|
||||
saveDataNoneFound = 0, "No saves found for #%s#!"
|
||||
saveDataResetSuccess = 0, "Save for #%s# reset!"
|
||||
saveDataTypeText = 0, "系統存檔\n"
|
||||
saveDataTypeText = 1, "用戶存檔\n"
|
||||
saveDataTypeText = 2, "BCAT存檔\n"
|
||||
saveDataTypeText = 3, "設備存檔\n"
|
||||
saveDataTypeText = 4, "臨時存檔\n"
|
||||
saveDataTypeText = 5, "緩存存檔\n"
|
||||
saveDataTypeText = 6, "系統BCAT存檔\n"
|
||||
saveTypeMainMenu = 0, "Device"
|
||||
mainMenuSettings = 0, "Configuraciones"
|
||||
onlineErrorConnecting = 0, "¡Error Conectando!"
|
||||
onlineNoUpdates = 0, "No hay actualizaciones disponibles."
|
||||
popAddedToPathFilter = 0, "se adicionó '#%s#' a filtros de carpeta."
|
||||
popCPUBoostEnabled = 0, "Aumento de CPU para ZIP."
|
||||
popChangeOutputError = 0, "#%s# contiene carácteres ilegales o no-ASCII."
|
||||
popChangeOutputFolder = 0, "Se cambia #%s# por #%s#"
|
||||
popErrorCommittingFile = 0, "¡Error guardando archivo!"
|
||||
popFolderIsEmpty = 0, "¡La carpeta está vacía!"
|
||||
popProcessShutdown = 0, "#%s# Apagado satisfactorio."
|
||||
popSaveIsEmpty = 0, "¡Partida Guardada está vacía!"
|
||||
popZipIsEmpty = 0, "¡Archivo ZIP está vacío!"
|
||||
saveDataBackupDeleted = 0, "#%s# ha sido borrado."
|
||||
saveDataBackupMovedToTrash = 0, "#%s# ha sido movido a papelera."
|
||||
saveDataCreatedForUser = 0, "Se creó Partida Guardada para %s!"
|
||||
saveDataCreationFailed = 0, "¡Error en creación de Partida Guardada!"
|
||||
saveDataDeleteAllUser = 0, "*¿SEGURO QUE DESEA BORRAR TODAS LAS PARTIDAS GUARDADAS DE %s?*"
|
||||
saveDataDeleteSuccess = 0, "¡Se borró la Partida Guardada de #%s#!"
|
||||
saveDataExtendFailed = 0, "Error al expandir la partida guardada."
|
||||
saveDataExtendSuccess = 0, "¡Partida Guardada para #%s# epandida con éxito!"
|
||||
saveDataIndexText = 0, "Guardar Índice: "
|
||||
saveDataNoneFound = 0, "¡No se encontraron partidas guardadas para #%s#!"
|
||||
saveDataResetSuccess = 0, "¡Partida Guardada para #%s# restablecida!"
|
||||
saveDataTypeText = 0, "Datos de Sistema\n"
|
||||
saveDataTypeText = 1, "Partida Guardada\n"
|
||||
saveDataTypeText = 2, "BCAT\n"
|
||||
saveDataTypeText = 3, "Datos de Dispositivo\n"
|
||||
saveDataTypeText = 4, "Almacenamiento Temporal\n"
|
||||
saveDataTypeText = 5, "Almacenamiento de Caché\n"
|
||||
saveDataTypeText = 6, "System BCAT\n"
|
||||
saveTypeMainMenu = 0, "Dispositivo"
|
||||
saveTypeMainMenu = 1, "BCAT"
|
||||
saveTypeMainMenu = 2, "Cache"
|
||||
saveTypeMainMenu = 3, "System"
|
||||
saveTypeMainMenu = 4, "System BCAT"
|
||||
saveTypeMainMenu = 2, "Caché"
|
||||
saveTypeMainMenu = 3, "Sistema"
|
||||
saveTypeMainMenu = 4, "BCAT de Sistema"
|
||||
saveTypeMainMenu = 5, "SysTemp Storagetem"
|
||||
settingsMenu = 0, "Empty Trash Bin"
|
||||
settingsMenu = 1, "Check for Updates"
|
||||
settingsMenu = 2, "Set JKSV Save Output Folder"
|
||||
settingsMenu = 3, "Edit Blacklisted Titles"
|
||||
settingsMenu = 4, "Delete All Save Backups"
|
||||
settingsMenu = 5, "Include Device Saves With Users: "
|
||||
settingsMenu = 6, "Auto Backup On Restore: "
|
||||
settingsMenu = 7, "Auto-Name Backups: "
|
||||
settingsMenu = 8, "Overclock/CPU Boost: "
|
||||
settingsMenu = 9, "Hold To Delete: "
|
||||
settingsMenu = 10, "Hold To Restore: "
|
||||
settingsMenu = 11, "Hold To Overwrite: "
|
||||
settingsMenu = 12, "Force Mount: "
|
||||
settingsMenu = 13, "Account System Saves: "
|
||||
settingsMenu = 14, "Enable Writing to System Saves: "
|
||||
settingsMenu = 15, "Use FS Commands Directly: "
|
||||
settingsMenu = 16, "Export Saves to ZIP: "
|
||||
settingsMenu = 17, "Force English To Be Used: "
|
||||
settingsMenu = 18, "Enable Trash Bin: "
|
||||
settingsMenu = 19, "Title Sorting Type: "
|
||||
settingsMenu = 20, "Animation Scale: "
|
||||
settingsOff = 0, "Off"
|
||||
settingsOn = 0, ">On>"
|
||||
sortType = 0, "Alphabetical"
|
||||
sortType = 1, "Time Played"
|
||||
sortType = 2, "Last Played"
|
||||
swkbdEnterName = 0, "Enter a new name"
|
||||
swkbdExpandSize = 0, "Enter New Size in MB"
|
||||
swkbdMkDir = 0, "Enter a folder name"
|
||||
swkbdNewSafeTitle = 0, "Input New Output Folder"
|
||||
swkbdProcessID = 0, "Enter Process ID"
|
||||
swkbdRename = 0, "Enter a new name for item"
|
||||
swkbdSaveIndex = 0, "Enter Cache Index"
|
||||
swkbdSetWorkDir = 0, "Enter a new Output Path"
|
||||
swkbdSysSavID = 0, "Enter System Save ID"
|
||||
threadStatusAddingFileToZip = 0, "Adding '#%s#' to ZIP..."
|
||||
threadStatusCheckingForUpdate = 0, "Checking for updates..."
|
||||
threadStatusCopyingFile = 0, "Copying '#%s#'..."
|
||||
threadStatusCreatingSaveData = 0, "Creating Save Data for #%s#..."
|
||||
threadStatusDecompressingFile = 0, "Decompressing '#%s#'..."
|
||||
threadStatusDeletingFile = 0, "Deleting..."
|
||||
threadStatusDeletingSaveData = 0, "Deleting Save Data for #%s#..."
|
||||
threadStatusDeletingUpdate = 0, "Deleting pending update..."
|
||||
threadStatusDownloadingUpdate = 0, "Downloading update..."
|
||||
threadStatusExtendingSaveData = 0, "Extending Save Data for #%s#..."
|
||||
threadStatusGetDirProps = 0, "Getting Folder Properties..."
|
||||
threadStatusOpeningFolder = 0, "Opening '#%s#'..."
|
||||
threadStatusPackingJKSV = 0, "Writing JKSV folder contents to ZIP..."
|
||||
threadStatusResettingSaveData = 0, "Resetting save data..."
|
||||
titleOptions = 0, "Information"
|
||||
titleOptions = 1, "Blacklist"
|
||||
titleOptions = 2, "Change Output Folder"
|
||||
titleOptions = 3, "Open in File Mode"
|
||||
titleOptions = 4, "Delete All Save Backups"
|
||||
titleOptions = 5, "Reset Save Data"
|
||||
titleOptions = 6, "Delete Save Data"
|
||||
titleOptions = 7, "Extend Save Data"
|
||||
translationMainPage = 0, "Translation: "
|
||||
userOptions = 0, "Dump All For "
|
||||
userOptions = 1, "Create Save Data"
|
||||
userOptions = 2, "Create All Save Data"
|
||||
userOptions = 3, "Delete All User Saves"
|
||||
settingsMenu = 0, "Vaciar Papelera"
|
||||
settingsMenu = 1, "Buscar Actualizaciones"
|
||||
settingsMenu = 2, "Configurar carpeta de salida para JKSV"
|
||||
settingsMenu = 3, "Editar lista negra de Títulos"
|
||||
settingsMenu = 4, "Eliminar todos los respaldos"
|
||||
settingsMenu = 5, "Incluír Datos de Dispositivo con los Usuarios: "
|
||||
settingsMenu = 6, "Crear respaldo automático al restaurar: "
|
||||
settingsMenu = 7, "Nombrar Automáticamente los respaldos: "
|
||||
settingsMenu = 8, "Overclock/Aumento de CPU: "
|
||||
settingsMenu = 9, "Sostener para Borrar: "
|
||||
settingsMenu = 10, "Sostener para Restaurar: "
|
||||
settingsMenu = 11, "Sostener para Sobreescribir: "
|
||||
settingsMenu = 12, "Montar forzado: "
|
||||
settingsMenu = 13, "Datos de la cuenta de Sistema: "
|
||||
settingsMenu = 14, "Habilitar escritura para datos de Sistema: "
|
||||
settingsMenu = 15, "Usar comandos FS directamente: "
|
||||
settingsMenu = 16, "Exportar partidas guardadas a archivos ZIP: "
|
||||
settingsMenu = 17, "Forzar el uso de Inglés: "
|
||||
settingsMenu = 18, "Habilitar papelera: "
|
||||
settingsMenu = 19, "Ordenar por : "
|
||||
settingsMenu = 20, "Escala de Animación: "
|
||||
settingsOff = 0, "Apagado"
|
||||
settingsOn = 0, ">Encendido>"
|
||||
sortType = 0, "Alfabetico"
|
||||
sortType = 1, "Duración Juegos"
|
||||
sortType = 2, "Último Jugado"
|
||||
swkbdEnterName = 0, "Ingrese un nuevo nombre"
|
||||
swkbdExpandSize = 0, "Ingrese nuevo tamaño en MB"
|
||||
swkbdMkDir = 0, "Ingrese nombre de carpeta"
|
||||
swkbdNewSafeTitle = 0, "Ingrese Nueva Carpeta de Salida"
|
||||
swkbdProcessID = 0, "Ingrese ID de proceso"
|
||||
swkbdRename = 0, "Ingrese un nuevo nombre para el elemento"
|
||||
swkbdSaveIndex = 0, "Ingrese Índice de Caché"
|
||||
swkbdSetWorkDir = 0, "Ingrese Nueva Carpeta de Salida"
|
||||
swkbdSysSavID = 0, "Ingrese ID de Datos de Sistema"
|
||||
threadStatusAddingFileToZip = 0, "Agregando '#%s#' a archivo ZIP..."
|
||||
threadStatusCheckingForUpdate = 0, "Verificando actualizaciones..."
|
||||
threadStatusCopyingFile = 0, "Copiando '#%s#'..."
|
||||
threadStatusCreatingSaveData = 0, "Creando Partida Guardada para #%s#..."
|
||||
threadStatusDecompressingFile = 0, "Descomprimiendo '#%s#'..."
|
||||
threadStatusDeletingFile = 0, "Borrando..."
|
||||
threadStatusDeletingSaveData = 0, "Borrando Partida Guardada para #%s#..."
|
||||
threadStatusDeletingUpdate = 0, "Borrando Actualización Pendiente..."
|
||||
threadStatusDownloadingUpdate = 0, "Borrando Actualización..."
|
||||
threadStatusExtendingSaveData = 0, "Expandiendo Datos Guardados para #%s#..."
|
||||
threadStatusGetDirProps = 0, "Obteniendo propiedades de Carpeta..."
|
||||
threadStatusOpeningFolder = 0, "Abriendo '#%s#'..."
|
||||
threadStatusPackingJKSV = 0, "Guardando contenidos de carpeta de JKSV en archivo ZIP..."
|
||||
threadStatusResettingSaveData = 0, "Restableciendo datos de partida..."
|
||||
titleOptions = 0, "Información"
|
||||
titleOptions = 1, "Lista Negra"
|
||||
titleOptions = 2, "Cambiar Carpeta de Salida"
|
||||
titleOptions = 3, "Abrir en Modo Archivo"
|
||||
titleOptions = 4, "Borrar todos los respaldos"
|
||||
titleOptions = 5, "Restablecer Datos de Partida"
|
||||
titleOptions = 6, "Borrar Datos de Partida"
|
||||
titleOptions = 7, "Expandir Datos de Partida"
|
||||
translationMainPage = 0, "Traducción: "
|
||||
userOptions = 0, "Extrar Todo para "
|
||||
userOptions = 1, "Crear Datos de Partida"
|
||||
userOptions = 2, "Crear Todos los Datos de Partida"
|
||||
userOptions = 3, "Borrar Datos de Partida para todos los Usuarios"
|
||||
|
|
|
|||
54
src/data.cpp
54
src/data.cpp
|
|
@ -118,7 +118,10 @@ static inline void addTitleToList(const uint64_t& tid)
|
|||
//Setup 'shortcuts' to strings
|
||||
NacpLanguageEntry *ent;
|
||||
nacpGetLanguageEntry(&data::titles[tid].nacp, &ent);
|
||||
data::titles[tid].title = ent->name;
|
||||
if(strlen(ent->name) == 0)
|
||||
data::titles[tid].title = ctrlData->nacp.lang[SetLanguage_ENUS].name;
|
||||
else
|
||||
data::titles[tid].title = ent->name;
|
||||
data::titles[tid].author = ent->author;
|
||||
if(cfg::isDefined(tid))
|
||||
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
|
||||
|
|
@ -127,7 +130,7 @@ static inline void addTitleToList(const uint64_t& tid)
|
|||
|
||||
if(cfg::isFavorite(tid))
|
||||
data::titles[tid].fav = true;
|
||||
|
||||
|
||||
data::titles[tid].icon = gfx::loadJPEGMem(ctrlData->icon, iconSize);
|
||||
if(!data::titles[tid].icon)
|
||||
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
|
||||
|
|
@ -178,6 +181,52 @@ static void loadTitlesFromRecords()
|
|||
}
|
||||
}
|
||||
|
||||
static void importSVIs()
|
||||
{
|
||||
std::string sviDir = fs::getWorkDir() + "svi/";
|
||||
fs::dirList sviList(sviDir);
|
||||
if(sviList.getCount() > 0)
|
||||
{
|
||||
for(unsigned i = 0; i < sviList.getCount(); i++)
|
||||
{
|
||||
uint64_t tid = 0;
|
||||
NacpStruct *nacp = new NacpStruct;
|
||||
NacpLanguageEntry *ent;
|
||||
std::string sviPath = fs::getWorkDir() + "svi/" + sviList.getItem(i);
|
||||
|
||||
size_t iconSize = fs::fsize(sviPath) - (sizeof(uint64_t) + sizeof(NacpStruct));
|
||||
uint8_t *iconBuffer = new uint8_t[iconSize];
|
||||
FILE *sviIn = fopen(sviPath.c_str(), "rb");
|
||||
fread(&tid, sizeof(uint64_t), 1, sviIn);
|
||||
fread(nacp, sizeof(NacpStruct), 1, sviIn);
|
||||
fread(iconBuffer, 1, iconSize, sviIn);
|
||||
|
||||
if(!titleIsLoaded(tid))
|
||||
{
|
||||
nacpGetLanguageEntry(nacp, &ent);
|
||||
memcpy(&data::titles[tid].nacp, nacp, sizeof(NacpStruct));
|
||||
data::titles[tid].title = ent->name;
|
||||
data::titles[tid].author = ent->author;
|
||||
if(cfg::isDefined(tid))
|
||||
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
|
||||
else if((data::titles[tid].safeTitle = util::safeString(ent->name)) == "")
|
||||
data::titles[tid].safeTitle = util::getIDStr(tid);
|
||||
|
||||
if(cfg::isFavorite(tid))
|
||||
data::titles[tid].fav = true;
|
||||
|
||||
if(!data::titles[tid].icon && iconSize > 0)
|
||||
data::titles[tid].icon = gfx::loadJPEGMem(iconBuffer, iconSize);
|
||||
else if(!data::titles[tid].icon && iconSize == 0)
|
||||
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
|
||||
}
|
||||
delete nacp;
|
||||
delete[] iconBuffer;
|
||||
fclose(sviIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool data::loadUsersTitles(bool clearUsers)
|
||||
{
|
||||
static unsigned systemUserCount = 4;
|
||||
|
|
@ -186,6 +235,7 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
s64 total = 0;
|
||||
|
||||
loadTitlesFromRecords();
|
||||
importSVIs();
|
||||
|
||||
//Clear titles
|
||||
for(data::user& u : data::users)
|
||||
|
|
|
|||
10
src/gfx.cpp
10
src/gfx.cpp
|
|
@ -31,8 +31,6 @@ static const uint32_t blueMask = 0x0000FF00;
|
|||
static const uint32_t alphaMask = 0x000000FF;
|
||||
static const uint32_t breakPoints[7] = {' ', L' ', '/', '_', '-', L'。', L'、'};
|
||||
|
||||
static uint8_t *alphaMod;
|
||||
|
||||
static inline bool compClr(const SDL_Color *c1, const SDL_Color *c2)
|
||||
{
|
||||
return (c1->r == c2->r) && (c1->b == c2->b) && (c1->g == c2->g) && (c1->a == c2->a);
|
||||
|
|
@ -104,12 +102,6 @@ void gfx::init()
|
|||
|
||||
SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_BLEND);
|
||||
|
||||
//Load the alpha mod to round icon corners
|
||||
alphaMod = (uint8_t *)malloc(256 * 256);
|
||||
FILE *modLoad = fopen("romfs:/img/icn/icon.msk", "rb");
|
||||
fread(alphaMod, 1, 256 * 256, modLoad);
|
||||
fclose(modLoad);
|
||||
|
||||
loadSystemFont();
|
||||
}
|
||||
|
||||
|
|
@ -119,8 +111,6 @@ void gfx::exit()
|
|||
SDL_Quit();
|
||||
freeSystemFont();
|
||||
|
||||
free(alphaMod);
|
||||
|
||||
for(auto c : glyphCache)
|
||||
SDL_DestroyTexture(c.second.tex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ static void settMenuDeleteAllBackups_t(void *a)
|
|||
fs::dirList *jksvDir = new fs::dirList(fs::getWorkDir());
|
||||
for(unsigned i = 0; i < jksvDir->getCount(); i++)
|
||||
{
|
||||
if(jksvDir->isDir(i))
|
||||
if(jksvDir->isDir(i) && jksvDir->getItem(i) != "svi")
|
||||
{
|
||||
std::string delTarget = fs::getWorkDir() + jksvDir->getItem(i) + "/";
|
||||
fs::delDir(delTarget);
|
||||
|
|
|
|||
|
|
@ -14,11 +14,14 @@ static ui::slideOutPanel *infoPanel, *fldPanel;//There's no reason to have a sep
|
|||
static fs::dirList *fldList;
|
||||
static std::string infoPanelString;
|
||||
static SDL_Texture *fldBuffer;//This is so folder menu doesn't draw over guide
|
||||
static Mutex ttlViewLock = 0;
|
||||
|
||||
void ui::ttlRefresh()
|
||||
{
|
||||
mutexLock(&ttlViewLock);
|
||||
for(int i = 0; i < (int)data::users.size(); i++)
|
||||
ttlViews[i]->refresh();
|
||||
mutexUnlock(&ttlViewLock);
|
||||
}
|
||||
|
||||
static void fldFuncCancel(void *a)
|
||||
|
|
@ -308,6 +311,30 @@ static void ttlOptsExtendSaveData(void *a)
|
|||
}
|
||||
}
|
||||
|
||||
static void ttlOptsExportSVI(void *a)
|
||||
{
|
||||
data::userTitleInfo *ut = data::getCurrentUserTitleInfo();
|
||||
data::titleInfo *t = data::getTitleInfoByTID(ut->tid);
|
||||
std::string out = fs::getWorkDir() + "svi/";
|
||||
fs::mkDir(out.substr(0, out.length() - 1));
|
||||
out += util::getIDStr(ut->tid) + ".svi";
|
||||
FILE *svi = fopen(out.c_str(), "wb");
|
||||
if(svi)
|
||||
{
|
||||
//Grab icon
|
||||
NsApplicationControlData *ctrlData = new NsApplicationControlData;
|
||||
uint64_t ctrlSize = 0;
|
||||
nsGetApplicationControlData(NsApplicationControlSource_Storage, ut->tid, ctrlData, sizeof(NsApplicationControlData), &ctrlSize);
|
||||
size_t jpegSize = ctrlSize - sizeof(ctrlData->nacp);
|
||||
|
||||
fwrite(&ut->tid, sizeof(uint64_t), 1, svi);
|
||||
fwrite(&t->nacp, sizeof(NacpStruct), 1, svi);
|
||||
fwrite(ctrlData->icon, 1, jpegSize, svi);
|
||||
fclose(svi);
|
||||
delete ctrlData;
|
||||
}
|
||||
}
|
||||
|
||||
static void infoPanelDraw(void *a)
|
||||
{
|
||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
|
|
@ -430,7 +457,7 @@ void ui::ttlInit()
|
|||
fldList = new fs::dirList;
|
||||
|
||||
ttlOpts->setActive(false);
|
||||
for(int i = 0; i < 8; i++)
|
||||
for(int i = 0; i < 9; i++)
|
||||
ttlOpts->addOpt(NULL, ui::getUIString("titleOptions", i));
|
||||
|
||||
//Information
|
||||
|
|
@ -449,6 +476,8 @@ void ui::ttlInit()
|
|||
ttlOpts->optAddButtonEvent(6, HidNpadButton_A, ttlOptsDeleteSaveData, NULL);
|
||||
//Extend
|
||||
ttlOpts->optAddButtonEvent(7, HidNpadButton_A, ttlOptsExtendSaveData, NULL);
|
||||
//Export NACP
|
||||
ttlOpts->optAddButtonEvent(8, HidNpadButton_A, ttlOptsExportSVI, NULL);
|
||||
}
|
||||
|
||||
void ui::ttlExit()
|
||||
|
|
@ -484,7 +513,9 @@ void ui::ttlDraw(SDL_Texture *target)
|
|||
{
|
||||
unsigned curUserIndex = data::getCurrentUserIndex();
|
||||
|
||||
mutexLock(&ttlViewLock);
|
||||
ttlViews[curUserIndex]->draw(target);
|
||||
mutexUnlock(&ttlViewLock);
|
||||
if(ui::mstate == TTL_SEL && !fldPanel->isOpen())
|
||||
gfx::drawTextf(NULL, 18, ttlHelpX, 673, &ui::txtCont, ui::getUICString("helpTitle", 0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ void ui::initStrings()
|
|||
addUIString("titleOptions", 5, "Reset Save Data");
|
||||
addUIString("titleOptions", 6, "Delete Save Data");
|
||||
addUIString("titleOptions", 7, "Extend Save Data");
|
||||
addUIString("titleOptions", 8, "Export SVI");
|
||||
|
||||
//Thread Status Strings
|
||||
addUIString("threadStatusCreatingSaveData", 0, "Creating save data for #%s#...");
|
||||
|
|
|
|||
|
|
@ -266,17 +266,17 @@ static void usrOptCreateAllSaves_t(void *a)
|
|||
{
|
||||
AccountUid uid = u->getUID();
|
||||
for(unsigned i = 0; i < accSids.size(); i++)
|
||||
fs::createSaveDataThreaded(FsSaveDataType_Account, accSids[i], uid);
|
||||
fs::createSaveData(FsSaveDataType_Account, accSids[i], uid, t);
|
||||
}
|
||||
else if(sel == devPos)
|
||||
{
|
||||
for(unsigned i = 0; i < devSids.size(); i++)
|
||||
fs::createSaveDataThreaded(FsSaveDataType_Device, devSids[i], util::u128ToAccountUID(0));
|
||||
fs::createSaveData(FsSaveDataType_Device, devSids[i], util::u128ToAccountUID(0), t);
|
||||
}
|
||||
else if(sel == bcatPos)
|
||||
{
|
||||
for(unsigned i = 0; i < bcatSids.size(); i++)
|
||||
fs::createSaveDataThreaded(FsSaveDataType_Bcat, bcatSids[i], util::u128ToAccountUID(0));
|
||||
fs::createSaveData(FsSaveDataType_Bcat, bcatSids[i], util::u128ToAccountUID(0), t);
|
||||
}
|
||||
t->finished = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user