Skip to content

Commit

Permalink
Update for v1.1.0
Browse files Browse the repository at this point in the history
- Fix savedata backup/restore for disc titles
- Separate backups by user
- Add loadiine support
- Move backups folder to sd:/wiiu (you need to move your backups to the
new location)
- Savedata wiping
- Invert task and title selection
- Code clean-up
  • Loading branch information
Ryuzaki-MrL committed Apr 6, 2017
1 parent ba51de6 commit 9dc7fb3
Show file tree
Hide file tree
Showing 6 changed files with 407 additions and 130 deletions.
2 changes: 1 addition & 1 deletion meta/meta.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<app version="1">
<name>SaveMii</name>
<coder>Ryuzaki_MrL</coder>
<version>1.0.0</version>
<version>1.1.0</version>
<release_date>20170404000000</release_date>
<short_description>WiiU/vWii Save Manager</short_description>
<long_description>WiiU/vWii Save Manager
Expand Down
47 changes: 0 additions & 47 deletions src/lib_easy.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,53 +69,6 @@ void uprintf(int x, int y, const char* format, ...) {
curr_line=curr_line_tmp;
}

void pause(int showmsg) {
while(1) {
if (showmsg) {
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
console_print_pos(0, curr_line, "Press any key to continue...\n");
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
}
updatePressedButtons();
if (isPressed(0xFFFF)) break;
}
}

int promptConfirm(const char* question) {
ucls();
const char* msg = "(A) Confirm - (B) Cancel";
int ret = 0;
while(1) {
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
console_print_pos(25 - (strlen(question)>>1), 8, question);
console_print_pos(25 - (strlen(msg)>>1), 10, msg);
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
updatePressedButtons();
if (isPressed(VPAD_BUTTON_A | VPAD_BUTTON_B | VPAD_BUTTON_HOME)) {
ret = isPressed(VPAD_BUTTON_A);
break;
}
}
return ret;
}

void promptError(const char* message) {
ucls();
while(1) {
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
console_print_pos(25 - (strlen(message)>>1), 9, message);
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
updatePressedButtons();
if (isPressed(0xFFFF)) break;
}
}

int64_t uGetTime() {
return OSGetTime()/SECS_TO_TICKS(1);
}
Expand Down
3 changes: 0 additions & 3 deletions src/lib_easy.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ void ucls();
void ScreenInit();
void flipBuffers();
void uprintf(int x, int y, const char* format, ...);
void pause(int showmsg);
int promptConfirm(const char* question);
void promptError(const char* message);
int64_t uGetTime();
void updatePressedButtons();
void updateHeldButtons();
Expand Down
118 changes: 78 additions & 40 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,17 @@
#include "savemng.h"

#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_MINOR 1
#define VERSION_MICRO 0

u8 slot = 0;
bool allusers = 0, common = 1;
int menu = 0, mode = 0, task = 0, targ = 0;
int cursor = 0, scroll = 0;
int titleswiiu = 0, titlesvwii = 0;

typedef struct {
u32 highID;
u32 lowID;
char shortname[256];
bool isTitleOnUSB;
} Title;

//just to be able to call async
void someFunc(void *arg)
{
void someFunc(void *arg) {
(void)arg;
}

Expand Down Expand Up @@ -59,6 +52,7 @@ void MCPHookClose() {

Title* loadWiiUTitles() {

// Source: haxchi installer
int mcp_handle = MCP_Open();
int count = MCP_TitleCount(mcp_handle);
int listSize = count*0x61;
Expand All @@ -79,7 +73,7 @@ Title* loadWiiUTitles() {
char* element = tList+(i*0x61);
u32 highID = *(u32*)(element), lowID = *(u32*)(element+4);
if (highID!=0x00050000) continue;
bool isTitleOnUSB = memcmp(element+0x56,"mlc",4)!=0;
bool isTitleOnUSB = (memcmp(element+0x56,"usb",4)==0);
char path[255];
memset(path, 0, 255);
sprintf(path, "storage_%s:/usr/title/%08x/%08x/meta/meta.xml", isTitleOnUSB ? "usb" : "mlc", highID, lowID);
Expand All @@ -101,11 +95,14 @@ Title* loadWiiUTitles() {
for (cur_node = root_element->children; cur_node; cur_node = cur_node->next) {
if (
(cur_node->type != XML_ELEMENT_NODE) ||
(memcmp(cur_node->name, "shortname_en", 13) != 0) ||
(xmlNodeGetContent(cur_node) == NULL) ||
(!strlen((char*)xmlNodeGetContent(cur_node)))
) continue;
strcpy(titles[titleswiiu].shortname, (char*)xmlNodeGetContent(cur_node));

if (!memcmp(cur_node->name, "shortname_en", 13))
strcpy(titles[titleswiiu].shortName, (char*)xmlNodeGetContent(cur_node));
if (!memcmp(cur_node->name, "product_code", 13))
strcpy(titles[titleswiiu].productCode, (char*)(xmlNodeGetContent(cur_node)+6));
}

xmlFreeDoc(tmp);
Expand Down Expand Up @@ -133,8 +130,8 @@ Title* loadWiiUTitles() {

Title* loadWiiTitles() {

struct dirent *dirent = NULL;
DIR *dir = NULL;
struct dirent* dirent = NULL;
DIR* dir = NULL;

dir = opendir("slccmpt01:/title/00010000");
if (dir == NULL) {
Expand Down Expand Up @@ -168,7 +165,7 @@ Title* loadWiiTitles() {
fread(bnrBuf, 0x02, 0x20, bnrFile);
fclose(bnrFile);
for (int j = 0, k = 0; j < 0x20; j++) {
titles[i].shortname[k++] = (char)bnrBuf[j];
titles[i].shortName[k++] = (char)bnrBuf[j];
}
free(bnrBuf);
}
Expand All @@ -192,7 +189,7 @@ Title* loadWiiTitles() {
}

void unloadTitles(Title* titles) {
free(titles);
if (titles) free(titles);
}

/* Entry point */
Expand All @@ -206,6 +203,7 @@ int Menu_Main(void) {
}
if (res < 0) {
promptError("IOSUHAX_Open failed.");
unmount_sd_fat("sd");
return EXIT_SUCCESS;
}

Expand All @@ -214,6 +212,7 @@ int Menu_Main(void) {
int fsaFd = IOSUHAX_FSA_Open();
if (fsaFd < 0) {
promptError("IOSUHAX_FSA_Open failed.");
unmount_sd_fat("sd");
if (mcp_hook_fd >= 0) MCPHookClose();
else IOSUHAX_Close();
return EXIT_SUCCESS;
Expand All @@ -226,8 +225,9 @@ int Menu_Main(void) {
ucls();
Title* wiiutitles = loadWiiUTitles();
Title* wiititles = loadWiiTitles();
int* versionList = (int*)malloc(0x100*sizeof(int));

while(1) {
while(wiiutitles!=NULL && wiititles!=NULL) {

OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
Expand All @@ -237,29 +237,46 @@ int Menu_Main(void) {

Title* titles = mode ? wiititles : wiiutitles;
int count = mode ? titlesvwii : titleswiiu;
int entrycount = 0;

switch(menu) {
case 0: { // Main Menu
entrycount = 2;
console_print_pos(0, 2, " Wii U Save Management");
console_print_pos(0, 3, " vWii Save Management");
console_print_pos(0, 2 + cursor, "->");
} break;
case 1: { // WiiU/vWii Save Management
console_print_pos(0, 2, " Backup savedata");
console_print_pos(0, 3, " Restore savedata");
// console_print_pos(0, 4, " Wipe savedata");
console_print_pos(0, 2 + cursor, "->");
} break;
case 2: { // Wii/Wii U Title List
case 1: { // Select Title
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", titles[i+scroll].shortname);
if (strlen(titles[i+scroll].shortName)) console_print_pos(0, i+2, " %s", titles[i+scroll].shortName);
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 3: { // Slot select
console_print_pos(0, 2, "Press LEFT or RIGHT to select slot.");
console_print_pos(0, 3, " < %03u >", slot);
case 2: { // Select Task
entrycount = 3 + 2*(mode==0);
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");
}
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);
else console_print_pos(0, 3, " < %03u >", slot);
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, 8, "Include 'common' save?");
console_print_pos(0, 9, " < %s >", common ? "yes" : "no ");
console_print_pos(0, 3 + cursor*3, "->");
}
} break;
}

Expand All @@ -272,8 +289,6 @@ int Menu_Main(void) {
updatePressedButtons();
updateHeldButtons();

int entrycount = ((menu==0) ? 2 : ((menu==1) ? 2 : count));

if (isPressed(VPAD_BUTTON_DOWN) || isHeld(VPAD_BUTTON_DOWN)) {
if (entrycount<=14) cursor = (cursor + 1) % entrycount;
else if (cursor < 6) cursor++;
Expand All @@ -289,31 +304,53 @@ int Menu_Main(void) {
}

if (isPressed(VPAD_BUTTON_LEFT) || isHeld(VPAD_BUTTON_LEFT)) {
if (menu==3) slot--;
if (menu==3) {
switch(cursor) {
case 0: slot--; break;
case 1: allusers^=1; break;
case 2: common^=1; break;
}
}
usleep(100000);
} else if (isPressed(VPAD_BUTTON_RIGHT) || isHeld(VPAD_BUTTON_RIGHT)) {
if (menu==3) slot++;
if (menu==3) {
switch(cursor) {
case 0: slot++; break;
case 1: allusers^=1; break;
case 2: common^=1; break;
}
}
usleep(100000);
}

if (isPressed(VPAD_BUTTON_A)) {
ucls();
if (menu<3) {
if (menu==0) mode = cursor;
if (menu==1) task = cursor;
if (menu==2) targ = cursor+scroll;
if (menu==1) targ = cursor+scroll;
if (menu==2) {
task = cursor;
if (task > 2) {
char gamePath[PATH_SIZE];
memset(versionList, 0, 0x100*sizeof(int));
if (getLoadiineGameSaveDir(gamePath, titles[targ].productCode)==0)
getLoadiineSaveVersionList(versionList, gamePath);
}
}
menu++;
cursor = scroll = 0;
} else {
switch(task) {
case 0: backupSavedata(titles[targ].highID, titles[targ].lowID, titles[targ].isTitleOnUSB, slot); break;
case 1: restoreSavedata(titles[targ].highID, titles[targ].lowID, titles[targ].isTitleOnUSB, slot); break;
case 2: wipeSavedata(titles[targ].highID, titles[targ].lowID, titles[targ].isTitleOnUSB); break;
case 0: backupSavedata(&titles[targ], slot, allusers, common); break;
case 1: restoreSavedata(&titles[targ], slot, allusers, common); break;
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;
}
}
} else if (isPressed(VPAD_BUTTON_B)) {
} else if (isPressed(VPAD_BUTTON_B) && menu>0) {
ucls();
if (menu>0) menu--;
menu--;
cursor = scroll = 0;
}

Expand All @@ -323,6 +360,7 @@ int Menu_Main(void) {

unloadTitles(wiiutitles);
unloadTitles(wiititles);
free(versionList);

fatUnmount("sd");
fatUnmount("usb");
Expand Down
Loading

0 comments on commit 9dc7fb3

Please sign in to comment.