Added new hook-methods, added more information to the example_plugin

- Split up the WUPS includes into multiple seperate files, renamed some structs
- Added the hooks functions. (INITIALIZE_PLUGIN, DEINITIALIZE_PLUGIN, ON_VYSNC, ON_APP_STATUS_CHANGED, ON_APPLICATION_ENDING). INITIALZE is now "ON_APPLICATION_START". See the example for more information.
- Updated all plugins to fit the new hook. Some profit of the new hooks and are simpler now. (For example SwipSwapMe doesn't need to check if it's the first boot)
- arguments of the ON_APPLICATION_START have changed. It's not a pointer anymore and now has the boolean fields sd_mounted/usb_mounted which indicate if the device was mounted and it available via sd:/ or usb:/
- Some minor cleanups and formatting.
This commit is contained in:
Maschell 2018-02-25 13:07:49 +01:00
parent a12db00fd9
commit 2aadfcf68e
29 changed files with 1108 additions and 465 deletions

View File

@ -29,6 +29,17 @@ extern "C" {
#define DEFAULT_LANG_PATH DEFAULT_WUPSLOADER_PATH "/languages" #define DEFAULT_LANG_PATH DEFAULT_WUPSLOADER_PATH "/languages"
#define LANGUAGE_FILE_EXT ".lang" #define LANGUAGE_FILE_EXT ".lang"
#define WUPS_SDUSB_MOUNTED_NONE 0
#define WUPS_SDUSB_MOUNTED_FAKE (1<<0)
#define WUPS_SDUSB_MOUNTED_OS_SD (1<<1)
#define WUPS_SDUSB_LIBIOSU_LOADED (1<<2)
#define WUPS_SD_MOUNTED_LIBFAT (1<<3)
#define WUPS_USB_MOUNTED_LIBFAT (1<<4)
#define WUPS_USB_MOUNTED_LIBNTFS (1<<5)
#define WUPS_SD_MOUNTED (WUPS_SDUSB_MOUNTED_OS_SD | WUPS_SD_MOUNTED_LIBFAT)
#define WUPS_USB_MOUNTED (WUPS_USB_MOUNTED_LIBFAT)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -52,7 +52,7 @@
#include "version.h" #include "version.h"
#include "settings/CSettings.h" #include "settings/CSettings.h"
static void ApplyPatches(); static void ApplyPatchesAndCallHookStartingApp();
void CallHook(wups_loader_hook_type_t hook_type); void CallHook(wups_loader_hook_type_t hook_type);
static void RestorePatches(); static void RestorePatches();
s32 isInMiiMakerHBL(); s32 isInMiiMakerHBL();
@ -80,7 +80,7 @@ extern "C" int Menu_Main(int argc, char **argv) {
DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION); DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION);
setup_os_exceptions(); //setup_os_exceptions();
Init(); Init();
@ -88,6 +88,7 @@ extern "C" int Menu_Main(int argc, char **argv) {
//Reset everything when were going back to the Mii Maker //Reset everything when were going back to the Mii Maker
if(isInMiiMakerHBL()) { if(isInMiiMakerHBL()) {
CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN);
// Restore patches as the patched functions could change. // Restore patches as the patched functions could change.
RestorePatches(); RestorePatches();
@ -112,73 +113,36 @@ extern "C" int Menu_Main(int argc, char **argv) {
PluginLoader::destroyInstance(); PluginLoader::destroyInstance();
} }
DEBUG_FUNCTION_LINE("Apply patches.\n");
ApplyPatches();
if(!isInMiiMakerHBL()) { if(!isInMiiMakerHBL()) {
CallHook(WUPS_LOADER_HOOK_INIT_FUNCTION); //CallHook(WUPS_LOADER_HOOK_STARTING_APPLICATION);
DEBUG_FUNCTION_LINE("Apply patches.\n");
ApplyPatchesAndCallHookStartingApp();
return EXIT_RELAUNCH_ON_LOAD; return EXIT_RELAUNCH_ON_LOAD;
} }
if(result == APPLICATION_CLOSE_APPLY) { if(result == APPLICATION_CLOSE_APPLY) {
CallHook(WUPS_LOADER_HOOK_INIT_PLUGIN);
DEBUG_FUNCTION_LINE("Loading the system menu.\n"); DEBUG_FUNCTION_LINE("Loading the system menu.\n");
DeInit();
SYSLaunchMenu(); SYSLaunchMenu();
return EXIT_RELAUNCH_ON_LOAD; return EXIT_RELAUNCH_ON_LOAD;
} }
DEBUG_FUNCTION_LINE("Going back to the Homebrew Launcher\n"); DEBUG_FUNCTION_LINE("Going back to the Homebrew Launcher\n");
RestorePatches(); RestorePatches();
CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN);
DeInit(); DeInit();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void ApplyPatches() { void ApplyPatchesAndCallHookStartingApp() {
PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks); PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks);
for(int plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) { for(int plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
CallHookEx(WUPS_LOADER_HOOK_STARTING_APPLICATION,plugin_index);
new_PatchInvidualMethodHooks(&gbl_replacement_data.plugin_data[plugin_index]); new_PatchInvidualMethodHooks(&gbl_replacement_data.plugin_data[plugin_index]);
} }
} }
void CallHook(wups_loader_hook_type_t hook_type) {
for(int plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",plugin_data->plugin_name);
DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks);
for(int j=0; j<plugin_data->number_used_hooks; j++) {
replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
if(hook_data->type == hook_type) {
DEBUG_FUNCTION_LINE("Calling hook of type %d\n",hook_data->type);
void * func_ptr = hook_data->func_pointer;
//TODO: Switch cases depending on arguments etc.
// Adding arguments!
if(func_ptr != NULL) {
if(hook_type == WUPS_LOADER_HOOK_INIT_FUNCTION) {
DEBUG_FUNCTION_LINE("Calling it! %08X\n",func_ptr);
wups_loader_init_args_t args;
args.device_mounted = gSDInitDone;
args.fs_wrapper.open_repl = (const void*)&open;
args.fs_wrapper.close_repl = (const void*)&close;
args.fs_wrapper.write_repl = (const void*)&write;
args.fs_wrapper.read_repl = (const void*)&read;
args.fs_wrapper.lseek_repl = (const void*)&lseek;
args.fs_wrapper.stat_repl = (const void*)&stat;
args.fs_wrapper.fstat_repl = (const void*)&fstat;
args.fs_wrapper.opendir_repl = (const void*)&opendir;
args.fs_wrapper.closedir_repl = (const void*)&closedir;
args.fs_wrapper.readdir_repl = (const void*)&readdir;
args.overlayfunction_ptr = (const void*)&overlay_helper;
( (void (*)(wups_loader_init_args_t *))((unsigned int*)func_ptr) )(&args);
}
} else {
DEBUG_FUNCTION_LINE("Was not defined\n");
}
}
}
}
}
void DeInit() { void DeInit() {
DeInit_SD_USB(); DeInit_SD_USB();
} }
@ -239,7 +203,6 @@ void Init_SD_USB() {
gSDInitDone |= WUPS_USB_MOUNTED_LIBFAT; gSDInitDone |= WUPS_USB_MOUNTED_LIBFAT;
} }
} }
DEBUG_FUNCTION_LINE("%08X\n",gSDInitDone);
} }
void DeInit_SD_USB() { void DeInit_SD_USB() {

View File

@ -12,17 +12,19 @@
extern "C" { extern "C" {
#endif #endif
u32 * getFromGX2Buffer(struct buffer_store store, u32 size){ u32 * getFromGX2Buffer(struct buffer_store store, u32 size) {
if(store.buffer != NULL){ if(store.buffer != NULL) {
DEBUG_FUNCTION_LINE("We try to use the GX2 buffer. Needed space %08X (%d kb), available %08X (%d kb).\n",size,size/1024,store.buffer_size,store.buffer_size/1024); DEBUG_FUNCTION_LINE("We try to use the GX2 buffer. Needed space %08X (%d kb), available %08X (%d kb).\n",size,size/1024,store.buffer_size,store.buffer_size/1024);
if(store.buffer_size >= size){ if(store.buffer_size >= size) {
memset(store.buffer,0,store.buffer_size);
GX2Invalidate(GX2_INVALIDATE_CPU, store.buffer, store.buffer_size);
return (u32*) store.buffer; return (u32*) store.buffer;
} }
} }
return NULL; return NULL;
} }
void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback){ void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callback) {
if(callback == NULL) return; if(callback == NULL) return;
if(!OSIsHomeButtonMenuEnabled()) return; // This pauses the game. Make sure to only do it when the home button is allowed. if(!OSIsHomeButtonMenuEnabled()) return; // This pauses the game. Make sure to only do it when the home button is allowed.
@ -36,59 +38,61 @@ void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callbac
bool allocated_tv = false; bool allocated_tv = false;
bool allocated_drc = false; bool allocated_drc = false;
if(screen == WUPS_OVERLAY_DRC_ONLY){ if(screen == WUPS_OVERLAY_DRC_ONLY) {
u32 screen_buf1_size = OSScreenGetBufferSizeEx(1); u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size); screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size);
if(screenbuffer1 == NULL){ if(screenbuffer1 == NULL) {
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n"); DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n");
screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size); screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size);
if(screenbuffer1 != NULL){ if(screenbuffer1 != NULL) {
memset(screenbuffer1,0,screen_buf1_size);
DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n"); DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n");
allocated_drc = true; allocated_drc = true;
} }
} }
} else if(screen == WUPS_OVERLAY_TV_ONLY){ } else if(screen == WUPS_OVERLAY_TV_ONLY) {
u32 screen_buf0_size = OSScreenGetBufferSizeEx(0); u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size); screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size);
if(screenbuffer0 == NULL){ if(screenbuffer0 == NULL) {
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n"); DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n");
screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size); screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size);
if(screenbuffer0 != NULL){ if(screenbuffer0 != NULL) {
memset(screenbuffer0,0,screen_buf0_size);
DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n"); DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n");
allocated_tv = true; allocated_tv = true;
} }
} }
} else if( screen == WUPS_OVERLAY_DRC_AND_TV || WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO){ } else if( screen == WUPS_OVERLAY_DRC_AND_TV || WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO) {
// TV Buffer init. // TV Buffer init.
u32 screen_buf0_size = OSScreenGetBufferSizeEx(0); u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size); screenbuffer0 = getFromGX2Buffer(tv_store,screen_buf0_size);
if(screenbuffer0 == NULL){ if(screenbuffer0 == NULL) {
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n"); DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the TV.\n");
screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size); screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size);
if(screenbuffer0 != NULL){ if(screenbuffer0 != NULL) {
memset(screenbuffer0,0,screen_buf0_size);
DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n"); DEBUG_FUNCTION_LINE("Successfully allocated TV buffer!.\n");
allocated_tv = true; allocated_tv = true;
} }
} }
// DRC Buffer init. // DRC Buffer init.
u32 screen_buf1_size = OSScreenGetBufferSizeEx(1); u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
// Doesn't fit in the GX2 DRC buffer, we don't need to check it. // Doesn't fit in the GX2 DRC buffer, we don't need to check it.
DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n"); DEBUG_FUNCTION_LINE("We need to try to allocate buffer for the DRC.\n");
screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size); screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size);
if(screenbuffer1 != NULL){ if(screenbuffer1 != NULL) {
DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n"); DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n");
allocated_drc = true; allocated_drc = true;
} }
if(screenbuffer1 == NULL){ // FAILED to allocate, if(screenbuffer1 == NULL) { // FAILED to allocate,
if(screen == WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO){ if(screen == WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO) {
DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n"); DEBUG_FUNCTION_LINE("Successfully allocated DRC buffer!.\n");
//but we can use the TV buffer from GX2. //but we can use the TV buffer from GX2.
if(!allocated_tv){ // Make sure it's not allocated if(!allocated_tv) { // Make sure it's not allocated
screenbuffer0 = NULL; // Bye bye screenbuffer0 = NULL; // Bye bye
} }
screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size); // Use it! Hopefully this works. screenbuffer1 = getFromGX2Buffer(tv_store,screen_buf1_size); // Use it! Hopefully this works.
@ -96,59 +100,75 @@ void overlay_helper(wups_overlay_options_type_t screen, overlay_callback callbac
} }
} }
if(screenbuffer0 == NULL && screenbuffer1 == NULL){ if(screenbuffer0 == NULL && screenbuffer1 == NULL) {
goto error_exit; goto error_exit;
} }
if(screenbuffer0 != NULL){ OSScreenSetBufferEx(0, (void *)screenbuffer0); } if(screenbuffer0 != NULL) {
if(screenbuffer1 != NULL){ OSScreenSetBufferEx(1, (void *)screenbuffer1); } OSScreenSetBufferEx(0, (void *)screenbuffer0);
}
if(screenbuffer1 != NULL) {
OSScreenSetBufferEx(1, (void *)screenbuffer1);
}
if(screenbuffer0 != NULL){ OSScreenEnableEx(0, 1); } if(screenbuffer0 != NULL) {
if(screenbuffer1 != NULL){ OSScreenEnableEx(1, 1); } OSScreenEnableEx(0, 1);
}
if(screenbuffer1 != NULL) {
OSScreenEnableEx(1, 1);
}
// Clear screens // Clear screens
if(screenbuffer0 != NULL){ OSScreenClearBufferEx(0, 0); } if(screenbuffer0 != NULL) {
if(screenbuffer1 != NULL){ OSScreenClearBufferEx(1, 0); } OSScreenClearBufferEx(0, 0);
}
if(screenbuffer1 != NULL) {
OSScreenClearBufferEx(1, 0);
}
// Flip buffers // Flip buffers
if(screenbuffer0 != NULL){ OSScreenFlipBuffersEx(0); } if(screenbuffer0 != NULL) {
if(screenbuffer1 != NULL){ OSScreenFlipBuffersEx(1); } OSScreenFlipBuffersEx(0);
}
if(screenbuffer1 != NULL) {
OSScreenFlipBuffersEx(1);
}
wups_overlay_options_type_t real_screen_type; wups_overlay_options_type_t real_screen_type;
if(screenbuffer0 != NULL){ if(screenbuffer0 != NULL) {
if(screenbuffer1 != NULL){ if(screenbuffer1 != NULL) {
real_screen_type = WUPS_OVERLAY_DRC_AND_TV; real_screen_type = WUPS_OVERLAY_DRC_AND_TV;
} else { } else {
real_screen_type = WUPS_OVERLAY_TV_ONLY; real_screen_type = WUPS_OVERLAY_TV_ONLY;
} }
} else if(screenbuffer1 != NULL){ } else if(screenbuffer1 != NULL) {
real_screen_type = WUPS_OVERLAY_DRC_ONLY; real_screen_type = WUPS_OVERLAY_DRC_ONLY;
} else { } else {
real_screen_type = WUPS_OVERLAY_NONE; real_screen_type = WUPS_OVERLAY_NONE;
} }
// call the callback. // call the callback.
if(real_screen_type != WUPS_OVERLAY_NONE){ if(real_screen_type != WUPS_OVERLAY_NONE) {
callback(real_screen_type); callback(real_screen_type);
} }
if(tv_store.buffer != NULL){ if(tv_store.buffer != NULL) {
GX2SetTVBuffer(tv_store.buffer,tv_store.buffer_size,tv_store.mode,tv_store.surface_format,tv_store.buffering_mode); GX2SetTVBuffer(tv_store.buffer,tv_store.buffer_size,tv_store.mode,tv_store.surface_format,tv_store.buffering_mode);
} }
if(drc_store.buffer != NULL){ if(drc_store.buffer != NULL) {
GX2SetDRCBuffer(drc_store.buffer,drc_store.buffer_size,drc_store.mode,drc_store.surface_format,drc_store.buffering_mode); GX2SetDRCBuffer(drc_store.buffer,drc_store.buffer_size,drc_store.mode,drc_store.surface_format,drc_store.buffering_mode);
} }
error_exit: error_exit:
if(allocated_tv){ if(allocated_tv) {
free(screenbuffer0); free(screenbuffer0);
screenbuffer0 = NULL; screenbuffer0 = NULL;
} }
if(allocated_drc){ if(allocated_drc) {
free(screenbuffer1); free(screenbuffer1);
screenbuffer1 = NULL; screenbuffer1 = NULL;
} }

View File

@ -4,10 +4,13 @@
#include "hooks_patcher.h" #include "hooks_patcher.h"
#include "myutils/overlay_helper.h" #include "myutils/overlay_helper.h"
#include "main.h" #include "main.h"
#include "utils.h"
DECL(void, __PPCExit, void) { DECL(void, __PPCExit, void) {
DEBUG_FUNCTION_LINE("__PPCExit\n"); DEBUG_FUNCTION_LINE("__PPCExit\n");
CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
DeInit(); DeInit();
real___PPCExit(); real___PPCExit();
@ -18,6 +21,7 @@ DECL(u32, ProcUIProcessMessages, u32 u) {
if(res != gAppStatus) { if(res != gAppStatus) {
DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res); DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res);
gAppStatus = res; gAppStatus = res;
CallHook(WUPS_LOADER_HOOK_APP_STATUS_CHANGED);
} }
return res; return res;
@ -44,6 +48,7 @@ DECL(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 sur
} }
DECL(void, GX2WaitForVsync, void) { DECL(void, GX2WaitForVsync, void) {
CallHook(WUPS_LOADER_HOOK_VSYNC);
real_GX2WaitForVsync(); real_GX2WaitForVsync();
} }
@ -52,7 +57,7 @@ hooks_magic_t method_hooks_hooks[] __attribute__((section(".data"))) = {
MAKE_MAGIC(ProcUIProcessMessages, LIB_PROC_UI, DYNAMIC_FUNCTION), MAKE_MAGIC(ProcUIProcessMessages, LIB_PROC_UI, DYNAMIC_FUNCTION),
MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION), MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION),
MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION), MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION), MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION),
}; };

View File

@ -185,8 +185,6 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
return false; return false;
} }
DEBUG_FUNCTION_LINE("\n");
u32 curAddress = (u32) endAddress; u32 curAddress = (u32) endAddress;
Elf_Scn *scn; Elf_Scn *scn;

View File

@ -6,8 +6,12 @@
#include <malloc.h> #include <malloc.h>
#include <utils/logger.h> #include <utils/logger.h>
#include <wups.h>
#include "utils.h" #include "utils.h"
#include "common/common.h"
#include "common/retain_vars.h"
#include "myutils/overlay_helper.h"
// https://gist.github.com/ccbrown/9722406 // https://gist.github.com/ccbrown/9722406
void dumpHex(const void* data, size_t size) { void dumpHex(const void* data, size_t size) {
@ -38,3 +42,78 @@ void dumpHex(const void* data, size_t size) {
} }
} }
} }
void CallHook(wups_loader_hook_type_t hook_type) {
CallHookEx(hook_type,-1);
}
void CallHookEx(wups_loader_hook_type_t hook_type, s32 plugin_index_needed) {
for(int plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
if(plugin_index_needed != -1 && plugin_index_needed != plugin_index) {
continue;
}
//DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",plugin_data->plugin_name);
//DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks);
for(int j=0; j<plugin_data->number_used_hooks; j++) {
replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
if(hook_data->type == hook_type) {
DEBUG_FUNCTION_LINE("Calling hook of type %d for plugin %s\n",hook_data->type,plugin_data->plugin_name);
void * func_ptr = hook_data->func_pointer;
//TODO: Switch cases depending on arguments etc.
// Adding arguments!
if(func_ptr != NULL) {
if(hook_type == WUPS_LOADER_HOOK_INIT_PLUGIN) {
wups_loader_init_plugin_args_t args;
args.fs_wrapper.open_repl = (const void*)&open;
args.fs_wrapper.close_repl = (const void*)&close;
args.fs_wrapper.write_repl = (const void*)&write;
args.fs_wrapper.read_repl = (const void*)&read;
args.fs_wrapper.lseek_repl = (const void*)&lseek;
args.fs_wrapper.stat_repl = (const void*)&stat;
args.fs_wrapper.fstat_repl = (const void*)&fstat;
args.fs_wrapper.opendir_repl = (const void*)&opendir;
args.fs_wrapper.closedir_repl = (const void*)&closedir;
args.fs_wrapper.readdir_repl = (const void*)&readdir;
args.overlayfunction_ptr = (const void*)&overlay_helper;
((void (*)(wups_loader_init_plugin_args_t))((unsigned int*)func_ptr) )(args);
} else if(hook_type == WUPS_LOADER_HOOK_DEINIT_PLUGIN) {
((void (*)(void))((unsigned int*)func_ptr) )();
} else if(hook_type == WUPS_LOADER_HOOK_STARTING_APPLICATION) {
wups_loader_app_started_args_t args;
memset(&args,0,sizeof(args));
if(gSDInitDone & WUPS_SD_MOUNTED) {
args.sd_mounted = true;
}
if(gSDInitDone & WUPS_USB_MOUNTED) {
args.usb_mounted = true;
}
((void (*)(wups_loader_app_started_args_t))((unsigned int*)func_ptr) )(args);
} else if(hook_type == WUPS_LOADER_HOOK_ENDING_APPLICATION) {
((void (*)(void))((unsigned int*)func_ptr))();
} else if(hook_type == WUPS_LOADER_HOOK_VSYNC) {
((void (*)(void))((unsigned int*)func_ptr))();
} else if(hook_type == WUPS_LOADER_HOOK_APP_STATUS_CHANGED) {
wups_loader_app_status_t status;
if(gAppStatus == 0) {
status = WUPS_APP_STATUS_FOREGROUND;
} else if(gAppStatus == 2) {
status = WUPS_APP_STATUS_BACKGROUND;
} else if(gAppStatus == 3) {
status = WUPS_APP_STATUS_CLOSED;
} else {
status = WUPS_APP_STATUS_UNKNOWN;
}
((void (*)(wups_loader_app_status_t))((unsigned int*)func_ptr))(status);
} else {
DEBUG_FUNCTION_LINE("ERROR: HOOK TYPE WAS NOT IMPLEMENTED %08X \n",hook_type);
}
} else {
DEBUG_FUNCTION_LINE("Failed to call hook. It was not defined\n");
}
}
}
}
}

View File

@ -6,7 +6,12 @@
extern "C" { extern "C" {
#endif #endif
#include <wups.h>
void dumpHex(const void* data, size_t size); void dumpHex(const void* data, size_t size);
void CallHook(wups_loader_hook_type_t hook_type);
void CallHookEx(wups_loader_hook_type_t hook_type, s32 plugin_index_needed);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -6,21 +6,120 @@
#include "dynamic_libs/fs_functions.h" #include "dynamic_libs/fs_functions.h"
#include "utils/logger.h" #include "utils/logger.h"
/**
Mandatory plugin information.
If not set correctly, the loader will refuse to use the plugin.
**/
WUPS_PLUGIN_NAME("Example plugin"); WUPS_PLUGIN_NAME("Example plugin");
WUPS_PLUGIN_DESCRIPTION("This is just an example plugin and will log the FSOpenFile function."); WUPS_PLUGIN_DESCRIPTION("This is just an example plugin and will log the FSOpenFile function.");
WUPS_PLUGIN_VERSION("v1.0"); WUPS_PLUGIN_VERSION("v1.0");
WUPS_PLUGIN_AUTHOR("Maschell"); WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("BSD"); WUPS_PLUGIN_LICENSE("BSD");
INITIALIZE(args){ /**
All of this defines can be used in ANY file.
It's possible to split it up into multiple files.
**/
/**
Get's called ONCE when the loader exits, but BEFORE the ON_APPLICATION_START gets called or functions are overridden.
**/
INITIALIZE_PLUGIN(){
// Initializes overlay and fs features in the background.
InitOSFunctionPointers();
InitSocketFunctionPointers();
log_init();
DEBUG_FUNCTION_LINE("INITIALIZE_PLUGIN of example_plugin!\n");
}
/**
Gets called when the plugin loader is re-entered => when the plugin is unloaded.
The overridden functions are restored before this is getting called.
**/
DEINITIALIZE_PLUGIN(){
InitOSFunctionPointers();
InitSocketFunctionPointers();
log_init();
DEBUG_FUNCTION_LINE("DEINITIALIZE_PLUGIN of example_plugin!\n");
}
/**
Gets called when an application starts.
This is called BEFORE the functions are overridden.
Make sure to initialize all functions you're using in the overridden functions!
**/
ON_APPLICATION_START(){
InitOSFunctionPointers(); InitOSFunctionPointers();
InitSocketFunctionPointers(); InitSocketFunctionPointers();
log_init(); log_init();
log_print("Init of example_plugin!\n"); DEBUG_FUNCTION_LINE("ON_APPLICATION_START of example_plugin!\n");
} }
/**
Gets called when an application ends. A good place for freeing memory.
**/
ON_APPLICATION_ENDING(){
DEBUG_FUNCTION_LINE("ON_APPLICATION_ENDING of example_plugin!\n");
}
/**
Gets called on each frame.
**/
ON_VYSNC(){
DEBUG_FUNCTION_LINE("ON_VYSNC of example_plugin!\n");
}
/**
Gets called whenever the application status changes.
Possible values of "status":
WUPS_APP_STATUS_FOREGROUND, App is now running in foreground
WUPS_APP_STATUS_BACKGROUND App is now running in background
WUPS_APP_STATUS_CLOSED App is going to be closed
**/
ON_APP_STATUS_CHANGED(status){
if(status == WUPS_APP_STATUS_FOREGROUND){
DEBUG_FUNCTION_LINE("ON_APP_STATUS_CHANGED of example_plugin! App is now in foreground\n");
} else if(status == WUPS_APP_STATUS_BACKGROUND){
DEBUG_FUNCTION_LINE("ON_APP_STATUS_CHANGED of example_plugin! App is now in background\n");
} else if(status == WUPS_APP_STATUS_CLOSED){
DEBUG_FUNCTION_LINE("ON_APP_STATUS_CHANGED of example_plugin! App is now going to be closed\n");
}
}
/**
This defines a function replacement.
It allows to replace the system function with an own function.
So whenever a game / application calles an overridden function, your function gets called instead.
Currently it's only possible to override functions that are loaded from .rpl files of OSv10 (00050010-1000400A).
Signature of this macro:
DECL_FUNCTION( RETURN_TYPE, ARBITRARY_NAME_OF_FUNCTION , ARGS_SEPERATED_BY_COMMA){
//Your code goes here.
}
Within this macro, two more function get declare you can use.
my_ARBITRARY_NAME_OF_FUNCTION and real_FSOpenFile
RETURN_TYPE my_ARBITRARY_NAME_OF_FUNCTION(ARGS_SEPERATED_BY_COMMA):
is just name of the function that gets declared in this macro.
It has the same effect as calling the overridden function directly.
RETURN_TYPE real_ARBITRARY_NAME_OF_FUNCTION(ARGS_SEPERATED_BY_COMMA):
is the name of the function, that leads to function that was overridden.
Use this to call the original function that will be overridden.
CAUTION: Other plugins may already have manipulated the the return value or arguments.
Use this macro for each function you want to override
**/
DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) { DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) {
int result = real_FSOpenFile(pClient, pCmd, path, mode, handle, error); int result = real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
@ -28,4 +127,12 @@ DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *
return result; return result;
} }
WUPS_MUST_REPLACE(FSOpenFile,WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile); /**
This tells the loader which functions from which library (.rpl) should be replaced with which function from this file.
The list of possible libraries can be found in the wiki. (In general it's WUPS_LOADER_LIBRARY_ + the name of the RPL in caps lock)
WUPS_MUST_REPLACE(FUNCTION_NAME_IN_THIS_FILE, NAME_OF_LIB_WHICH_CONTAINS_THIS_FUNCTION, NAME_OF_FUNCTION_TO_OVERRIDE)
Define this for each function you want to override.
**/
WUPS_MUST_REPLACE(FSOpenFile, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile);

View File

@ -19,7 +19,17 @@ WUPS_PLUGIN_LICENSE("GPL");
#define WIIU_PATH "/wiiu" #define WIIU_PATH "/wiiu"
#define DEFAULT_HID_TO_VPAD_PATH SD_PATH WIIU_PATH "/apps/hidtovpad" #define DEFAULT_HID_TO_VPAD_PATH SD_PATH WIIU_PATH "/apps/hidtovpad"
INITIALIZE(args){ INITIALIZE_PLUGIN(){
// Needed for SD access
}
DEINITIALIZE_PLUGIN(){
//CursorDrawer::destroyInstance();
ControllerPatcher::DeInit();
ControllerPatcher::stopNetworkServer();
}
ON_APPLICATION_START(args){
InitOSFunctionPointers(); InitOSFunctionPointers();
InitSocketFunctionPointers(); InitSocketFunctionPointers();
InitVPadFunctionPointers(); InitVPadFunctionPointers();
@ -27,29 +37,21 @@ INITIALIZE(args){
InitPadScoreFunctionPointers(); InitPadScoreFunctionPointers();
log_init(); log_init();
log_print("Init of hid_to_vpad!\n");
if(args != NULL && (args->device_mounted & WUPS_SD_MOUNTED) > 0){ DEBUG_FUNCTION_LINE("Initializing the controller data\n");
DEBUG_FUNCTION_LINE("Loading with SD Access\n");
ControllerPatcher::Init(CONTROLLER_PATCHER_PATH); ControllerPatcher::Init(CONTROLLER_PATCHER_PATH);
} else {
DEBUG_FUNCTION_LINE("Loading without SD Access\n");
ControllerPatcher::Init(NULL);
}
ControllerPatcher::disableControllerMapping(); ControllerPatcher::disableControllerMapping();
log_print("Starting HID to VPAD network server\n");
log_print("Start network server\n");
ControllerPatcher::startNetworkServer(); ControllerPatcher::startNetworkServer();
//TODO: ControllerPatcher::DeInit() on restore.
} }
ON_APPLICATION_ENDING(){
DECL_FUNCTION(void, __PPCExit, void){ //CursorDrawer::destroyInstance();
ControllerPatcher::resetCallbackData();
ControllerPatcher::destroyConfigHelper(); ControllerPatcher::destroyConfigHelper();
ControllerPatcher::stopNetworkServer(); ControllerPatcher::stopNetworkServer();
real___PPCExit();
ControllerPatcher::resetCallbackData();
} }
DECL_FUNCTION(s32, VPADRead, s32 chan, VPADData *buffer, u32 buffer_size, s32 *error) { DECL_FUNCTION(s32, VPADRead, s32 chan, VPADData *buffer, u32 buffer_size, s32 *error) {
@ -86,4 +88,3 @@ DECL_FUNCTION(s32, VPADRead, s32 chan, VPADData *buffer, u32 buffer_size, s32 *e
} }
WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead); WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead);
WUPS_MUST_REPLACE(__PPCExit, WUPS_LOADER_LIBRARY_COREINIT, __PPCExit);

View File

@ -12,7 +12,7 @@ WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("GPL"); WUPS_PLUGIN_LICENSE("GPL");
INITIALIZE(args) { ON_APPLICATION_START(args) {
InitOSFunctionPointers(); InitOSFunctionPointers();
InitSocketFunctionPointers(); InitSocketFunctionPointers();
log_init(); log_init();

View File

@ -0,0 +1,290 @@
DO_LOGGING := 1
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
endif
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
export WUPSDIR := $(DEVKITPRO)/wups
export GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
PREFIX := powerpc-eabi-
export AS := $(PREFIX)as
export CC := $(PREFIX)gcc
export CXX := $(PREFIX)g++
export LD := $(PREFIX)ld
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR)).mod
BUILD := build
SOURCES := src
DATA :=
INCLUDES := src
MAP ?= $(TARGET:.mod=.map)
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
# -Os: optimise size
# -Wall: generate lots of warnings
# -DGEKKO_U: define the symbol GEKKO (used in some headers)
# -D__wiiu__: define the symbol __wii__ (used in some headers)
# -mrvl: enable wii/gamecube compilation
# -mcpu=750: enable processor specific compilation
# -meabi: enable eabi specific compilation
# -mhard-float: enable hardware floating point instructions
# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables
# -fno-common: stop common variables which the loader can't understand
# -msdata-none: do not use r2 or r13 as small data areas
# -memb: enable embedded application specific compilation
# -ffunction-sections: split up functions so linker can garbage collect
# -fdata-sections: split up data so linker can garbage collect
COMMON_CFLAGS += -Os -Wall -DGEKKO_U -D__wiiu__ -mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common -msdata=none -memb -ffunction-sections -fdata-sections
# -x c: compile as c code
# -std=c11: use the c11 standard
CFLAGS += $(COMMON_CFLAGS) -x c -std=c11
# -x c: compile as c++ code
# -std=gnu++11: use the c++11 standard
CXXFLAGS += $(COMMON_CFLAGS) -x c++ -std=gnu++11
ifeq ($(DO_LOGGING), 1)
CFLAGS += -D__LOGGING__
CXXFLAGS += -D__LOGGING__
endif
ASFLAGS := -mregnames
# --relocatable: make sure ld doesn't remove relocations wups will need
# -s: strip local symbols to speed linking
# -u: keep certain sections
# -wrap: wrap function
# --gc-sections: remove unneeded symbols
# -T: use the linker script specified (to force certain wups sections together)
# -Map: generate a map file
LDFLAG_COMMON += -u wups_load -u wups_meta -u wups_hooks -T $(WUPSDIR)/wups.ld \
-Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,--gc-sections
LDFLAGS_MOD += $(LDFLAG_COMMON),--relocatable
LDFLAGS_ELF += --relocatable -s -T $(WUPSDIR)/wups_elf.ld
#---------------------------------------------------------------------------------
Q := @
MAKEFLAGS += --no-print-directory
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lwups -lutils -ldynamiclibs
#
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(DEVKITPPC)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export PROJECTDIR := $(CURDIR)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD_MOD := $(CC)
else
export LD_MOD := $(CXX)
endif
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES))
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include \
-I$(PORTLIBS)/include/libutils -I$(WUPSDIR)/include
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(PORTLIBS)/lib \
-L$(WUPSDIR)/lib
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean install
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf $(OUTPUT)
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
###############################################################################
# Rule to make everything.
PHONY += all
all : $(OUTPUT)
###############################################################################
# Special build rules
# Rule to make the module file.
$(OUTPUT) : output.elf
@echo "checking for missing symbols ..."
@$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAG_COMMON) $(LIBS) $(LIBPATHS) -o check_linking.elf
@echo "linking ..." $@
@$(LD_MOD) ../$(BUILD)/output.elf $(LDFLAGS_MOD) $(LIBS) $(LIBPATHS) -o $@
# Rule to make the module file.
output.elf : $(OFILES)
@echo "linking ... output.elf"
@$(LD) $(OFILES) $(LDFLAGS_ELF) $(LIBS) $(LIBPATHS) -o $@
###############################################################################
# Standard build rules
#---------------------------------------------------------------------------------
%.a:
#---------------------------------------------------------------------------------
@echo $(notdir $@)
@rm -f $@
@$(AR) -rc $@ $^
#---------------------------------------------------------------------------------
%.o: %.cpp
@echo $(notdir $<)
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) $(INCLUDE) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.c
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) $(INCLUDE) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.S
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.png.o : %.png
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.jpg.o : %.jpg
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.bin.o : %.bin
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.wav.o : %.wav
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.mp3.o : %.mp3
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.ogg.o : %.ogg
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
###############################################################################
# Assembly listing rules
# Rule to make assembly listing.
PHONY += list
list : $(LIST)
# Rule to make the listing file.
%.list : $(TARGET)
$(LOG)
-$Qmkdir -p $(dir $@)
$Q$(OBJDUMP) -d $< > $@
###############################################################################
# Clean rule
# Rule to clean files.
PHONY += clean
clean :
$Qrm -rf $(wildcard $(BUILD) $(BIN))
###############################################################################
# Phony targets
.PHONY : $(PHONY)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -0,0 +1,14 @@
#include <wups.h>
WUPS_PLUGIN_NAME("NNU Patcher");
WUPS_PLUGIN_DESCRIPTION("Enables eshop access on lower firmware versions.");
WUPS_PLUGIN_VERSION("v1.0");
WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("BSD");
DECL_FUNCTION(int, NeedsNetworkUpdate__Q2_2nn3nimFPb, bool * result){
*result = 0;
return 0;
}
WUPS_MUST_REPLACE(NeedsNetworkUpdate__Q2_2nn3nimFPb,WUPS_LOADER_LIBRARY_NN_NIM, NeedsNetworkUpdate__Q2_2nn3nimFPb);

View File

@ -41,14 +41,15 @@ u8 gCallbackCooldown __attribute__((section(".data"))) = 0;
DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) { DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) {
int result = real_VPADRead(chan, buffer, buffer_size, error); int result = real_VPADRead(chan, buffer, buffer_size, error);
int btns = VPAD_BUTTON_Y | VPAD_BUTTON_X | VPAD_BUTTON_A | VPAD_BUTTON_B; u32 btns = VPAD_BUTTON_Y | VPAD_BUTTON_X | VPAD_BUTTON_A | VPAD_BUTTON_B;
if(result > 0 && ((buffer[0].btns_h & (btns)) == btns) && gCallbackCooldown == 0 ){ if(result > 0 && ((buffer[0].btns_h & (btns)) == btns) && gCallbackCooldown == 0 ){
gCallbackCooldown = 0x3C; gCallbackCooldown = 0x3C;
WUPS_OpenOverlay(WUPS_OVERLAY_DRC_ONLY ,SplashScreen_callback); //WUPS_OpenOverlay(WUPS_OVERLAY_DRC_ONLY ,SplashScreen_callback);
WUPS_OpenOverlay(WUPS_OVERLAY_TV_ONLY ,SplashScreen_callback); //WUPS_OpenOverlay(WUPS_OVERLAY_DRC_ONLY ,SplashScreen_callback);
//WUPS_OpenOverlay(WUPS_OVERLAY_TV_ONLY ,SplashScreen_callback);
WUPS_OpenOverlay(WUPS_OVERLAY_DRC_AND_TV ,SplashScreen_callback); WUPS_OpenOverlay(WUPS_OVERLAY_DRC_AND_TV ,SplashScreen_callback);
WUPS_OpenOverlay(WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO ,SplashScreen_callback); //WUPS_OpenOverlay(WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO ,SplashScreen_callback);
} }
if(gCallbackCooldown > 0){ if(gCallbackCooldown > 0){
gCallbackCooldown--; gCallbackCooldown--;

View File

@ -37,8 +37,12 @@ WUPS_PLUGIN_VERSION("v0.1");
WUPS_PLUGIN_AUTHOR("Maschell"); WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("GPL"); WUPS_PLUGIN_LICENSE("GPL");
INITIALIZE_PLUGIN(){
// To init the overlay and FS
}
/* Entry point */ /* Entry point */
INITIALIZE(args){ ON_APPLICATION_START(args){
InitOSFunctionPointers(); InitOSFunctionPointers();
InitSocketFunctionPointers(); //For logging InitSocketFunctionPointers(); //For logging
InitVPadFunctionPointers(); InitVPadFunctionPointers();

View File

@ -11,20 +11,16 @@ WUPS_PLUGIN_VERSION("v1.0");
WUPS_PLUGIN_AUTHOR("Maschell"); WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("GPL"); WUPS_PLUGIN_LICENSE("GPL");
ON_APPLICATION_START(args){
INITIALIZE(args){
InitOSFunctionPointers(); InitOSFunctionPointers();
InitSocketFunctionPointers(); InitSocketFunctionPointers();
InitVPadFunctionPointers(); InitVPadFunctionPointers();
log_init(); log_init();
log_print("Init of padcon!\n"); DEBUG_FUNCTION_LINE("Init of padcon!\n");
} }
// Both would be possible.
//WUPS_HOOK_INIT(init);
DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) { DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) {
int result = real_VPADRead(chan, buffer, buffer_size, error); int result = real_VPADRead(chan, buffer, buffer_size, error);
if(buffer->btns_r&VPAD_BUTTON_STICK_R) { if(buffer->btns_r&VPAD_BUTTON_STICK_R) {

View File

@ -2,7 +2,8 @@
u8 gAppStatus __attribute__((section(".data"))) = 0; u8 gAppStatus __attribute__((section(".data"))) = 0;
volatile u8 gSDInitDone __attribute__((section(".data"))) = 0; volatile bool gSDInitDone __attribute__((section(".data"))) = false;
volatile bool gUSBInitDone __attribute__((section(".data"))) = false;
char gModFolder[FS_MAX_ENTNAME_SIZE] __attribute__((section(".data"))); char gModFolder[FS_MAX_ENTNAME_SIZE] __attribute__((section(".data")));
//char gLastMetaPath[FS_MAX_ENTNAME_SIZE] __attribute__((section(".data"))); //char gLastMetaPath[FS_MAX_ENTNAME_SIZE] __attribute__((section(".data")));

View File

@ -7,7 +7,8 @@
#define FS_QUEUE_MESSAGE_COUNT 5 #define FS_QUEUE_MESSAGE_COUNT 5
extern u8 gAppStatus; extern u8 gAppStatus;
extern volatile u8 gSDInitDone; extern volatile bool gSDInitDone;
extern volatile bool gUSBInitDone;
extern char gModFolder[FS_MAX_ENTNAME_SIZE]; extern char gModFolder[FS_MAX_ENTNAME_SIZE];

View File

@ -14,44 +14,43 @@
#include "main.h" #include "main.h"
#include "modpackSelector.h" #include "modpackSelector.h"
WUPS_PLUGIN_NAME("SDCaffiine lite"); WUPS_PLUGIN_NAME("SDCaffiine");
WUPS_PLUGIN_DESCRIPTION("Replaces the game files on the fly. Can be used for gamemods"); WUPS_PLUGIN_DESCRIPTION("Replaces the game files on the fly. Can be used for gamemods");
WUPS_PLUGIN_VERSION("v1.0"); WUPS_PLUGIN_VERSION("v1.0");
WUPS_PLUGIN_AUTHOR("Maschell"); WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("GPL"); WUPS_PLUGIN_LICENSE("GPL");
INITIALIZE(args){ INITIALIZE_PLUGIN(){
// Initializes overlay and fs features in the background.
}
ON_APPLICATION_START(args) {
InitOSFunctionPointers(); InitOSFunctionPointers();
InitSocketFunctionPointers(); //For logging InitSocketFunctionPointers(); //For logging
InitVPadFunctionPointers(); //For logging InitVPadFunctionPointers(); //For logging
log_init(); log_init();
if(FileReplacerUtils::setGroupAndOwnerID()){ if(FileReplacerUtils::setGroupAndOwnerID()) {
DEBUG_FUNCTION_LINE("SUCCESS\n"); //DEBUG_FUNCTION_LINE("SUCCESS\n");
} }
if(args != NULL){ DEBUG_FUNCTION_LINE("SD mounted? %d\n",args.sd_mounted);
gSDInitDone = args->device_mounted; DEBUG_FUNCTION_LINE("USB mounted? %d\n",args.usb_mounted);
/*if((args->device_mounted & WUPS_SD_MOUNTED) > 0){
DEBUG_FUNCTION_LINE("Yay, SD was mounted!\n");
gSDInitDone = WUPS_SD_MOUNTED;
DEBUG_FUNCTION_LINE("opendir result %08X!\n",opendir("sd:/")); gSDInitDone = args.sd_mounted;
gUSBInitDone = args.usb_mounted;
} else {
DEBUG_FUNCTION_LINE("SD wasn't mounted...!\n");
}*/
}else {
DEBUG_FUNCTION_LINE("args were NULL!\n");
}
HandleMultiModPacks(OSGetTitleID()); HandleMultiModPacks(OSGetTitleID());
log_print("Init of SDCafiine!\n"); log_print("Init of SDCafiine!\n");
} }
void deInitApplication(){ ON_APPLICATION_ENDING() {
//FileReplacerUtils::getInstance()->StopAsyncThread(); FileReplacerUtils::getInstance()->StopAsyncThread();
FileReplacerUtils::destroyInstance(); FileReplacerUtils::destroyInstance();
} }
ON_APP_STATUS_CHANGED(status) {
gAppStatus = status;
}

View File

@ -29,9 +29,8 @@ void HandleMultiModPacks(u64 titleID/*,bool showMenu*/) {
std::map<std::string,std::string> modTitlePath; std::map<std::string,std::string> modTitlePath;
std::map<std::string,std::string> mounting_points; std::map<std::string,std::string> mounting_points;
if(gSDInitDone & SDUSB_MOUNTED_OS_SD){ mounting_points[std::string(SD_PATH)] = std::string(NAME_PREFIX_SD); } if(gSDInitDone){ mounting_points[std::string(SD_PATH)] = std::string(NAME_PREFIX_SD); }
if(gSDInitDone & SD_MOUNTED_LIBFAT){ mounting_points[std::string(SD_PATH)] = std::string(NAME_PREFIX_SD); } if(gUSBInitDone){ mounting_points[std::string(USB_PATH)] = std::string(NAME_PREFIX_USB); }
if(gSDInitDone & USB_MOUNTED_LIBFAT){ mounting_points[std::string(USB_PATH)] = std::string(NAME_PREFIX_USB); }
//int i = 0; //int i = 0;
//for (i = 0; i < ntfs_mount_count; i++){ //for (i = 0; i < ntfs_mount_count; i++){

View File

@ -13,28 +13,10 @@
#include "common/common.h" #include "common/common.h"
#include "main.h" #include "main.h"
#define DEBUG_LOG 1 #define DEBUG_LOG 0
DECL_FUNCTION(void, __PPCExit, void){
DEBUG_FUNCTION_LINE("__PPCExit\n");
deInitApplication();
real___PPCExit();
}
DECL_FUNCTION(u32, ProcUIProcessMessages, u32 u){
u32 res = real_ProcUIProcessMessages(u);
if(res != gAppStatus){
//DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res);
gAppStatus = res;
}
return res;
}
DECL_FUNCTION(int, FSCloseFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error) { DECL_FUNCTION(int, FSCloseFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSCloseFile(pClient, pCmd, fd, error); } if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)){ return real_FSCloseFile(pClient, pCmd, fd, error); }
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
if((result = fs_wrapper_FSCloseFile(fd)) != USE_OS_FS_FUNCTION){ if((result = fs_wrapper_FSCloseFile(fd)) != USE_OS_FS_FUNCTION){
@ -45,7 +27,7 @@ DECL_FUNCTION(int, FSCloseFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, int
} }
DECL_FUNCTION(int, FSGetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error) { DECL_FUNCTION(int, FSGetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSGetPosFile(pClient, pCmd, fd, pos, error); } if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)){ return real_FSGetPosFile(pClient, pCmd, fd, pos, error); }
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
if((result = fs_wrapper_FSGetPosFile(fd,pos)) != USE_OS_FS_FUNCTION){ if((result = fs_wrapper_FSGetPosFile(fd,pos)) != USE_OS_FS_FUNCTION){
@ -56,7 +38,7 @@ DECL_FUNCTION(int, FSGetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, in
} }
DECL_FUNCTION(int, FSGetStat, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error) { DECL_FUNCTION(int, FSGetStat, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSGetStat(pClient, pCmd, path, stats, error); } if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)){ return real_FSGetStat(pClient, pCmd, path, stats, error); }
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
@ -74,7 +56,7 @@ DECL_FUNCTION(int, FSGetStat, FSClient *pClient, FSCmdBlock *pCmd, const char *p
} }
DECL_FUNCTION(int, FSGetStatFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error) { DECL_FUNCTION(int, FSGetStatFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSGetStatFile(pClient, pCmd, fd, stats, error); } if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)){ return real_FSGetStatFile(pClient, pCmd, fd, stats, error); }
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
if((result = fs_wrapper_FSGetStatFile(fd,stats)) != USE_OS_FS_FUNCTION){ if((result = fs_wrapper_FSGetStatFile(fd,stats)) != USE_OS_FS_FUNCTION){
@ -85,7 +67,7 @@ DECL_FUNCTION(int, FSGetStatFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, F
} }
DECL_FUNCTION(int, FSIsEof, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error) { DECL_FUNCTION(int, FSIsEof, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE) return real_FSIsEof(pClient, pCmd, fd, error); if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)) return real_FSIsEof(pClient, pCmd, fd, error);
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
if((result = fs_wrapper_FSIsEof(fd)) != USE_OS_FS_FUNCTION){ if((result = fs_wrapper_FSIsEof(fd)) != USE_OS_FS_FUNCTION){
@ -96,7 +78,7 @@ DECL_FUNCTION(int, FSIsEof, FSClient *pClient, FSCmdBlock *pCmd, int fd, int err
} }
DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) { DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSOpenFile(pClient, pCmd, path, mode, handle, error); } if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)){ return real_FSOpenFile(pClient, pCmd, path, mode, handle, error); }
/*if(endsWith(path,BOOT_TV_TEX_TGA,-1,-1)){ //Mario Party 10 crashes when pressing the home button. /*if(endsWith(path,BOOT_TV_TEX_TGA,-1,-1)){ //Mario Party 10 crashes when pressing the home button.
if(startsWith("/vol/storage_mlc01/usr/title/",path)){ if(startsWith("/vol/storage_mlc01/usr/title/",path)){
@ -129,7 +111,7 @@ DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *
} }
DECL_FUNCTION(int, FSReadFile, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int handle, int flag, int error) { DECL_FUNCTION(int, FSReadFile, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int handle, int flag, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSReadFile(pClient, pCmd, buffer, size, count, handle, flag, error); } if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)){ return real_FSReadFile(pClient, pCmd, buffer, size, count, handle, flag, error); }
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
if((result = fs_wrapper_FSReadFile(handle,buffer,size,count)) != USE_OS_FS_FUNCTION){ if((result = fs_wrapper_FSReadFile(handle,buffer,size,count)) != USE_OS_FS_FUNCTION){
@ -140,7 +122,7 @@ DECL_FUNCTION(int, FSReadFile, FSClient *pClient, FSCmdBlock *pCmd, void *buffer
} }
DECL_FUNCTION(int, FSSetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, u32 pos, int error) { DECL_FUNCTION(int, FSSetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, u32 pos, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE) return real_FSSetPosFile(pClient, pCmd, fd, pos, error); if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)) return real_FSSetPosFile(pClient, pCmd, fd, pos, error);
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
if((result = fs_wrapper_FSSetPosFile(fd,pos)) != USE_OS_FS_FUNCTION){ if((result = fs_wrapper_FSSetPosFile(fd,pos)) != USE_OS_FS_FUNCTION){
@ -151,7 +133,7 @@ DECL_FUNCTION(int, FSSetPosFile, FSClient *pClient, FSCmdBlock *pCmd, int fd, u3
} }
DECL_FUNCTION(int, FSReadFileWithPos, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error) { DECL_FUNCTION(int, FSReadFileWithPos, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error) {
if(gAppStatus == 2 || gSDInitDone <= SDUSB_MOUNTED_FAKE){ return real_FSReadFileWithPos(pClient, pCmd, buffer, size, count, pos, fd, flag, error); } if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || !(gUSBInitDone || gSDInitDone)){ return real_FSReadFileWithPos(pClient, pCmd, buffer, size, count, pos, fd, flag, error); }
int result = USE_OS_FS_FUNCTION; int result = USE_OS_FS_FUNCTION;
if((result = fs_wrapper_FSReadFileWithPos(buffer,size,count,pos,fd)) != USE_OS_FS_FUNCTION){ if((result = fs_wrapper_FSReadFileWithPos(buffer,size,count,pos,fd)) != USE_OS_FS_FUNCTION){
@ -169,7 +151,7 @@ However this my be a bit faster/robust, when we handle the async functions async
**/ **/
DECL_FUNCTION(int, FSCloseFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams) { DECL_FUNCTION(int, FSCloseFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams * asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSCloseFileAsync(pClient, pCmd, fd, error, asyncParams); return real_FSCloseFileAsync(pClient, pCmd, fd, error, asyncParams);
} }
@ -177,7 +159,7 @@ DECL_FUNCTION(int, FSCloseFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd
} }
DECL_FUNCTION(int, FSGetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error, FSAsyncParams * asyncParams) { DECL_FUNCTION(int, FSGetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int *pos, int error, FSAsyncParams * asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSGetPosFileAsync(pClient, pCmd, fd, pos, error, asyncParams); return real_FSGetPosFileAsync(pClient, pCmd, fd, pos, error, asyncParams);
} }
@ -185,7 +167,7 @@ DECL_FUNCTION(int, FSGetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int f
} }
DECL_FUNCTION(int, FSGetStatAsync, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error, FSAsyncParams * asyncParams) { DECL_FUNCTION(int, FSGetStatAsync, FSClient *pClient, FSCmdBlock *pCmd, const char *path, FSStat *stats, int error, FSAsyncParams * asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSGetStatAsync(pClient, pCmd, path, stats, error, asyncParams); return real_FSGetStatAsync(pClient, pCmd, path, stats, error, asyncParams);
} }
@ -193,7 +175,7 @@ DECL_FUNCTION(int, FSGetStatAsync, FSClient *pClient, FSCmdBlock *pCmd, const ch
} }
DECL_FUNCTION(int, FSGetStatFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error, FSAsyncParams * asyncParams) { DECL_FUNCTION(int, FSGetStatFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, FSStat * stats, int error, FSAsyncParams * asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSGetStatFileAsync(pClient, pCmd, fd, stats, error, asyncParams); return real_FSGetStatFileAsync(pClient, pCmd, fd, stats, error, asyncParams);
} }
@ -201,7 +183,7 @@ DECL_FUNCTION(int, FSGetStatFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int
} }
DECL_FUNCTION(int, FSIsEofAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams *asyncParams) { DECL_FUNCTION(int, FSIsEofAsync, FSClient *pClient, FSCmdBlock *pCmd, int fd, int error, FSAsyncParams *asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSIsEofAsync(pClient, pCmd, fd, error,asyncParams); return real_FSIsEofAsync(pClient, pCmd, fd, error,asyncParams);
} }
@ -224,7 +206,7 @@ u64 getTitleIDFromPath(const char * path){
}*/ }*/
DECL_FUNCTION(int, FSOpenFileAsync, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error, FSAsyncParams *asyncParams) { DECL_FUNCTION(int, FSOpenFileAsync, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error, FSAsyncParams *asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSOpenFileAsync(pClient, pCmd, path, mode, handle,error, asyncParams); return real_FSOpenFileAsync(pClient, pCmd, path, mode, handle,error, asyncParams);
} }
@ -232,7 +214,7 @@ DECL_FUNCTION(int, FSOpenFileAsync, FSClient *pClient, FSCmdBlock *pCmd, const c
} }
DECL_FUNCTION(int, FSReadFileAsync, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error, FSAsyncParams *asyncParams) { DECL_FUNCTION(int, FSReadFileAsync, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, int fd, int flag, int error, FSAsyncParams *asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSReadFileAsync(pClient, pCmd, buffer, size, count, fd, flag, error, asyncParams); return real_FSReadFileAsync(pClient, pCmd, buffer, size, count, fd, flag, error, asyncParams);
} }
@ -240,7 +222,7 @@ DECL_FUNCTION(int, FSReadFileAsync, FSClient *pClient, FSCmdBlock *pCmd, void *b
} }
DECL_FUNCTION(int, FSReadFileWithPosAsync, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error, FSAsyncParams *asyncParams) { DECL_FUNCTION(int, FSReadFileWithPosAsync, FSClient *pClient, FSCmdBlock *pCmd, void *buffer, int size, int count, u32 pos, int fd, int flag, int error, FSAsyncParams *asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSReadFileWithPosAsync(pClient, pCmd, buffer, size, count, pos, fd, flag, error, asyncParams); return real_FSReadFileWithPosAsync(pClient, pCmd, buffer, size, count, pos, fd, flag, error, asyncParams);
} }
@ -248,7 +230,7 @@ DECL_FUNCTION(int, FSReadFileWithPosAsync, FSClient *pClient, FSCmdBlock *pCmd,
} }
DECL_FUNCTION(int, FSSetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int handle, u32 pos, int error, FSAsyncParams *asyncParams) { DECL_FUNCTION(int, FSSetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int handle, u32 pos, int error, FSAsyncParams *asyncParams) {
if(gAppStatus == 2 || checkErrorFlag(&error) || gSDInitDone <= SDUSB_MOUNTED_FAKE){ // Use the real implementation if the app is not in foreground or we already checked it. if(gAppStatus == WUPS_APP_STATUS_BACKGROUND || checkErrorFlag(&error) || !(gUSBInitDone || gSDInitDone)){ // Use the real implementation if the app is not in foreground or we already checked it.
return real_FSSetPosFileAsync(pClient, pCmd, handle, pos, error,asyncParams); return real_FSSetPosFileAsync(pClient, pCmd, handle, pos, error,asyncParams);
} }
@ -257,12 +239,12 @@ DECL_FUNCTION(int, FSSetPosFileAsync, FSClient *pClient, FSCmdBlock *pCmd, int h
/* /*
DECL_FUNCTION(int, FSBindMount, void *pClient, void *pCmd, char *source, char *target, int error){ DECL_FUNCTION(int, FSBindMount, void *pClient, void *pCmd, char *source, char *target, int error){
if(gAppStatus == 2) return real_FSBindMount(pClient,pCmd,source,target,error); if(gAppStatus == WUPS_APP_STATUS_BACKGROUND) return real_FSBindMount(pClient,pCmd,source,target,error);
memcpy(gLastMetaPath,source,strlen(source) + 1); memcpy(gLastMetaPath,source,strlen(source) + 1);
return real_FSBindMount(pClient,pCmd,source,target,error); return real_FSBindMount(pClient,pCmd,source,target,error);
} }
DECL_FUNCTION(int, FSBindUnmount, void *pClient, void *pCmd, char *target, int error){ DECL_FUNCTION(int, FSBindUnmount, void *pClient, void *pCmd, char *target, int error){
if(gAppStatus == 2) real_FSBindUnmount(pClient,pCmd,target,error); if(gAppStatus == WUPS_APP_STATUS_BACKGROUND) real_FSBindUnmount(pClient,pCmd,target,error);
gLastMetaPath[0] = 0; gLastMetaPath[0] = 0;
return real_FSBindUnmount(pClient,pCmd,target,error); return real_FSBindUnmount(pClient,pCmd,target,error);
}*/ }*/
@ -287,7 +269,3 @@ WUPS_MUST_REPLACE(FSOpenFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FS
WUPS_MUST_REPLACE(FSReadFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSReadFileAsync); WUPS_MUST_REPLACE(FSReadFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSReadFileAsync);
WUPS_MUST_REPLACE(FSReadFileWithPosAsync, WUPS_LOADER_LIBRARY_COREINIT, FSReadFileWithPosAsync); WUPS_MUST_REPLACE(FSReadFileWithPosAsync, WUPS_LOADER_LIBRARY_COREINIT, FSReadFileWithPosAsync);
WUPS_MUST_REPLACE(FSSetPosFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSSetPosFileAsync); WUPS_MUST_REPLACE(FSSetPosFileAsync, WUPS_LOADER_LIBRARY_COREINIT, FSSetPosFileAsync);
WUPS_MUST_REPLACE(__PPCExit, WUPS_LOADER_LIBRARY_COREINIT, __PPCExit);
WUPS_MUST_REPLACE(ProcUIProcessMessages, WUPS_LOADER_LIBRARY_PROC_UI, ProcUIProcessMessages);

View File

@ -96,8 +96,8 @@ DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *e
if(result > 0 && ((buffer[0].btns_h & gButtonCombo) == gButtonCombo) && gCallbackCooldown == 0 ){ if(result > 0 && ((buffer[0].btns_h & gButtonCombo) == gButtonCombo) && gCallbackCooldown == 0 ){
gCallbackCooldown = 0x3C; gCallbackCooldown = 0x3C;
if(gAppStatus == WUPS_APP_STATUS_FOREGROUND){
gSwap = !gSwap; gSwap = !gSwap;
if(!gAppStatus){
swapVoices(); swapVoices();
} }
} }
@ -106,17 +106,7 @@ DECL_FUNCTION(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *e
return result; return result;
} }
DECL_FUNCTION(u32, ProcUIProcessMessages, u32 u){
u32 res = real_ProcUIProcessMessages(u);
if(res != gAppStatus){
log_printf("App status changed from %d to %d \n",gAppStatus,res);
gAppStatus = res;
}
return res;
}
WUPS_MUST_REPLACE(ProcUIProcessMessages, WUPS_LOADER_LIBRARY_PROC_UI, ProcUIProcessMessages);
WUPS_MUST_REPLACE(GX2CopyColorBufferToScanBuffer, WUPS_LOADER_LIBRARY_GX2, GX2CopyColorBufferToScanBuffer); WUPS_MUST_REPLACE(GX2CopyColorBufferToScanBuffer, WUPS_LOADER_LIBRARY_GX2, GX2CopyColorBufferToScanBuffer);
WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead); WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead);
WUPS_MUST_REPLACE(AXAcquireVoiceExOld, WUPS_LOADER_LIBRARY_SND_CORE, AXAcquireVoiceEx); WUPS_MUST_REPLACE(AXAcquireVoiceExOld, WUPS_LOADER_LIBRARY_SND_CORE, AXAcquireVoiceEx);

View File

@ -21,6 +21,9 @@
#include <malloc.h> #include <malloc.h>
#include <wups.h> #include <wups.h>
#include <vector>
#include <string>
#include <dynamic_libs/os_functions.h> #include <dynamic_libs/os_functions.h>
#include <dynamic_libs/gx2_functions.h> #include <dynamic_libs/gx2_functions.h>
#include <dynamic_libs/gx2_types.h> #include <dynamic_libs/gx2_types.h>
@ -40,47 +43,56 @@ WUPS_PLUGIN_VERSION("v1.0");
WUPS_PLUGIN_AUTHOR("Maschell"); WUPS_PLUGIN_AUTHOR("Maschell");
WUPS_PLUGIN_LICENSE("GPL"); WUPS_PLUGIN_LICENSE("GPL");
u8 isFirstBoot __attribute__((section(".data"))) = 1;
u32 SplashScreen(s32 time,s32 combotime); u32 SplashScreen(s32 time,s32 combotime);
/* Entry point */ /* Entry point */
INITIALIZE(args){ ON_APPLICATION_START(args){
gAppStatus = 0;
InitOSFunctionPointers(); InitOSFunctionPointers();
InitSocketFunctionPointers(); //For logging InitSocketFunctionPointers(); //For logging
InitSysFunctionPointers(); // For SYSLaunchMenu() InitSysFunctionPointers(); // For SYSLaunchMenu()
InitProcUIFunctionPointers();
//For patching //For patching
InitVPadFunctionPointers(); InitVPadFunctionPointers();
InitPadScoreFunctionPointers(); InitPadScoreFunctionPointers();
InitAXFunctionPointers(); InitAXFunctionPointers();
InitGX2FunctionPointers();
memset(gVoiceInfos,0,sizeof(gVoiceInfos)); memset(gVoiceInfos,0,sizeof(gVoiceInfos));
}
if(isFirstBoot){ // First boot back to SysMenu ON_APP_STATUS_CHANGED(status) {
gAppStatus = status;
}
INITIALIZE_PLUGIN(){
InitOSFunctionPointers();
InitVPadFunctionPointers();
u32 res = SplashScreen(10,2); u32 res = SplashScreen(10,2);
gButtonCombo = res; gButtonCombo = res;
isFirstBoot = 0;
}
} }
#define FPS 60 #define FPS 60
u32 SplashScreen(s32 time,s32 combotime){ u32 SplashScreen(s32 time,s32 combotime){
u32 result = VPAD_BUTTON_TV; u32 result = VPAD_BUTTON_TV;
// Prepare screen
s32 screen_buf0_size = 0;
// Init screen and screen buffers // Init screen
OSScreenInit(); OSScreenInit();
screen_buf0_size = OSScreenGetBufferSizeEx(0);
OSScreenSetBufferEx(0, (void *)0xF4000000); u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
OSScreenSetBufferEx(1, (void *)(0xF4000000 + screen_buf0_size)); u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
u32 * screenbuffer0 = (u32*)memalign(0x100, screen_buf0_size);
u32 * screenbuffer1 = (u32*)memalign(0x100, screen_buf1_size);
if(screenbuffer0 == NULL || screenbuffer1 == NULL){
if(screenbuffer0 != NULL){ free(screenbuffer0); }
if(screenbuffer1 != NULL){ free(screenbuffer1); }
return result;
}
OSScreenSetBufferEx(0, (void *)screenbuffer0);
OSScreenSetBufferEx(1, (void *)screenbuffer1);
OSScreenEnableEx(0, 1); OSScreenEnableEx(0, 1);
OSScreenEnableEx(1, 1); OSScreenEnableEx(1, 1);
@ -93,21 +105,23 @@ u32 SplashScreen(s32 time,s32 combotime){
OSScreenFlipBuffersEx(0); OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1); OSScreenFlipBuffersEx(1);
OSScreenClearBufferEx(0, 0);
OSScreenClearBufferEx(1, 0);
std::vector<std::string> strings;
strings.push_back("SwipSwapMe 0.2 - by Maschell.");
strings.push_back("");
strings.push_back("");
strings.push_back("Press the combo you want to use for swapping now for 2 seconds.");
strings.push_back("Pressing the TV button will return directly.");
strings.push_back("");
strings.push_back("Otherwise the default combo (TV button) will be used in 10 seconds.");
u8 pos = 0; u8 pos = 0;
OSScreenPutFontEx(0, 0, pos++,"SwipSwapMe 0.2 - by Maschell."); for (std::vector<std::string>::iterator it = strings.begin() ; it != strings.end(); ++it){
OSScreenPutFontEx(1, 0, pos,"SwipSwapMe 0.2 - by Maschell."); OSScreenPutFontEx(0, 0, pos, (*it).c_str());
OSScreenPutFontEx(0, 0, pos,""); OSScreenPutFontEx(1, 0, pos, (*it).c_str());
OSScreenPutFontEx(1, 0, pos++,""); pos++;
OSScreenPutFontEx(0, 0, pos,""); }
OSScreenPutFontEx(1, 0, pos++,"");
OSScreenPutFontEx(0, 0, pos,"Press the combo you want to use for swapping now for 2 seconds.");
OSScreenPutFontEx(1, 0, pos++,"Press the combo you want to use for swapping now for 2 seconds.");
OSScreenPutFontEx(0, 0, pos,"Pressing the TV button will return directly.");
OSScreenPutFontEx(1, 0, pos++,"Pressing the TV button will return directly.");
OSScreenPutFontEx(0, 0, pos,"");
OSScreenPutFontEx(1, 0, pos++,"");
OSScreenPutFontEx(0, 0, pos,"Otherwise the default combo (TV button) will be used in 10 seconds.");
OSScreenPutFontEx(1, 0, pos++,"Otherwise the default combo (TV button) will be used in 10 seconds.");
OSScreenFlipBuffersEx(0); OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1); OSScreenFlipBuffersEx(1);
@ -138,5 +152,9 @@ u32 SplashScreen(s32 time,s32 combotime){
i++; i++;
os_usleep(sleepingtime*1000); os_usleep(sleepingtime*1000);
} }
if(screenbuffer0 != NULL){ free(screenbuffer0); }
if(screenbuffer1 != NULL){ free(screenbuffer1); }
return result; return result;
} }

View File

@ -21,7 +21,7 @@ static void * new_readdir_ptr __attribute__((section(".data"))) = NULL;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void WUPS_InitFS(wups_loader_init_args_t* args){ void WUPS_InitFS(wups_loader_init_plugin_args_t* args){
if(args != NULL){ if(args != NULL){
new_open_ptr = (void*) args->fs_wrapper.open_repl; new_open_ptr = (void*) args->fs_wrapper.open_repl;
new_close_ptr = (void*) args->fs_wrapper.close_repl; new_close_ptr = (void*) args->fs_wrapper.close_repl;

View File

@ -17,7 +17,7 @@ static void * overlayfunction_ptr __attribute__((section(".data"))) = NULL;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void WUPS_InitOverlay(wups_loader_init_args_t* args){ void WUPS_InitOverlay(wups_loader_init_plugin_args_t* args){
if(args != NULL){ if(args != NULL){
InitOSFunctionPointers(); InitOSFunctionPointers();
overlayfunction_ptr = (void*) args->overlayfunction_ptr; overlayfunction_ptr = (void*) args->overlayfunction_ptr;

57
wups_include/common.h Normal file
View File

@ -0,0 +1,57 @@
/* based on blsug.h
* by Alex Chadwick
*
* Copyright (C) 2014, Alex Chadwick
* Modified by Maschell, 2018
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef WUPS_COMMON_DEF_H_
#define WUPS_COMMON_DEF_H_
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#ifdef __cplusplus
extern "C" {
#endif
#define WUPS_SECTION(x) __attribute__((__section__ (".wups." x)))
#define WUPS_META(id, value) \
extern const char wups_meta_ ## id [] WUPS_SECTION("meta"); \
const char wups_meta_ ## id [] = #id "=" value
#define WUPS_PLUGIN_NAME(x) WUPS_META(name, x); WUPS_META(wups, "0.1"); WUPS_META(buildtimestamp, __DATE__ " " __TIME__)
#define WUPS_PLUGIN_AUTHOR(x) WUPS_META(author, x)
#define WUPS_PLUGIN_VERSION(x) WUPS_META(version, x)
#define WUPS_PLUGIN_LICENSE(x) WUPS_META(license, x)
#define WUPS_PLUGIN_DESCRIPTION(x) WUPS_META(description, x)
#ifdef __cplusplus
}
#endif
#endif /* WUPS_COMMON_DEF_H_ */

View File

@ -0,0 +1,146 @@
/* based on blsug.h
* by Alex Chadwick
*
* Copyright (C) 2014, Alex Chadwick
* Modified by Maschell, 2018
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef WUPS_FUNCTION_PATCHING_DEF_H_
#define WUPS_FUNCTION_PATCHING_DEF_H_
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum wups_loader_library_type_t {
WUPS_LOADER_LIBRARY_AVM,
WUPS_LOADER_LIBRARY_CAMERA,
WUPS_LOADER_LIBRARY_COREINIT,
WUPS_LOADER_LIBRARY_DC,
WUPS_LOADER_LIBRARY_DMAE,
WUPS_LOADER_LIBRARY_DRMAPP,
WUPS_LOADER_LIBRARY_ERREULA,
WUPS_LOADER_LIBRARY_GX2,
WUPS_LOADER_LIBRARY_H264,
WUPS_LOADER_LIBRARY_LZMA920,
WUPS_LOADER_LIBRARY_MIC,
WUPS_LOADER_LIBRARY_NFC,
WUPS_LOADER_LIBRARY_NIO_PROF,
WUPS_LOADER_LIBRARY_NLIBCURL,
WUPS_LOADER_LIBRARY_NLIBNSS,
WUPS_LOADER_LIBRARY_NLIBNSS2,
WUPS_LOADER_LIBRARY_NN_AC,
WUPS_LOADER_LIBRARY_NN_ACP,
WUPS_LOADER_LIBRARY_NN_ACT,
WUPS_LOADER_LIBRARY_NN_AOC,
WUPS_LOADER_LIBRARY_NN_BOSS,
WUPS_LOADER_LIBRARY_NN_CCR,
WUPS_LOADER_LIBRARY_NN_CMPT,
WUPS_LOADER_LIBRARY_NN_DLP,
WUPS_LOADER_LIBRARY_NN_EC,
WUPS_LOADER_LIBRARY_NN_FP,
WUPS_LOADER_LIBRARY_NN_HAI,
WUPS_LOADER_LIBRARY_NN_HPAD,
WUPS_LOADER_LIBRARY_NN_IDBE,
WUPS_LOADER_LIBRARY_NN_NDM,
WUPS_LOADER_LIBRARY_NN_NETS2,
WUPS_LOADER_LIBRARY_NN_NFP,
WUPS_LOADER_LIBRARY_NN_NIM,
WUPS_LOADER_LIBRARY_NN_OLV,
WUPS_LOADER_LIBRARY_NN_PDM,
WUPS_LOADER_LIBRARY_NN_SAVE,
WUPS_LOADER_LIBRARY_NN_SL,
WUPS_LOADER_LIBRARY_NN_SPM,
WUPS_LOADER_LIBRARY_NN_TEMP,
WUPS_LOADER_LIBRARY_NN_UDS,
WUPS_LOADER_LIBRARY_NN_VCTL,
WUPS_LOADER_LIBRARY_NSYSCCR,
WUPS_LOADER_LIBRARY_NSYSHID,
WUPS_LOADER_LIBRARY_NSYSKBD,
WUPS_LOADER_LIBRARY_NSYSNET,
WUPS_LOADER_LIBRARY_NSYSUHS,
WUPS_LOADER_LIBRARY_NSYSUVD,
WUPS_LOADER_LIBRARY_NTAG,
WUPS_LOADER_LIBRARY_PADSCORE,
WUPS_LOADER_LIBRARY_PROC_UI,
WUPS_LOADER_LIBRARY_SND_CORE,
WUPS_LOADER_LIBRARY_SND_USER,
WUPS_LOADER_LIBRARY_SNDCORE2,
WUPS_LOADER_LIBRARY_SNDUSER2,
WUPS_LOADER_LIBRARY_SWKBD,
WUPS_LOADER_LIBRARY_SYSAPP,
WUPS_LOADER_LIBRARY_TCL,
WUPS_LOADER_LIBRARY_TVE,
WUPS_LOADER_LIBRARY_UAC,
WUPS_LOADER_LIBRARY_UAC_RPL,
WUPS_LOADER_LIBRARY_USB_MIC,
WUPS_LOADER_LIBRARY_UVC,
WUPS_LOADER_LIBRARY_UVD,
WUPS_LOADER_LIBRARY_VPAD,
WUPS_LOADER_LIBRARY_VPADBASE,
WUPS_LOADER_LIBRARY_ZLIB125,
} wups_loader_library_type_t;
typedef enum wups_loader_entry_type_t {
WUPS_LOADER_ENTRY_FUNCTION,
WUPS_LOADER_ENTRY_FUNCTION_MANDATORY,
WUPS_LOADER_ENTRY_EXPORT
} wups_loader_entry_type_t;
typedef struct wups_loader_entry_t {
wups_loader_entry_type_t type;
struct {
const char *name; /* Name of the function that will be replaced */
const wups_loader_library_type_t library; /**/
const char *my_function_name; /* Function name of your own, new function (my_XXX) */
const void *target; /* Address of our own, new function (my_XXX)*/
const void *call_addr; /* Address for calling the real function.(real_XXX) */
} _function;
} wups_loader_entry_t;
#define WUPS_MUST_REPLACE(x, lib, function_name) WUPS_MUST_REPLACE_EX(real_ ## x, lib, my_ ## x, function_name);
#define WUPS_MUST_REPLACE_EX(original_func, rpl_type, replace_func, replace_function_name) \
extern const wups_loader_entry_t wups_load_ ## replace_func \
WUPS_SECTION("load"); \
const wups_loader_entry_t wups_load_ ## replace_func = { \
.type = WUPS_LOADER_ENTRY_FUNCTION_MANDATORY, \
._function = { \
.name = #replace_function_name, \
.library = rpl_type, \
.my_function_name = #replace_func, \
.target = (const void*)&(replace_func), \
.call_addr = (const void*)&(original_func) \
} \
}
#define DECL_FUNCTION(res, name, ...) \
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".data"))); \
res my_ ## name(__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif /* WUPS_FUNCTION_PATCHING_DEF_H_ */

122
wups_include/hooks.h Normal file
View File

@ -0,0 +1,122 @@
/****************************************************************************
* Copyright (C) 2018 Maschell
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef WUPS_HOOKS_DEF_H_
#define WUPS_HOOKS_DEF_H_
#include "common.h"
#include <dynamic_libs/os_types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define WUPS_HOOK_EX(type_def,original_func) \
extern const wups_loader_hook_t wups_hooks_ ## original_func \
WUPS_SECTION("hooks"); \
const wups_loader_hook_t wups_hooks_ ## original_func = { \
.type = type_def, \
.target = (const void*)&(original_func) \
}
typedef enum wups_loader_hook_type_t {
WUPS_LOADER_HOOK_INIT_PLUGIN, /* Called when exiting the plugin loader */
WUPS_LOADER_HOOK_DEINIT_PLUGIN, /* Called when re-entering the plugin loader */
WUPS_LOADER_HOOK_STARTING_APPLICATION, /* Called when an application gets started */
WUPS_LOADER_HOOK_ENDING_APPLICATION, /* Called when an application ends */
WUPS_LOADER_HOOK_VSYNC, /* Called when an application calls GX2WaitForVsync (most times each frame) */
WUPS_LOADER_HOOK_APP_STATUS_CHANGED, /* Called when the app status changes (foreground, background, closing) */
} wups_loader_hook_type_t;
typedef struct wups_loader_hook_t {
wups_loader_hook_type_t type; /* Defines the type of the hook */
const void *target; /* Address of our own, new function */
} wups_loader_hook_t;
typedef enum wups_loader_app_status_t {
WUPS_APP_STATUS_FOREGROUND, /* App is now running in foreground */
WUPS_APP_STATUS_BACKGROUND, /* App is now running in background */
WUPS_APP_STATUS_CLOSED, /* App is going to be closed */
WUPS_APP_STATUS_UNKNOWN, /* Unknown status _should_ never happen.*/
} wups_loader_app_status_t;
typedef struct wups_loader_init_plugin_args_t {
struct {
const void * open_repl;
const void * close_repl;
const void * write_repl;
const void * read_repl;
const void * lseek_repl;
const void * stat_repl;
const void * fstat_repl;
const void * opendir_repl;
const void * closedir_repl;
const void * readdir_repl;
} fs_wrapper;
const void * overlayfunction_ptr;
} wups_loader_init_plugin_args_t;
typedef struct wups_loader_app_started_args_t {
bool sd_mounted;
bool usb_mounted;
} wups_loader_app_started_args_t;
#define INITIALIZE_PLUGIN() \
void init_plugin(wups_loader_init_plugin_args_t*);\
void myInit_plugin(void);\
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_PLUGIN,init_plugin); \
void init_plugin(wups_loader_init_plugin_args_t* args){ \
if(args != NULL){\
WUPS_InitFS(args);\
WUPS_InitOverlay(args);\
\
}\
myInit_plugin();\
} \
void myInit_plugin()
#define DEINITIALIZE_PLUGIN() \
void deinit_plugin(void);\
WUPS_HOOK_EX(WUPS_LOADER_HOOK_DEINIT_PLUGIN,deinit_plugin); \
void deinit_plugin()
#define ON_APPLICATION_START(myargs) \
void on_app_starting(wups_loader_app_started_args_t);\
WUPS_HOOK_EX(WUPS_LOADER_HOOK_STARTING_APPLICATION,on_app_starting); \
void on_app_starting(wups_loader_app_started_args_t myargs)
#define ON_APPLICATION_ENDING() \
void on_app_ending(void);\
WUPS_HOOK_EX(WUPS_LOADER_HOOK_ENDING_APPLICATION,on_app_ending); \
void on_app_ending(void)
#define ON_VYSNC() \
void on_vsync(void);\
WUPS_HOOK_EX(WUPS_LOADER_HOOK_VSYNC,on_vsync); \
void on_vsync(void)
#define ON_APP_STATUS_CHANGED(status) \
void on_app_status_changed(wups_loader_app_status_t);\
WUPS_HOOK_EX(WUPS_LOADER_HOOK_APP_STATUS_CHANGED,on_app_status_changed); \
void on_app_status_changed(wups_loader_app_status_t status)
#ifdef __cplusplus
}
#endif
#endif /* WUPS_WUPS_H_ */

58
wups_include/utils.h Normal file
View File

@ -0,0 +1,58 @@
/****************************************************************************
* Copyright (C) 2018 Maschell
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef WUPS_UTILS_DEF_H_
#define WUPS_UTILS_DEF_H_
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum wups_overlay_options_type_t {
WUPS_OVERLAY_NONE,
WUPS_OVERLAY_DRC_ONLY, /* Tries to display only on gamepad screen */
WUPS_OVERLAY_TV_ONLY, /* Tries to display only on tv screen */
WUPS_OVERLAY_DRC_AND_TV, /* Tries to display on both screens. Prioritizes the TV screen if memory is low. */
WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO /* Tries to display on both screens. But if memory is low, prioritize the DRC screen.*/
} wups_overlay_options_type_t;
typedef void (*overlay_callback)(wups_overlay_options_type_t);
/*
Gets called by the framework
*/
void WUPS_InitFS(wups_loader_init_plugin_args_t* args);
void WUPS_InitOverlay(wups_loader_init_plugin_args_t* args);
/*
Can be called by the user.
*/
void WUPS_Overlay_PrintTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...);
void WUPS_Overlay_OSScreenClear(wups_overlay_options_type_t screen);
void WUPS_Overlay_FlipBuffers(wups_overlay_options_type_t screen);
void WUPS_OpenOverlay(wups_overlay_options_type_t screen, overlay_callback callback);
#ifdef __cplusplus
}
#endif
#endif /* WUPS_WUPS_H_ */

View File

@ -26,229 +26,9 @@
#ifndef WUPS_H_ #ifndef WUPS_H_
#define WUPS_H_ #define WUPS_H_
#include <stddef.h> #include "common.h"
#include <stdint.h> #include "function_patching.h"
#include <sys/types.h> #include "hooks.h"
#include <sys/stat.h> #include "utils.h"
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#ifdef __cplusplus
extern "C" {
#endif
#define WUPS_SECTION(x) __attribute__((__section__ (".wups." x)))
#define DECL_FUNCTION(res, name, ...) \
res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".data"))); \
res my_ ## name(__VA_ARGS__)
typedef enum wups_loader_library_type_t {
WUPS_LOADER_LIBRARY_AVM,
WUPS_LOADER_LIBRARY_CAMERA,
WUPS_LOADER_LIBRARY_COREINIT,
WUPS_LOADER_LIBRARY_DC,
WUPS_LOADER_LIBRARY_DMAE,
WUPS_LOADER_LIBRARY_DRMAPP,
WUPS_LOADER_LIBRARY_ERREULA,
WUPS_LOADER_LIBRARY_GX2,
WUPS_LOADER_LIBRARY_H264,
WUPS_LOADER_LIBRARY_LZMA920,
WUPS_LOADER_LIBRARY_MIC,
WUPS_LOADER_LIBRARY_NFC,
WUPS_LOADER_LIBRARY_NIO_PROF,
WUPS_LOADER_LIBRARY_NLIBCURL,
WUPS_LOADER_LIBRARY_NLIBNSS,
WUPS_LOADER_LIBRARY_NLIBNSS2,
WUPS_LOADER_LIBRARY_NN_AC,
WUPS_LOADER_LIBRARY_NN_ACP,
WUPS_LOADER_LIBRARY_NN_ACT,
WUPS_LOADER_LIBRARY_NN_AOC,
WUPS_LOADER_LIBRARY_NN_BOSS,
WUPS_LOADER_LIBRARY_NN_CCR,
WUPS_LOADER_LIBRARY_NN_CMPT,
WUPS_LOADER_LIBRARY_NN_DLP,
WUPS_LOADER_LIBRARY_NN_EC,
WUPS_LOADER_LIBRARY_NN_FP,
WUPS_LOADER_LIBRARY_NN_HAI,
WUPS_LOADER_LIBRARY_NN_HPAD,
WUPS_LOADER_LIBRARY_NN_IDBE,
WUPS_LOADER_LIBRARY_NN_NDM,
WUPS_LOADER_LIBRARY_NN_NETS2,
WUPS_LOADER_LIBRARY_NN_NFP,
WUPS_LOADER_LIBRARY_NN_NIM,
WUPS_LOADER_LIBRARY_NN_OLV,
WUPS_LOADER_LIBRARY_NN_PDM,
WUPS_LOADER_LIBRARY_NN_SAVE,
WUPS_LOADER_LIBRARY_NN_SL,
WUPS_LOADER_LIBRARY_NN_SPM,
WUPS_LOADER_LIBRARY_NN_TEMP,
WUPS_LOADER_LIBRARY_NN_UDS,
WUPS_LOADER_LIBRARY_NN_VCTL,
WUPS_LOADER_LIBRARY_NSYSCCR,
WUPS_LOADER_LIBRARY_NSYSHID,
WUPS_LOADER_LIBRARY_NSYSKBD,
WUPS_LOADER_LIBRARY_NSYSNET,
WUPS_LOADER_LIBRARY_NSYSUHS,
WUPS_LOADER_LIBRARY_NSYSUVD,
WUPS_LOADER_LIBRARY_NTAG,
WUPS_LOADER_LIBRARY_PADSCORE,
WUPS_LOADER_LIBRARY_PROC_UI,
WUPS_LOADER_LIBRARY_SND_CORE,
WUPS_LOADER_LIBRARY_SND_USER,
WUPS_LOADER_LIBRARY_SNDCORE2,
WUPS_LOADER_LIBRARY_SNDUSER2,
WUPS_LOADER_LIBRARY_SWKBD,
WUPS_LOADER_LIBRARY_SYSAPP,
WUPS_LOADER_LIBRARY_TCL,
WUPS_LOADER_LIBRARY_TVE,
WUPS_LOADER_LIBRARY_UAC,
WUPS_LOADER_LIBRARY_UAC_RPL,
WUPS_LOADER_LIBRARY_USB_MIC,
WUPS_LOADER_LIBRARY_UVC,
WUPS_LOADER_LIBRARY_UVD,
WUPS_LOADER_LIBRARY_VPAD,
WUPS_LOADER_LIBRARY_VPADBASE,
WUPS_LOADER_LIBRARY_ZLIB125,
} wups_loader_library_type_t;
typedef enum wups_loader_hook_type_t {
WUPS_LOADER_HOOK_INIT_FUNCTION
} wups_loader_hook_type_t;
typedef struct wups_loader_hook_t {
wups_loader_hook_type_t type;
const void *target; /*Address of our own, new function (my_XXX)*/
} wups_loader_hook_t;
#define WUPS_HOOK_INIT(original_func) \
extern const wups_loader_hook_t wups_hooks_init_ ## original_func \
WUPS_SECTION("hooks"); \
const wups_loader_hook_t wups_hooks_init_ ## original_func = { \
.type = WUPS_LOADER_HOOK_INIT_FUNCTION, \
.target = (const void*)&(original_func) \
}
#define WUPS_SDUSB_MOUNTED_NONE 0
#define WUPS_SDUSB_MOUNTED_FAKE (1<<0)
#define WUPS_SDUSB_MOUNTED_OS_SD (1<<1)
#define WUPS_SDUSB_LIBIOSU_LOADED (1<<2)
#define WUPS_SD_MOUNTED_LIBFAT (1<<3)
#define WUPS_USB_MOUNTED_LIBFAT (1<<4)
#define WUPS_USB_MOUNTED_LIBNTFS (1<<5)
#define WUPS_SD_MOUNTED (WUPS_SDUSB_MOUNTED_OS_SD | WUPS_SD_MOUNTED_LIBFAT)
#define WUPS_USB_MOUNTED (WUPS_USB_MOUNTED_LIBFAT)
typedef enum wups_overlay_options_type_t {
WUPS_OVERLAY_NONE,
WUPS_OVERLAY_DRC_ONLY, /* Tries to display only on gamepad screen */
WUPS_OVERLAY_TV_ONLY, /* Tries to display only on tv screen */
WUPS_OVERLAY_DRC_AND_TV, /* Tries to display on both screens. Prioritizes the TV screen if memory is low. */
WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO /* Tries to display on both screens. But if memory is low, prioritize the DRC screen.*/
} wups_overlay_options_type_t;
typedef struct wups_loader_init_args_t {
int device_mounted;
struct {
const void * open_repl;
const void * close_repl;
const void * write_repl;
const void * read_repl;
const void * lseek_repl;
const void * stat_repl;
const void * fstat_repl;
const void * opendir_repl;
const void * closedir_repl;
const void * readdir_repl;
} fs_wrapper;
const void * overlayfunction_ptr;
} wups_loader_init_args_t;
void WUPS_InitFS(wups_loader_init_args_t* args);
void WUPS_InitOverlay(wups_loader_init_args_t* args);
#ifdef __cplusplus
#define EXTERN_C_START extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_START
#define EXTERN_C_END
#endif
#define INITIALIZE(my_args) \
void init(wups_loader_init_args_t*);\
void myInit(wups_loader_init_args_t*);\
WUPS_HOOK_INIT(init); \
void init(wups_loader_init_args_t* args){ \
if(args != NULL){\
WUPS_InitFS(args);\
WUPS_InitOverlay(args);\
\
}\
myInit(args);\
} \
void myInit(wups_loader_init_args_t* my_args)
typedef enum wups_loader_entry_type_t {
WUPS_LOADER_ENTRY_FUNCTION,
WUPS_LOADER_ENTRY_FUNCTION_MANDATORY,
WUPS_LOADER_ENTRY_EXPORT
} wups_loader_entry_type_t;
typedef struct wups_loader_entry_t {
wups_loader_entry_type_t type;
struct {
const char *name; /* Name of the function that will be replaced */
const wups_loader_library_type_t library; /**/
const char *my_function_name; /* Function name of your own, new function (my_XXX) */
const void *target; /* Address of our own, new function (my_XXX)*/
const void *call_addr; /* Address for calling the real function.(real_XXX) */
} _function;
} wups_loader_entry_t;
#define WUPS_MUST_REPLACE(x, lib, function_name) WUPS_MUST_REPLACE_EX(real_ ## x, lib, my_ ## x, function_name);
#define WUPS_MUST_REPLACE_EX(original_func, rpl_type, replace_func, replace_function_name) \
extern const wups_loader_entry_t wups_load_ ## replace_func \
WUPS_SECTION("load"); \
const wups_loader_entry_t wups_load_ ## replace_func = { \
.type = WUPS_LOADER_ENTRY_FUNCTION_MANDATORY, \
._function = { \
.name = #replace_function_name, \
.library = rpl_type, \
.my_function_name = #replace_func, \
.target = (const void*)&(replace_func), \
.call_addr = (const void*)&(original_func) \
} \
}
#define WUPS_META(id, value) \
extern const char wups_meta_ ## id [] WUPS_SECTION("meta"); \
const char wups_meta_ ## id [] = #id "=" value
#define WUPS_PLUGIN_NAME(x) WUPS_META(name, x); WUPS_META(wups, "0.1"); WUPS_META(buildtimestamp, __DATE__ " " __TIME__)
#define WUPS_PLUGIN_AUTHOR(x) WUPS_META(author, x)
#define WUPS_PLUGIN_VERSION(x) WUPS_META(version, x)
#define WUPS_PLUGIN_LICENSE(x) WUPS_META(license, x)
#define WUPS_PLUGIN_DESCRIPTION(x) WUPS_META(description, x)
typedef void (*overlay_callback)(wups_overlay_options_type_t);
void WUPS_Overlay_PrintTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...);
void WUPS_Overlay_OSScreenClear(wups_overlay_options_type_t screen);
void WUPS_Overlay_FlipBuffers(wups_overlay_options_type_t screen);
void WUPS_OpenOverlay(wups_overlay_options_type_t screen, overlay_callback callback);
#ifdef __cplusplus
}
#endif
#endif /* WUPS_WUPS_H_ */ #endif /* WUPS_WUPS_H_ */