mirror of
https://github.com/Ryuzaki-MrL/savemii.git
synced 2026-08-22 10:53:59 -05:00
if title is in both NAND and USB add option to copy save from one to another and ask for backup destination
This commit is contained in:
25
src/main.c
25
src/main.c
@@ -111,6 +111,16 @@ Title* loadWiiUTitles() {
|
||||
free(xmlBuf);
|
||||
}
|
||||
}
|
||||
|
||||
titles[titleswiiu].isTitleDupe = false;
|
||||
for (int i = 0; i < titleswiiu; i++) {
|
||||
if ((titles[i].highID == highID) && (titles[i].lowID == lowID)) {
|
||||
titles[titleswiiu].isTitleDupe = true;
|
||||
titles[titleswiiu].dupeID = i;
|
||||
titles[i].isTitleDupe = true;
|
||||
titles[i].dupeID = titleswiiu;
|
||||
}
|
||||
}
|
||||
|
||||
titles[titleswiiu].highID = highID;
|
||||
titles[titleswiiu].lowID = lowID;
|
||||
@@ -250,29 +260,35 @@ int Menu_Main(void) {
|
||||
entrycount = count;
|
||||
for (int i = 0; i < 14; i++) {
|
||||
if (i+scroll<0 || i+scroll>=count) break;
|
||||
if (strlen(titles[i+scroll].shortName)) console_print_pos(0, i+2, " %s (%s)", titles[i+scroll].shortName, titles[i+scroll].isTitleOnUSB ? "USB" : "NAND");
|
||||
if (strlen(titles[i+scroll].shortName)) console_print_pos(0, i+2, " %s (%s) %s", titles[i+scroll].shortName, titles[i+scroll].isTitleOnUSB ? "USB" : "NAND", titles[i+scroll].isTitleDupe ? "[D]" : "");
|
||||
else console_print_pos(0, i+2, " %08lx%08lx", titles[i+scroll].highID, titles[i+scroll].lowID);
|
||||
} console_print_pos(0, 2 + cursor, "->");
|
||||
} break;
|
||||
case 2: { // Select Task
|
||||
entrycount = 3 + 2*(mode==0);
|
||||
entrycount = 3 + 2*(mode==0) + 1*((mode==0) && (titles[targ].isTitleDupe));
|
||||
console_print_pos(0, 2, " Backup savedata");
|
||||
console_print_pos(0, 3, " Restore savedata");
|
||||
console_print_pos(0, 4, " Wipe savedata");
|
||||
if (mode==0) {
|
||||
console_print_pos(0, 5, " Import from loadiine");
|
||||
console_print_pos(0, 6, " Export to loadiine");
|
||||
if (titles[targ].isTitleDupe) {
|
||||
console_print_pos(0, 7, " Copy Savedata to Title in %s", titles[targ].isTitleOnUSB ? "NAND" : "USB");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
console_print_pos(0, 2 + cursor, "->");
|
||||
} break;
|
||||
case 3: { // Select Options
|
||||
entrycount = 1 + 2*(mode==0);
|
||||
console_print_pos(0, 2, "Select %s:", task>2 ? "version" : "slot");
|
||||
if (task > 2) console_print_pos(0, 3, " < v%u >", versionList ? versionList[slot] : 0);
|
||||
if (task == 5) console_print_pos(0, 3, " < %s >", titles[targ].isTitleOnUSB ? "NAND" : "USB");
|
||||
else if (task > 2) console_print_pos(0, 3, " < v%u >", versionList ? versionList[slot] : 0);
|
||||
else console_print_pos(0, 3, " < %03u > (%s)", slot, isSlotEmpty(titles[targ].highID, titles[targ].lowID, slot) ? "Empty" : "Used");
|
||||
if (mode==0) {
|
||||
console_print_pos(0, 5, "Select user:");
|
||||
console_print_pos(0, 6, " < %s >", (allusers&&(task<3)) ? "all users" : "this user");
|
||||
console_print_pos(0, 6, " < %s >", (allusers&&((task<3) || task==5)) ? "all users" : "this user");
|
||||
console_print_pos(0, 8, "Include 'common' save?");
|
||||
console_print_pos(0, 9, " < %s >", common ? "yes" : "no ");
|
||||
console_print_pos(0, 3 + cursor*3, "->");
|
||||
@@ -365,6 +381,7 @@ int Menu_Main(void) {
|
||||
case 2: wipeSavedata(&titles[targ], allusers, common); break;
|
||||
case 3: importFromLoadiine(&titles[targ], common, versionList ? versionList[slot] : 0); break;
|
||||
case 4: exportToLoadiine(&titles[targ], common, versionList ? versionList[slot] : 0); break;
|
||||
case 5: copySavedata(&titles[targ], &titles[titles[targ].dupeID], allusers, common); break;
|
||||
}
|
||||
}
|
||||
} else if (isPressed(VPAD_BUTTON_B) && menu>0) {
|
||||
|
||||
@@ -319,6 +319,43 @@ int getEmptySlot(u32 highID, u32 lowID) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void copySavedata(Title* title, Title* titleb, bool allusers, bool common) {
|
||||
u32 highID = title->highID, lowID = title->lowID;
|
||||
bool isUSB = title->isTitleOnUSB;
|
||||
u32 highIDb = titleb->highID, lowIDb = titleb->lowID;
|
||||
bool isUSBb = titleb->isTitleOnUSB;
|
||||
|
||||
if (!promptConfirm("Are you sure?")) return;
|
||||
int slotb = getEmptySlot(titleb->highID, titleb->lowID);
|
||||
if (slotb>=0 && promptConfirm("Backup current savedata first?")) {
|
||||
backupSavedata(titleb, slotb, allusers, common);
|
||||
promptError("Backup done. Now copying Savedata.");
|
||||
}
|
||||
|
||||
char srcPath[PATH_SIZE];
|
||||
char dstPath[PATH_SIZE];
|
||||
const char* path = (isUSB ? "storage_usb:/usr/save" : "storage_mlc:/usr/save");
|
||||
const char* pathb = (isUSBb ? "storage_usb:/usr/save" : "storage_mlc:/usr/save");
|
||||
sprintf(srcPath, "%s/%08x/%08x/%s", path, highID, lowID, "user");
|
||||
sprintf(dstPath, "%s/%08x/%08x/%s", pathb, highIDb, lowIDb, "user");
|
||||
if (!allusers) {
|
||||
char usrPath[16];
|
||||
getUserID(usrPath);
|
||||
u32 srcOffset = strlen(srcPath);
|
||||
u32 dstOffset = strlen(dstPath);
|
||||
if (common) {
|
||||
strcpy(srcPath + srcOffset, "/common");
|
||||
strcpy(dstPath + dstOffset, "/common");
|
||||
if (DumpDir(srcPath, dstPath)!=0) promptError("Common save not found.");
|
||||
}
|
||||
sprintf(srcPath + srcOffset, "/%s", usrPath);
|
||||
sprintf(dstPath + dstOffset, "/%s", usrPath);
|
||||
}
|
||||
if (DumpDir(srcPath, dstPath)!=0) promptError("Copy failed.");
|
||||
promptError(srcPath);
|
||||
promptError(dstPath);
|
||||
}
|
||||
|
||||
void backupSavedata(Title* title, u8 slot, bool allusers, bool common) {
|
||||
|
||||
if (!isSlotEmpty(title->highID, title->lowID, slot) && !promptConfirm("Backup found on this slot. Overwrite it?")) return;
|
||||
|
||||
@@ -22,6 +22,8 @@ typedef struct {
|
||||
char shortName[256];
|
||||
char productCode[32];
|
||||
bool isTitleOnUSB;
|
||||
bool isTitleDupe;
|
||||
u16 dupeID;
|
||||
} Title;
|
||||
|
||||
void console_print_pos(int x, int y, const char* format, ...);
|
||||
@@ -34,6 +36,7 @@ int getLoadiineUserDir(char* out, const char* fullSavePath, const char* userID);
|
||||
|
||||
bool isSlotEmpty(u32 highID, u32 lowID, u8 slot);
|
||||
|
||||
void copySavedata(Title* title, Title* titled, bool allusers, bool common);
|
||||
void backupSavedata(Title* title, u8 slot, bool allusers, bool common);
|
||||
void restoreSavedata(Title* title, u8 slot, bool allusers, bool common);
|
||||
void wipeSavedata(Title* title, bool allusers, bool common);
|
||||
|
||||
Reference in New Issue
Block a user