Use the ContentRedirectionModule to redirect /vol/content

This commit is contained in:
Maschell 2022-04-22 17:37:16 +02:00
parent b97c6bf3c9
commit 31b7070c9b
6 changed files with 70 additions and 30 deletions

View File

@ -1,7 +1,7 @@
FROM wiiuenv/devkitppc:20211229 FROM wiiuenv/devkitppc:20220417
COPY --from=wiiuenv/libmappedmemory:20210924 /artifacts $DEVKITPRO COPY --from=wiiuenv/libmappedmemory:20210924 /artifacts $DEVKITPRO
COPY --from=wiiuenv/librpxloader:20211002 /artifacts $DEVKITPRO COPY --from=wiiuenv/libcontentredirection:20220414 /artifacts $DEVKITPRO
COPY --from=wiiuenv/wiiupluginsystem:20220123 /artifacts $DEVKITPRO COPY --from=wiiuenv/wiiupluginsystem:20220123 /artifacts $DEVKITPRO
WORKDIR project WORKDIR project

View File

@ -39,14 +39,19 @@ CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__
CXXFLAGS := $(CFLAGS) -std=gnu++17 CXXFLAGS := $(CFLAGS) -std=gnu++17
ASFLAGS := -g $(ARCH) ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) -T$(WUMS_ROOT)/share/libmappedmemory.ld -T$(WUMS_ROOT)/share/librpxloader.ld $(WUPSSPECS) LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) -T$(WUMS_ROOT)/share/libmappedmemory.ld $(WUPSSPECS)
ifeq ($(DEBUG),1) ifeq ($(DEBUG),1)
CXXFLAGS += -DDEBUG -g CXXFLAGS += -DDEBUG -g
CFLAGS += -DDEBUG -g CFLAGS += -DDEBUG -g
endif endif
LIBS := -lwups -lwut -lmappedmemory -lrpxloader ifeq ($(VERBOSE_DEBUG),1)
CXXFLAGS += -DVERBOSE_DEBUG -g
CFLAGS += -DVERBOSE_DEBUG -g
endif
LIBS := -lwups -lwut -lmappedmemory -lcontentredirection
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level # list of directories containing libraries, this must be the top level

View File

@ -6,18 +6,18 @@
The main feature of this application is the **on-the-fly replacing of files**, which can be used used to loaded modified content from external media (**SD**). It hooks into the file system functions of the WiiU. Whenever a file is accessed, SDCafiine checks if a (modified) version of it present on the SD device, and redirect the file operations if needed. The main feature of this application is the **on-the-fly replacing of files**, which can be used used to loaded modified content from external media (**SD**). It hooks into the file system functions of the WiiU. Whenever a file is accessed, SDCafiine checks if a (modified) version of it present on the SD device, and redirect the file operations if needed.
## Dependecies ## Dependecies
Requires the [RPXLoadingModule](https://github.com/wiiu-env/RPXLoadingModule) to be loaded. Requires the [ContentRedirectionModule](https://github.com/wiiu-env/ContentRedirectionModule) to be loaded.
## Installation of the modules ## Installation of the modules
(`[ENVIRONMENT]` is a placeholder for the actual environment name.) (`[ENVIRONMENT]` is a placeholder for the actual environment name.)
1. Copy the file `sdcafiine.wps` into `sd:/wiiu/environments/[ENVIRONMENT]/plugins`. 1. Copy the file `sdcafiine.wps` into `sd:/wiiu/environments/[ENVIRONMENT]/plugins`.
2. Requires the [WiiUPluginLoaderBackend](https://github.com/wiiu-env/WiiUPluginLoaderBackend) in `sd:/wiiu/environments/[ENVIRONMENT]/modules`. 2. Requires the [WiiUPluginLoaderBackend](https://github.com/wiiu-env/WiiUPluginLoaderBackend) in `sd:/wiiu/environments/[ENVIRONMENT]/modules`.
3. Requires the [RPXLoadingModule](https://github.com/wiiu-env/RPXLoadingModule) in `sd:/wiiu/environments/[ENVIRONMENT]/modules`. 3. Requires the [ContentRedirectionModule](https://github.com/wiiu-env/ContentRedirectionModule) in `sd:/wiiu/environments/[ENVIRONMENT]/modules`.
### Installation of the mods ### Installation of the mods
Before the mods can be loaded, they need to be copied to a SD device. Before the mods can be loaded, they need to be copied to a SD Card.
**In the following "root:/" is corresponding to the root of your SD device**. The basic filepath structure is this: **In the following "root:/" is corresponding to the root of your SD card**. The basic filepath structure is this:
``` ```
root:/sdcafiine/[TITLEID]/[MODPACK]/content/ <-- for game files. Maps to /vol/content/ root:/sdcafiine/[TITLEID]/[MODPACK]/content/ <-- for game files. Maps to /vol/content/

View File

@ -1,21 +1,38 @@
#include "modpackSelector.h" #include "modpackSelector.h"
#include "utils/logger.h" #include "utils/logger.h"
#include <content_redirection/redirection.h>
#include <coreinit/title.h> #include <coreinit/title.h>
#include <wups.h> #include <wups.h>
WUPS_PLUGIN_NAME("SDCafiine"); WUPS_PLUGIN_NAME("SDCafiine");
WUPS_PLUGIN_DESCRIPTION("Wiiload Server"); WUPS_PLUGIN_DESCRIPTION("SDCafiine");
WUPS_PLUGIN_VERSION("0.1"); WUPS_PLUGIN_VERSION("0.1");
WUPS_PLUGIN_AUTHOR("Maschell"); WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("GPL"); WUPS_PLUGIN_LICENSE("GPL");
WUPS_USE_WUT_DEVOPTAB(); WUPS_USE_WUT_DEVOPTAB();
CRLayerHandle contentLayerHandle __attribute__((section(".data"))) = 0;
INITIALIZE_PLUGIN() {
// But then use libcontentredirection instead.
ContentRedirectionStatus error;
if ((error = ContentRedirection_Init()) != CONTENT_REDIRECTION_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to init ContentRedirection. Error %d", error);
OSFatal("Failed to init ContentRedirection.");
}
}
/* Entry point */ /* Entry point */
ON_APPLICATION_START() { ON_APPLICATION_START() {
initLogging(); initLogging();
HandleMultiModPacks(OSGetTitleID()); HandleMultiModPacks(OSGetTitleID());
} }
ON_APPLICATION_ENDS() { ON_APPLICATION_ENDS() {
if (contentLayerHandle != 0) {
ContentRedirection_RemoveFSLayer(contentLayerHandle);
contentLayerHandle = 0;
}
deinitLogging(); deinitLogging();
} }

View File

@ -1,24 +1,22 @@
#include "modpackSelector.h" #include "modpackSelector.h"
#include <cstdarg> #include <cstdarg>
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include <cstring> #include <cstring>
#include <malloc.h> #include <malloc.h>
#include <map> #include <map>
#include <string> #include <string>
#include <content_redirection/redirection.h>
#include <coreinit/thread.h> #include <coreinit/thread.h>
#include <memory/mappedmemory.h> #include <memory/mappedmemory.h>
#include <coreinit/screen.h> #include <coreinit/screen.h>
#include <fs/DirList.h> #include <fs/DirList.h>
#include <rpxloader.h>
#include <utils/logger.h> #include <utils/logger.h>
#include <vpad/input.h> #include <vpad/input.h>
#define TEXT_SEL(x, text1, text2) ((x) ? (text1) : (text2)) #define TEXT_SEL(x, text1, text2) ((x) ? (text1) : (text2))
void ReplaceContent(const std::string &basePath); void ReplaceContent(const std::string &basePath);
void HandleMultiModPacks(uint64_t titleID) { void HandleMultiModPacks(uint64_t titleID) {
@ -29,22 +27,21 @@ void HandleMultiModPacks(uint64_t titleID) {
std::map<std::string, std::string> mounting_points; std::map<std::string, std::string> mounting_points;
std::string modTitleIDPath = std::string("fs:/vol/external01/sdcafiine/") + TitleIDString; std::string modTitleIDPath = std::string("fs:/vol/external01/sdcafiine/") + TitleIDString;
DirList modTitleDirList(modTitleIDPath.c_str(), nullptr, DirList::Dirs); DirList modTitleDirList(modTitleIDPath, nullptr, DirList::Dirs);
modTitleDirList.SortList(); modTitleDirList.SortList();
for (int index = 0; index < modTitleDirList.GetFilecount(); index++) { for (int index = 0; index < modTitleDirList.GetFilecount(); index++) {
std::string curFile = modTitleDirList.GetFilename(index); std::string curFile = modTitleDirList.GetFilename(index);
//DEBUG_FUNCTION_LINE("curFile %s \n",curFile.c_str());
if (curFile.compare(".") == 0 || curFile.compare("..") == 0) { if (curFile == "." || curFile == "..") {
continue; continue;
} }
std::string packageName = curFile; const std::string &packageName = curFile;
modTitlePath[packageName] = modTitleIDPath + "/" + curFile; modTitlePath[packageName] = modTitleIDPath.append("/").append(curFile);
DEBUG_FUNCTION_LINE("found %s", packageName.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Found %s", packageName.c_str());
} }
if (modTitlePath.empty()) { if (modTitlePath.empty()) {
@ -59,9 +56,9 @@ void HandleMultiModPacks(uint64_t titleID) {
OSScreenInit(); OSScreenInit();
uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV); uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV);
uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC); uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
uint8_t *screenBuffer = (uint8_t *) MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size + screen_buf1_size, 0x100); auto *screenBuffer = (uint8_t *) MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size + screen_buf1_size, 0x100);
if (screenBuffer == nullptr) { if (screenBuffer == nullptr) {
DEBUG_FUNCTION_LINE("Failed to alloc"); DEBUG_FUNCTION_LINE_ERR("Failed to alloc screenBuffer");
return; return;
} }
OSScreenSetBufferEx(SCREEN_TV, (void *) screenBuffer); OSScreenSetBufferEx(SCREEN_TV, (void *) screenBuffer);
@ -164,20 +161,23 @@ void HandleMultiModPacks(uint64_t titleID) {
OSScreenFlipBuffersEx(SCREEN_DRC); OSScreenFlipBuffersEx(SCREEN_DRC);
MEMFreeToMappedMemory(screenBuffer); MEMFreeToMappedMemory(screenBuffer);
return;
} }
extern CRLayerHandle contentLayerHandle;
void ReplaceContent(const std::string &basePath) { void ReplaceContent(const std::string &basePath) {
if (RL_RedirectContentWithFallback(basePath.c_str())) { auto res = ContentRedirection_AddFSLayer(&contentLayerHandle,
DEBUG_FUNCTION_LINE("redirect /vol/content to %s", basePath.c_str()); "SDCafiine Content",
basePath.c_str(),
FS_LAYER_TYPE_CONTENT_MERGE);
if (res == CONTENT_REDIRECTION_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE("Redirect /vol/content to %s", basePath.c_str());
} else { } else {
DEBUG_FUNCTION_LINE("ERROR: Failed to redirect /vol/content to %s", basePath.c_str()); DEBUG_FUNCTION_LINE_ERR("Failed to redirect /vol/content to %s", basePath.c_str());
} }
} }
void console_print_pos(int x, int y, const char *format, ...) { void console_print_pos(int x, int y, const char *format, ...) {
char *tmp = NULL; char *tmp = nullptr;
va_list va; va_list va;
va_start(va, format); va_start(va, format);

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <coreinit/debug.h>
#include <string.h> #include <string.h>
#include <whb/log.h> #include <whb/log.h>
@ -7,12 +8,19 @@
extern "C" { extern "C" {
#endif #endif
#ifdef DEBUG
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
#ifdef DEBUG
#ifdef VERBOSE_DEBUG
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) \
do { \
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0)
#else
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) #define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
#endif
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) \ #define DEBUG_FUNCTION_LINE(FMT, ARGS...) \
do { \ do { \
@ -24,6 +32,11 @@ extern "C" {
WHBLogWritef("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \ WHBLogWritef("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0) } while (0)
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) \
do { \
WHBLogPrintf("[%23s]%30s@L%04d: ##ERROR## " FMT "\n", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0)
#else #else
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0) #define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
@ -32,6 +45,11 @@ extern "C" {
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0) #define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0)
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) \
do { \
OSReport("[%23s]%30s@L%04d: ##ERROR## " FMT "\n", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
} while (0)
#endif #endif
void initLogging(); void initLogging();