Use libmocha, remove CBHC support, bump version

This commit is contained in:
Xpl0itU 2022-08-19 16:53:13 +02:00
parent 72c93e62bf
commit 654c714999
10 changed files with 95 additions and 135 deletions

View File

@ -1,22 +1,23 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${default}",
"/opt/",
"/opt/devkitpro/wut/include",
"/opt/devkitpro/portlibs/ppc/include",
"/opt/devkitpro/portlibs/ppc/include/freetype2",
"${workspaceFolder}/**",
"/opt/devkitpro/wut/usr/include"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++20",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
"configurations": [
{
"name": "Linux",
"includePath": [
"${default}",
"/opt/",
"/opt/devkitpro/wut/include",
"/opt/devkitpro/portlibs/ppc/include",
"/opt/devkitpro/portlibs/ppc/include/freetype2",
"${workspaceFolder}/**",
"/opt/devkitpro/wut/usr/include"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++20",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools"
}
],
"version": 4
}

View File

@ -70,7 +70,12 @@
"fstream": "cpp",
"iostream": "cpp",
"shared_mutex": "cpp",
"valarray": "cpp"
"valarray": "cpp",
"future": "cpp",
"mutex": "cpp",
"semaphore": "cpp",
"stop_token": "cpp",
"thread": "cpp"
},
"cmake.configureOnOpen": false
}

View File

@ -1,10 +1,15 @@
FROM wiiuenv/devkitppc:20220806 AS final
COPY --from=wiiuenv/libiosuhax:latest /artifacts $DEVKITPRO
CMD dkp-pacman -Syyu --noconfirm ppc-freetype
RUN git clone --recursive https://github.com/Crementif/libfat && \
RUN git clone --recursive https://github.com/wiiu-env/libmocha -b devoptab --single-branch && \
cd libmocha && \
make -j$(nproc) && \
make install && \
cd .. && \
rm -rf libmocha
RUN git clone --recursive https://github.com/Xpl0itU/libfat && \
cd libfat && \
make -j$(nproc) wiiu-install && \
cd .. && \

View File

@ -37,7 +37,7 @@ CXXFLAGS := -std=gnu++20 -g -Wall -Wno-int-in-bool-context -Wno-format-overflow
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map)
LIBS := -lfat -lwut -liosuhax -ljansson `freetype-config --libs`
LIBS := -lfat -lwut -lmocha -ljansson `freetype-config --libs`
#-------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level

View File

@ -23,7 +23,7 @@ Reasons to use this over original mod:
Credits:
- Bruno Vinicius, for the icon
- Maschell, for libiosuhax
- Maschell, for libmocha
- Crementif for help with freetype
- V10lator for helping with a lot of stuff
- Vague Rant for testing

View File

@ -3,7 +3,6 @@
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <fat.h>
#include <malloc.h>
#include <algorithm>

View File

@ -5,20 +5,23 @@
#include "draw.h"
#include "json.h"
#include "log_freetype.h"
#include <coreinit/filesystem.h>
#include <coreinit/mcp.h>
#include <coreinit/memdefaultheap.h>
#include <coreinit/thread.h>
#include <cstdio>
#include <dirent.h>
#include <fcntl.h>
#include <iosuhax.h>
#include <iosuhax_devoptab.h>
#include <padscore/kpad.h>
#include <string>
#include <sys/stat.h>
#include <unistd.h>
#include <vpad/input.h>
#include <fat.h>
#include <mocha/mocha.h>
#include <mocha/disc_interface.h>
#define PATH_SIZE 0x400
extern VPADStatus vpad_status;
@ -65,6 +68,8 @@ extern Account *wiiuacc;
extern Account *sdacc;
extern uint8_t wiiuaccn, sdaccn;
bool initFS() __attribute__((__cold__));
void deinitFS() __attribute__((__cold__));
void consolePrintPos(int x, int y, const char *format, ...) __attribute__((hot));
bool promptConfirm(Style st, std::string question);
void promptError(const char *message, ...);
@ -82,7 +87,6 @@ void restoreSavedata(Title *title, uint8_t slot, int8_t sdusers, int8_t allusers
void wipeSavedata(Title *title, int8_t allusers, bool common) __attribute__((hot));
void importFromLoadiine(Title *title, bool common, int version);
void exportToLoadiine(Title *title, bool common, int version);
void setFSAFD(int fd);
int checkEntry(const char *fPath);
int32_t loadFile(const char *fPath, uint8_t **buf) __attribute__((hot));
int32_t loadTitleIcon(Title *title) __attribute__((hot));

View File

@ -2,7 +2,7 @@
<app version="1">
<name>SaveMii WUT</name>
<coder>DaThinkingChair</coder>
<version>1.4.3</version>
<version>1.4.4</version>
<release_date>20220306000000</release_date>
<short_description>WiiU/vWii Save Manager</short_description>
<long_description>WiiU/vWii Save Manager

View File

@ -7,7 +7,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 4
#define VERSION_MICRO 3
#define VERSION_MICRO 4
#define M_OFF 1
static uint8_t slot = 0;
@ -19,33 +19,6 @@ static int cursorb = 0, cursort = 0, scrollb = 0;
static int titleswiiu = 0, titlesvwii = 0;
static const std::array<const char *, 4> sortn = {"None", "Name", "Storage", "Storage+Name"};
void someFunc(IOSError err, void *arg) { (void) arg; }
int MCPHookFd = -1;
int MCPHookOpen() {
//take over mcp thread
MCPHookFd = MCP_Open();
if (MCPHookFd < 0)
return -1;
IOS_IoctlAsync(MCPHookFd, 0x62, (void *) 0, 0, (void *) 0, 0, someFunc, (void *) 0);
//let wupserver start up
OSSleepTicks(OSMillisecondsToTicks(500));
if (IOSUHAX_Open("/dev/mcp") < 0)
return -1;
return 0;
}
void MCPHookClose() {
if (MCPHookFd < 0)
return;
//close down wupserver, return control to mcp
IOSUHAX_Close();
//wait for mcp to return
OSSleepTicks(OSMillisecondsToTicks(500));
MCP_Close(MCPHookFd);
MCPHookFd = -1;
}
template<class It>
static void sortTitle(It titles, It last, int tsort = 1, int sorta = 1) {
switch (tsort) {
@ -135,7 +108,7 @@ static Title *loadWiiUTitles(int run) {
int tNoSave = usable;
for (int i = 0; i <= 1; i++) {
for (uint8_t a = 0; a < 2; a++) {
std::string path = stringFormat("%s:/usr/save/%s", (i == 0) ? "usb" : "mlc", highIDs[a]);
std::string path = stringFormat("%s/usr/save/%s", (i == 0) ? "/vol/storage_usb01" : "/vol/storage_mlc01", highIDs[a]);
DIR *dir = opendir(path.c_str());
if (dir != nullptr) {
struct dirent *data;
@ -143,9 +116,9 @@ static Title *loadWiiUTitles(int run) {
if (data->d_name[0] == '.')
continue;
path = stringFormat("%s:/usr/save/%s/%s/user", (i == 0) ? "usb" : "mlc", highIDs[a], data->d_name);
path = stringFormat("%s/usr/save/%s/%s/user", (i == 0) ? "/vol/storage_usb01" : "/vol/storage_mlc01", highIDs[a], data->d_name);
if (checkEntry(path.c_str()) == 2) {
path = stringFormat("%s:/usr/save/%s/%s/meta/meta.xml", (i == 0) ? "usb" : "mlc", highIDs[a],
path = stringFormat("%s/usr/save/%s/%s/meta/meta.xml", (i == 0) ? "/vol/storage_usb01" : "/vol/storage_mlc01", highIDs[a],
data->d_name);
if (checkEntry(path.c_str()) == 1) {
for (int i = 0; i < usable; i++) {
@ -174,7 +147,7 @@ static Title *loadWiiUTitles(int run) {
for (uint8_t a = 0; a < 2; a++) {
for (int i = 0; i <= 1; i++) {
std::string path = stringFormat("%s:/usr/save/%s", (i == 0) ? "usb" : "mlc", highIDs[a]);
std::string path = stringFormat("%s/usr/save/%s", (i == 0) ? "/vol/storage_usb01" : "/vol/storage_mlc01", highIDs[a]);
DIR *dir = opendir(path.c_str());
if (dir != nullptr) {
struct dirent *data;
@ -182,7 +155,7 @@ static Title *loadWiiUTitles(int run) {
if (data->d_name[0] == '.')
continue;
path = stringFormat("%s:/usr/save/%s/%s/meta/meta.xml", (i == 0) ? "usb" : "mlc", highIDs[a],
path = stringFormat("%s/usr/save/%s/%s/meta/meta.xml", (i == 0) ? "/vol/storage_usb01" : "/vol/storage_mlc01", highIDs[a],
data->d_name);
if (checkEntry(path.c_str()) == 1) {
saves[pos].highID = highIDsNumeric[a];
@ -218,7 +191,7 @@ static Title *loadWiiUTitles(int run) {
uint32_t lowID = saves[i].lowID;
bool isTitleOnUSB = saves[i].dev == 0u;
const std::string path = stringFormat("%s:/usr/%s/%08x/%08x/meta/meta.xml", isTitleOnUSB ? "usb" : "mlc",
const std::string path = stringFormat("%s/usr/%s/%08x/%08x/meta/meta.xml", isTitleOnUSB ? "/vol/storage_usb01" : "/vol/storage_mlc01",
saves[i].found ? "title" : "save", highID, lowID);
titles[titleswiiu].saveInit = !saves[i].found;
@ -292,7 +265,7 @@ static Title *loadWiiTitles() {
std::string pathW;
for (int k = 0; k < 3; k++) {
pathW = stringFormat("slc:/title/%s", highIDs[k]);
pathW = stringFormat("/vol/storage_slccmpt01/title/%s", highIDs[k]);
DIR *dir = opendir(pathW.c_str());
if (dir != nullptr) {
struct dirent *data;
@ -326,7 +299,7 @@ static Title *loadWiiTitles() {
int i = 0;
for (int k = 0; k < 3; k++) {
pathW = stringFormat("slc:/title/%s", highIDs[k]);
pathW = stringFormat("/vol/storage_slccmpt01/title/%s", highIDs[k]);
DIR *dir = opendir(pathW.c_str());
if (dir != nullptr) {
struct dirent *data;
@ -344,7 +317,7 @@ static Title *loadWiiTitles() {
continue;
}
const std::string path = stringFormat("slc:/title/%s/%s/data/banner.bin", highIDs[k], data->d_name);
const std::string path = stringFormat("/vol/storage_slccmpt01/title/%s/%s/data/banner.bin", highIDs[k], data->d_name);
FILE *file = fopen(path.c_str(), "rb");
if (file != nullptr) {
fseek(file, 0x20, SEEK_SET);
@ -443,32 +416,13 @@ auto main() -> int {
WPADEnableURCC(1);
loadWiiUTitles(0);
int res = IOSUHAX_Open(NULL);
if (res < 0) { // Not Tiramisu/Mocha
res = MCPHookOpen();
if (res < 0) {
promptError("IOSUHAX_Open failed.");
flipBuffers();
WHBProcShutdown();
return 0;
}
}
int fsaFd = IOSUHAX_FSA_Open();
if (fsaFd < 0) {
promptError("IOSUHAX_FSA_Open failed.");
if (!initFS()) {
promptError("initFS failed. Please make sure your MochaPayload is up-to-date");
flipBuffers();
WHBProcShutdown();
return 0;
}
setFSAFD(fsaFd);
fatMountSimple("sd", &IOSUHAX_sdio_disc_interface);
mount_fs("slc", fsaFd, "/dev/slccmpt01", "/vol/storage_slccmpt01");
mount_fs("mlc", fsaFd, NULL, "/vol/storage_mlc01");
mount_fs("usb", fsaFd, NULL, "/vol/storage_usb01");
clearBuffers();
Title *wiiutitles = loadWiiUTitles(1);
Title *wiititles = loadWiiTitles();
@ -1019,8 +973,8 @@ auto main() -> int {
continue;
}
}
std::string path = stringFormat("%s:/usr/title/000%x/%x/code/fw.img",
(titles[targ].isTitleOnUSB) ? "usb" : "mlc", titles[targ].highID,
std::string path = stringFormat("%s/usr/title/000%x/%x/code/fw.img",
(titles[targ].isTitleOnUSB) ? "/vol/storage_usb01" : "/vol/storage_mlc01", titles[targ].highID,
titles[targ].lowID);
if ((mode == 0) && (checkEntry(path.c_str()) != 0))
if (!promptConfirm(ST_ERROR, "vWii saves are in the vWii section. Continue?"))
@ -1128,18 +1082,7 @@ auto main() -> int {
unloadTitles(wiititles, titlesvwii);
free(versionList);
fatUnmount("sd");
unmount_fs("slc");
unmount_fs("mlc");
unmount_fs("usb");
IOSUHAX_FSA_Close(fsaFd);
if (MCPHookFd >= 0) {
MCPHookClose();
SYSRelaunchTitle(0, NULL);
} else {
IOSUHAX_Close();
}
deinitFS();
OSScreenShutdown();
WHBLogFreetypeFree();

View File

@ -8,7 +8,6 @@
#define IO_MAX_FILE_BUFFER (1024 * 1024) // 1 MB
int fsaFd = -1;
static char *p1;
Account *wiiuacc;
Account *sdacc;
@ -19,6 +18,9 @@ VPADReadError vpad_error;
KPADStatus kpad[4], kpad_status;
extern FSClient *__wut_devoptab_fs_client;
static FSCmdBlock cmdBlk;
typedef struct {
void *buf;
size_t len;
@ -29,25 +31,26 @@ static file_buffer buffers[16];
static char *fileBuf[2];
static bool buffersInitialized = false;
static std::string newlibToFSA(std::string path) {
if (path[3] == ':') {
switch (path[0]) {
case 'u':
replace(path, "usb:", "/vol/storage_usb01");
break;
case 'm':
replace(path, "mlc:", "/vol/storage_mlc01");
break;
case 's':
replace(path, "slc:", "/vol/storage_slccmpt01");
break;
}
bool initFS() {
FSInit();
FSInitCmdBlock(&cmdBlk);
FSSetCmdPriority(&cmdBlk, 0);
bool ret = Mocha_InitLibrary() == MOCHA_RESULT_SUCCESS;
if (ret)
ret = Mocha_UnlockFSClient(__wut_devoptab_fs_client) == MOCHA_RESULT_SUCCESS;
if (ret) {
Mocha_MountFS("slc", "/dev/slccmpt01", "/vol/storage_slccmpt01");
fatMountSimple("sd", &Mocha_sdio_disc_interface);
return true;
}
return path;
return false;
}
void setFSAFD(int fd) {
fsaFd = fd;
void deinitFS() {
fatUnmount("sd");
Mocha_UnmountFS("slc");
Mocha_DeinitLibrary();
FSShutdown();
}
static void showFileOperation(std::string file_name, std::string file_src, std::string file_dest) {
@ -112,14 +115,14 @@ int32_t loadTitleIcon(Title *title) {
if (isWii) {
if (title->saveInit) {
path = stringFormat("slc:/title/%08x/%08x/data/banner.bin", highID, lowID);
path = stringFormat("/vol/storage_slccmpt01/title/%08x/%08x/data/banner.bin", highID, lowID);
return loadFilePart(path.c_str(), 0xA0, 24576, &title->iconBuf);
}
} else {
if (title->saveInit)
path = stringFormat("%s:/usr/save/%08x/%08x/meta/iconTex.tga", isUSB ? "usb" : "mlc", highID, lowID);
path = stringFormat("%s/usr/save/%08x/%08x/meta/iconTex.tga", isUSB ? "/vol/storage_usb01" : "/vol/storage_mlc01", highID, lowID);
else
path = stringFormat("%s:/usr/title/%08x/%08x/meta/iconTex.tga", isUSB ? "usb" : "mlc", highID, lowID);
path = stringFormat("%s/usr/title/%08x/%08x/meta/iconTex.tga", isUSB ? "/vol/storage_usb01" : "/vol/storage_mlc01", highID, lowID);
return loadFile(path.c_str(), &title->iconBuf);
}
@ -489,7 +492,7 @@ static auto copyFile(std::string pPath, std::string oPath) -> int {
copyFileThreaded(source, dest, sizef);
IOSUHAX_FSA_ChangeMode(fsaFd, newlibToFSA(oPath).c_str(), 0x666);
FSChangeMode(__wut_devoptab_fs_client, &cmdBlk, (char *) oPath.c_str(), (FSMode) 0x666, (FSMode) 0x777, FS_ERROR_FLAG_ALL);
fclose(source);
fclose(dest);
@ -678,7 +681,7 @@ auto hasAccountSave(Title *title, bool inSD, bool iine, uint32_t user, uint8_t s
char srcPath[PATH_SIZE];
if (!isWii) {
if (!inSD) {
const char *path = (isUSB ? "usb:/usr/save" : "mlc:/usr/save");
const char *path = (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save");
if (user == 0) {
sprintf(srcPath, "%s/%08x/%08x/%s/common", path, highID, lowID, "user");
} else if (user == 0xFFFFFFFF) {
@ -708,7 +711,7 @@ auto hasAccountSave(Title *title, bool inSD, bool iine, uint32_t user, uint8_t s
}
} else {
if (!inSD) {
sprintf(srcPath, "slc:/title/%08x/%08x/data", highID, lowID);
sprintf(srcPath, "/vol/storage_slccmpt01/title/%08x/%08x/data", highID, lowID);
} else {
sprintf(srcPath, "sd:/wiiu/backups/%08x%08x/%u", highID, lowID, slot);
}
@ -731,7 +734,7 @@ auto hasCommonSave(Title *title, bool inSD, bool iine, uint8_t slot, int version
std::string srcPath;
if (!inSD) {
const char *path = (isUSB ? "usb:/usr/save" : "mlc:/usr/save");
const char *path = (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save");
srcPath = stringFormat("%s/%08x/%08x/%s/common", path, highID, lowID, "user");
} else {
if (!iine) {
@ -766,8 +769,8 @@ void copySavedata(Title *title, Title *titleb, int8_t allusers, int8_t allusers_
promptError("Backup done. Now copying Savedata.");
}
std::string path = (isUSB ? "usb:/usr/save" : "mlc:/usr/save");
std::string pathb = (isUSBb ? "usb:/usr/save" : "mlc:/usr/save");
std::string path = (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save");
std::string pathb = (isUSBb ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save");
std::string srcPath = stringFormat("%s/%08x/%08x/%s", path.c_str(), highID, lowID, "user");
std::string dstPath = stringFormat("%s/%08x/%08x/%s", pathb.c_str(), highIDb, lowIDb, "user");
createFolder(dstPath.c_str());
@ -805,7 +808,7 @@ void backupAllSave(Title *titles, int count, OSCalendarTime *date) {
uint32_t lowID = titles[i].lowID;
bool isUSB = titles[i].isTitleOnUSB;
bool isWii = ((highID & 0xFFFFFFF0) == 0x00010000);
const std::string path = (isWii ? "slc:/title" : (isUSB ? "usb:/usr/save" : "mlc:/usr/save"));
const std::string path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save"));
std::string srcPath = stringFormat("%s/%08x/%08x/%s", path.c_str(), highID, lowID, isWii ? "data" : "user");
std::string dstPath = stringFormat("sd:/wiiu/backups/batch/%s/%08x%08x", datetime.c_str(), highID, lowID);
@ -824,7 +827,7 @@ void backupSavedata(Title *title, uint8_t slot, int8_t allusers, bool common) {
uint32_t lowID = title->lowID;
bool isUSB = title->isTitleOnUSB;
bool isWii = ((highID & 0xFFFFFFF0) == 0x00010000);
const std::string path = (isWii ? "slc:/title" : (isUSB ? "usb:/usr/save" : "mlc:/usr/save"));
const std::string path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save"));
std::string srcPath = stringFormat("%s/%08x/%08x/%s", path.c_str(), highID, lowID, isWii ? "data" : "user");
std::string dstPath;
if (isWii && (slot == 255))
@ -870,7 +873,7 @@ void restoreSavedata(Title *title, uint8_t slot, int8_t sdusers, int8_t allusers
bool isUSB = title->isTitleOnUSB;
bool isWii = ((highID & 0xFFFFFFF0) == 0x00010000);
std::string srcPath;
const std::string path = (isWii ? "slc:/title" : (isUSB ? "usb:/usr/save" : "mlc:/usr/save"));
const std::string path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save"));
if (isWii && (slot == 255))
srcPath = stringFormat("sd:/savegames/%08x%08x", highID, lowID);
else
@ -905,7 +908,7 @@ void wipeSavedata(Title *title, int8_t allusers, bool common) {
bool isWii = ((highID & 0xFFFFFFF0) == 0x00010000);
char srcPath[PATH_SIZE];
char origPath[PATH_SIZE];
const char *path = (isWii ? "slc:/title" : (isUSB ? "usb:/usr/save" : "mlc:/usr/save"));
const char *path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save"));
sprintf(srcPath, "%s/%08x/%08x/%s", path, highID, lowID, isWii ? "data" : "user");
if ((allusers > -1) && !isWii) {
uint32_t offset = strlen(srcPath);
@ -947,7 +950,7 @@ void importFromLoadiine(Title *title, bool common, int version) {
const char *usrPath = {getUserID().c_str()};
uint32_t srcOffset = strlen(srcPath);
getLoadiineUserDir(srcPath, srcPath, usrPath);
sprintf(dstPath, "%s:/usr/save/%08x/%08x/user", isUSB ? "usb" : "mlc", highID, lowID);
sprintf(dstPath, "%s/usr/save/%08x/%08x/user", isUSB ? "/vol/storage_usb01" : "/vol/storage_mlc01", highID, lowID);
createFolder(dstPath);
uint32_t dstOffset = strlen(dstPath);
sprintf(dstPath + dstOffset, "/%s", usrPath);
@ -976,7 +979,7 @@ void exportToLoadiine(Title *title, bool common, int version) {
const char *usrPath = {getUserID().c_str()};
uint32_t dstOffset = strlen(dstPath);
getLoadiineUserDir(dstPath, dstPath, usrPath);
sprintf(srcPath, "%s:/usr/save/%08x/%08x/user", isUSB ? "usb" : "mlc", highID, lowID);
sprintf(srcPath, "%s/usr/save/%08x/%08x/user", isUSB ? "/vol/storage_usb01" : "/vol/storage_mlc01", highID, lowID);
uint32_t srcOffset = strlen(srcPath);
sprintf(srcPath + srcOffset, "/%s", usrPath);
createFolder(dstPath);