-
-
Save gnmmarechal/49207250243844178022 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <string> | |
#include <3ds.h> | |
#include "fs.h" | |
#include "misc.h" | |
u8 sysLang = 0; | |
// Override the default service init/exit functions | |
extern "C" | |
{ | |
u32 __stacksize__ = 0x40000; | |
void __appInit() | |
{ | |
// Initialize services | |
srvInit(); | |
aptInit(); | |
gfxInit(GSP_RGB565_OES, GSP_RGB565_OES, false); | |
hidInit(NULL); | |
fsInit(); | |
sdmcArchiveInit(); | |
} | |
void __appExit() | |
{ | |
// Exit services | |
sdmcArchiveExit(); | |
fsExit(); | |
hidExit(); | |
gfxExit(); | |
aptExit(); | |
srvExit(); | |
} | |
} | |
Result _srvGetServiceHandle(Handle* out, const char* name) | |
{ | |
Result rc = 0; | |
u32* cmdbuf = getThreadCommandBuffer(); | |
cmdbuf[0] = 0x50100; | |
strcpy((char*)&cmdbuf[1], name); | |
cmdbuf[3] = strlen(name); | |
cmdbuf[4] = 0; | |
if((rc = svcSendSyncRequest(*srvGetSessionHandle()))) return rc; | |
*out = cmdbuf[3]; | |
return cmdbuf[1]; | |
} | |
void callback(const std::u16string& fsObject, u32 totalPercent, u32 filePercent) | |
{ | |
Buffer<char> str(256); | |
utf16_to_utf8((u8*)&str, (u16*)fsObject.c_str(), 255); | |
printf("\x1b[1;0H%s %u%%\nTotal: %u", &str, filePercent, totalPercent); | |
gfxFlushBuffers(); | |
gfxSwapBuffers(); | |
} | |
int main() | |
{ | |
Handle fsUHandle = 0; | |
Result res = _srvGetServiceHandle(&fsUHandle, "fs:USER"); // Get a handle for the process we run under | |
consoleInit(GFX_TOP, nullptr); | |
printf("Get fs:USER handle: 0x%X\n", res); | |
res = FSUSER_Initialize(&fsUHandle); | |
printf("FSUSER_Initialize: 0x%X\n", res); | |
FS_archive saveArchive = {ARCH_SAVEDATA, {PATH_EMPTY, 0, nullptr}}; | |
res = FSUSER_OpenArchive(&fsUHandle, &saveArchive); | |
printf("Open archive: 0x%X\n", res); | |
if(!res) printf("\x1b[2JA Backup save data.\nB Import save data.\nX Exit."); | |
else | |
{ | |
printf("Could not access the savedata archive! Press X to exit.\n"); | |
while(true) | |
{ | |
hidScanInput(); | |
if(hidKeysDown() & KEY_X) goto exit; | |
} | |
} | |
while(aptMainLoop()) | |
{ | |
hidScanInput(); | |
u32 kDown = hidKeysDown(); | |
if(kDown & KEY_A) | |
{ | |
try | |
{ | |
printf("\x1b[2JBacking up save data..."); | |
fs::copyDir(fsUHandle, *fsGetSessionHandle(), u"/", u"/saveDataBackup", callback, saveArchive); | |
printf("\x1b[2JA Backup save data.\nB Import save data.\nX Exit."); | |
} | |
catch(std::exception& e) | |
{ | |
printf("\n%s\n", e.what()); | |
} | |
} | |
if(kDown & KEY_B) | |
{ | |
try | |
{ | |
printf("\x1b[2JRestoring save data..."); | |
fs::copyDir(*fsGetSessionHandle(), fsUHandle, u"/saveDataBackup", u"/", callback, sdmcArchive, saveArchive); | |
res = FSUSER_ControlArchive(fsUHandle, &saveArchive); | |
printf("Control archive: 0x%X\n", res); | |
printf("\x1b[2JA Backup save data.\nB Import save data.\nX Exit."); | |
} | |
catch(std::exception& e) | |
{ | |
printf("\n%s\n", e.what()); | |
} | |
} | |
if(kDown & KEY_X) break; | |
gfxFlushBuffers(); | |
gfxSwapBuffers(); | |
gspWaitForVBlank(); | |
} | |
exit: | |
FSUSER_CloseArchive(&fsUHandle, &saveArchive); | |
svcCloseHandle(fsUHandle); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment