From 31b7070c9be6755b05e1c97da837e145ccaa0893 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 22 Apr 2022 17:37:16 +0200 Subject: [PATCH] Use the ContentRedirectionModule to redirect /vol/content --- Dockerfile | 4 ++-- Makefile | 9 +++++++-- README.md | 8 ++++---- src/main.cpp | 19 ++++++++++++++++++- src/modpackSelector.cpp | 36 ++++++++++++++++++------------------ src/utils/logger.h | 24 +++++++++++++++++++++--- 6 files changed, 70 insertions(+), 30 deletions(-) diff --git a/Dockerfile b/Dockerfile index 363d90d..086e7c9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM wiiuenv/devkitppc:20211229 +FROM wiiuenv/devkitppc:20220417 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 WORKDIR project \ No newline at end of file diff --git a/Makefile b/Makefile index 36fcdb4..cc516af 100644 --- a/Makefile +++ b/Makefile @@ -39,14 +39,19 @@ CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__ CXXFLAGS := $(CFLAGS) -std=gnu++17 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) CXXFLAGS += -DDEBUG -g CFLAGS += -DDEBUG -g 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 diff --git a/README.md b/README.md index 69502c3..0cbd35c 100644 --- a/README.md +++ b/README.md @@ -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. ## 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 (`[ENVIRONMENT]` is a placeholder for the actual environment name.) 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`. -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 -Before the mods can be loaded, they need to be copied to a SD device. -**In the following "root:/" is corresponding to the root of your SD device**. The basic filepath structure is this: +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 card**. The basic filepath structure is this: ``` root:/sdcafiine/[TITLEID]/[MODPACK]/content/ <-- for game files. Maps to /vol/content/ diff --git a/src/main.cpp b/src/main.cpp index aa05036..d38d9f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,21 +1,38 @@ #include "modpackSelector.h" #include "utils/logger.h" +#include #include #include WUPS_PLUGIN_NAME("SDCafiine"); -WUPS_PLUGIN_DESCRIPTION("Wiiload Server"); +WUPS_PLUGIN_DESCRIPTION("SDCafiine"); WUPS_PLUGIN_VERSION("0.1"); WUPS_PLUGIN_AUTHOR("Maschell"); WUPS_PLUGIN_LICENSE("GPL"); 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 */ ON_APPLICATION_START() { initLogging(); HandleMultiModPacks(OSGetTitleID()); } + ON_APPLICATION_ENDS() { + if (contentLayerHandle != 0) { + ContentRedirection_RemoveFSLayer(contentLayerHandle); + contentLayerHandle = 0; + } deinitLogging(); } \ No newline at end of file diff --git a/src/modpackSelector.cpp b/src/modpackSelector.cpp index ff3c3eb..3bb9c6e 100644 --- a/src/modpackSelector.cpp +++ b/src/modpackSelector.cpp @@ -1,24 +1,22 @@ #include "modpackSelector.h" #include #include -#include #include #include #include #include +#include #include #include #include #include -#include #include #include #define TEXT_SEL(x, text1, text2) ((x) ? (text1) : (text2)) - void ReplaceContent(const std::string &basePath); void HandleMultiModPacks(uint64_t titleID) { @@ -29,22 +27,21 @@ void HandleMultiModPacks(uint64_t titleID) { std::map mounting_points; - 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(); for (int index = 0; index < modTitleDirList.GetFilecount(); 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; } - std::string packageName = curFile; - modTitlePath[packageName] = modTitleIDPath + "/" + curFile; - DEBUG_FUNCTION_LINE("found %s", packageName.c_str()); + const std::string &packageName = curFile; + modTitlePath[packageName] = modTitleIDPath.append("/").append(curFile); + DEBUG_FUNCTION_LINE_VERBOSE("Found %s", packageName.c_str()); } if (modTitlePath.empty()) { @@ -59,9 +56,9 @@ void HandleMultiModPacks(uint64_t titleID) { OSScreenInit(); uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV); 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) { - DEBUG_FUNCTION_LINE("Failed to alloc"); + DEBUG_FUNCTION_LINE_ERR("Failed to alloc screenBuffer"); return; } OSScreenSetBufferEx(SCREEN_TV, (void *) screenBuffer); @@ -164,20 +161,23 @@ void HandleMultiModPacks(uint64_t titleID) { OSScreenFlipBuffersEx(SCREEN_DRC); MEMFreeToMappedMemory(screenBuffer); - - return; } +extern CRLayerHandle contentLayerHandle; void ReplaceContent(const std::string &basePath) { - if (RL_RedirectContentWithFallback(basePath.c_str())) { - DEBUG_FUNCTION_LINE("redirect /vol/content to %s", basePath.c_str()); + auto res = ContentRedirection_AddFSLayer(&contentLayerHandle, + "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 { - 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, ...) { - char *tmp = NULL; + char *tmp = nullptr; va_list va; va_start(va, format); diff --git a/src/utils/logger.h b/src/utils/logger.h index 061d52e..98ea317 100644 --- a/src/utils/logger.h +++ b/src/utils/logger.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -7,12 +8,19 @@ extern "C" { #endif +#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) + #ifdef DEBUG -#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) -#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) - +#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) +#endif #define DEBUG_FUNCTION_LINE(FMT, ARGS...) \ do { \ @@ -24,6 +32,11 @@ extern "C" { WHBLogWritef("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \ } 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 #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_ERR(FMT, ARGS...) \ + do { \ + OSReport("[%23s]%30s@L%04d: ##ERROR## " FMT "\n", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \ + } while (0) + #endif void initLogging();