diff --git a/src/common/retain_vars.cpp b/src/common/retain_vars.cpp index fe68153..0470f5e 100644 --- a/src/common/retain_vars.cpp +++ b/src/common/retain_vars.cpp @@ -4,6 +4,7 @@ replacement_data_t gbl_replacement_data __attribute__((section(".data"))); dyn_linking_relocation_data_t gbl_dyn_linking_data __attribute__((section(".data"))); uint8_t gAppStatus __attribute__((section(".data"))) = 0; +bool g_NotInLoader __attribute__((section(".data"))) = false; uint64_t gGameTitleID __attribute__((section(".data"))) = 0; volatile uint8_t gSDInitDone __attribute__((section(".data"))) = 0; @@ -16,3 +17,10 @@ struct buffer_store tv_store __attribute__((section(".data"))); char gbl_common_data[0x20000] __attribute__((section(".data"))); char * gbl_common_data_ptr __attribute__((section(".data"))) = gbl_common_data; + +GX2ColorBuffer g_vid_main_cbuf __attribute__((section(".data"))); +GX2Texture g_vid_drcTex __attribute__((section(".data"))); +GX2Sampler g_vid_sampler __attribute__((section(".data"))); +GX2Texture g_vid_tvTex __attribute__((section(".data"))); +GX2ContextState* g_vid_ownContextState __attribute__((section(".data"))); +GX2ContextState* g_vid_originalContextSave __attribute__((section(".data")))= NULL; diff --git a/src/common/retain_vars.h b/src/common/retain_vars.h index d4720cc..f776957 100644 --- a/src/common/retain_vars.h +++ b/src/common/retain_vars.h @@ -2,10 +2,14 @@ #define RETAINS_VARS_H_ #include "patcher/function_patcher.h" #include "plugin/dynamic_linking_defines.h" +#include extern replacement_data_t gbl_replacement_data; extern dyn_linking_relocation_data_t gbl_dyn_linking_data; + +extern bool g_NotInLoader; + extern uint8_t gAppStatus; extern uint64_t gGameTitleID; extern volatile uint8_t gSDInitDone; @@ -17,4 +21,11 @@ extern int32_t ntfs_mount_count; extern struct buffer_store drc_store; extern struct buffer_store tv_store; +extern GX2ColorBuffer g_vid_main_cbuf; +extern GX2Texture g_vid_drcTex; +extern GX2Texture g_vid_tvTex; +extern GX2ContextState* g_vid_ownContextState; +extern GX2ContextState* g_vid_originalContextSave; +extern GX2Sampler g_vid_sampler; + #endif // RETAINS_VARS_H_ diff --git a/src/main.cpp b/src/main.cpp index 12edd5f..dfa7274 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,6 +103,9 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) { gGameTitleID = OSGetTitleID(); + g_vid_ownContextState = NULL; + g_vid_originalContextSave = NULL; + int32_t result = 0; //Reset everything when were going back to the Mii Maker @@ -137,6 +140,16 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) { PluginLoader::destroyInstance(); MemoryUtils::init(); + + // Memory on custon heap is reset anyway so we don't need to free the image buffers. + memset((void*)&g_vid_main_cbuf,0,sizeof(g_vid_main_cbuf)); + memset((void*)&g_vid_drcTex,0,sizeof(g_vid_drcTex)); + memset((void*)&g_vid_tvTex,0,sizeof(g_vid_tvTex)); + g_vid_originalContextSave = NULL; + g_vid_ownContextState = NULL; + g_NotInLoader = false; + }else{ + g_NotInLoader = true; } DEBUG_FUNCTION_LINE("Patch own stuff\n"); diff --git a/src/patcher/hooks_patcher_static.cpp b/src/patcher/hooks_patcher_static.cpp index 7411ddd..1934152 100644 --- a/src/patcher/hooks_patcher_static.cpp +++ b/src/patcher/hooks_patcher_static.cpp @@ -5,9 +5,12 @@ #include "hooks_patcher.h" #include "myutils/overlay_helper.h" #include "myutils/ConfigUtils.h" +#include #include "main.h" #include "utils.h" #include "mymemory/memory_mapping.h" +#include "myutils/mem_utils.h" +#include "myutils/texture_utils.h" DECL(void, __PPCExit, void) { // Only continue if we are in the "right" application. @@ -125,7 +128,6 @@ bool checkMagic(VPADData *buffer) { angleX_frameCounter = 0; angleX_last = buffer->angle.x; } - } DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) { @@ -153,12 +155,177 @@ DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, in return result; } +void setupContextState() { + g_vid_ownContextState = (GX2ContextState*)memalign( + GX2_CONTEXT_STATE_ALIGNMENT, + sizeof(GX2ContextState) + ); + if(g_vid_ownContextState == NULL) { + OSFatal("VideoSquoosher: Failed to alloc g_vid_ownContextState\n"); + } + GX2SetupContextStateEx(g_vid_ownContextState, 1); + + GX2SetContextState(g_vid_ownContextState); + GX2SetColorBuffer(&g_vid_main_cbuf, GX2_RENDER_TARGET_0); + //GX2SetDepthBuffer(&tvDepthBuffer); + GX2SetContextState(g_vid_originalContextSave); + DEBUG_FUNCTION_LINE("Setup contest state done\n"); +} + +void initTextures() { + GX2InitColorBuffer(&g_vid_main_cbuf, + GX2_SURFACE_DIM_2D, + 1280, 720, 1, + GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, + GX2_AA_MODE_1X + ); + + if (g_vid_main_cbuf.surface.image_size) { + g_vid_main_cbuf.surface.image_data = MemoryUtils::alloc( + g_vid_main_cbuf.surface.image_size, + g_vid_main_cbuf.surface.align + ); + if(g_vid_main_cbuf.surface.image_data == NULL) { + OSFatal("Failed to alloc g_vid_main_cbuf\n"); + } + DEBUG_FUNCTION_LINE("Allocated %dx%d g_vid_main_cbuf %08X\n", + g_vid_main_cbuf.surface.width, + g_vid_main_cbuf.surface.height, + g_vid_main_cbuf.surface.image_data); + } else { + DEBUG_FUNCTION_LINE("GX2InitTexture failed for g_vid_main_cbuf!\n"); + } + + GX2InitTexture(&g_vid_drcTex, + 854, 480, 1, 0, + GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, + GX2_SURFACE_DIM_2D, + GX2_TILE_MODE_LINEAR_ALIGNED + ); + g_vid_drcTex.surface.use = (GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_TEXTURE); + + if (g_vid_drcTex.surface.image_size) { + + g_vid_drcTex.surface.image_data = MemoryUtils::alloc( + g_vid_drcTex.surface.image_size, + g_vid_drcTex.surface.align); + + if(g_vid_drcTex.surface.image_data == NULL) { + OSFatal("VideoSquoosher: Failed to alloc g_vid_drcTex\n"); + } + GX2Invalidate(GX2_INVALIDATE_CPU, g_vid_drcTex.surface.image_data, g_vid_drcTex.surface.image_size); + DEBUG_FUNCTION_LINE("VideoSquoosher: allocated %dx%d g_vid_drcTex %08X\n", + g_vid_drcTex.surface.width, + g_vid_drcTex.surface.height, + g_vid_drcTex.surface.image_data); + + } else { + DEBUG_FUNCTION_LINE("VideoSquoosher: GX2InitTexture failed for g_vid_drcTex!\n"); + } + + GX2InitTexture(&g_vid_tvTex, + 1280, 720, 1, 0, + GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, + GX2_SURFACE_DIM_2D, + GX2_TILE_MODE_LINEAR_ALIGNED + ); + g_vid_tvTex.surface.use = + (GX2_SURFACE_USE_COLOR_BUFFER | GX2_SURFACE_USE_TEXTURE); + + DCFlushRange(&g_vid_tvTex, sizeof(GX2Texture)); + + if (g_vid_tvTex.surface.image_size) { + g_vid_tvTex.surface.image_data = MemoryUtils::alloc( + g_vid_tvTex.surface.image_size, + g_vid_tvTex.surface.align + ); + if(g_vid_tvTex.surface.image_data == NULL) { + OSFatal("VideoSquoosher: Failed to alloc g_vid_tvTex\n"); + } + GX2Invalidate(GX2_INVALIDATE_CPU, g_vid_tvTex.surface.image_data, g_vid_tvTex.surface.image_size); + DEBUG_FUNCTION_LINE("VideoSquoosher: allocated %dx%d g_vid_tvTex %08X\n", + g_vid_tvTex.surface.width, + g_vid_tvTex.surface.height, + g_vid_tvTex.surface.image_data); + } else { + DEBUG_FUNCTION_LINE("VideoSquoosher: GX2InitTexture failed for g_vid_tvTex!\n"); + } + + GX2InitSampler(&g_vid_sampler, + GX2_TEX_CLAMP_CLAMP, + GX2_TEX_XY_FILTER_BILINEAR + ); +} + +DECL_FUNCTION(void, GX2SetContextState, GX2ContextState * curContext) { + if(gAppStatus == WUPS_APP_STATUS_FOREGROUND) { + g_vid_originalContextSave = curContext; + } + real_GX2SetContextState(curContext); +} + +DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer* cbuf, int32_t target) { + bool hasDRCHook = HasHookCallHook(WUPS_LOADER_HOOK_VID_DRC_DRAW); + bool hasTVHook = HasHookCallHook(WUPS_LOADER_HOOK_VID_TV_DRAW); + if(gAppStatus != WUPS_APP_STATUS_FOREGROUND || !g_NotInLoader || (!hasDRCHook && !hasTVHook)) { + return real_GX2CopyColorBufferToScanBuffer(cbuf,target); + } + + if (!g_vid_drcTex.surface.image_data) { + initTextures(); + } + + if(g_vid_ownContextState == NULL) { + setupContextState(); + } + + if(target == 1) { + TextureUtils::copyToTexture(cbuf,&g_vid_tvTex); + if(!hasTVHook) { + return real_GX2CopyColorBufferToScanBuffer(cbuf,target); + } + } else if(target == 4) { + TextureUtils::copyToTexture(cbuf,&g_vid_drcTex); + if(!hasDRCHook) { + return real_GX2CopyColorBufferToScanBuffer(cbuf,target); + } + } + + GX2SetContextState(g_vid_ownContextState); + GX2ClearColor(&g_vid_main_cbuf, 1.0f, 1.0f, 1.0f, 1.0f); + GX2SetContextState(g_vid_ownContextState); + + GX2SetViewport( + 0.0f, 0.0f, + g_vid_main_cbuf.surface.width, g_vid_main_cbuf.surface.height, + 0.0f, 1.0f + ); + GX2SetScissor( + 0, 0, + g_vid_main_cbuf.surface.width, g_vid_main_cbuf.surface.height + ); + + if(target == 1) { + //drawTexture(&g_vid_tvTex, &g_vid_sampler, 0, 0, 1280, 720, 1.0f); + CallHook(WUPS_LOADER_HOOK_VID_TV_DRAW); + } else if(target == 4) { + //drawTexture(&g_vid_drcTex, &g_vid_sampler, 0, 0, 1280, 720, 1.0f); + CallHook(WUPS_LOADER_HOOK_VID_DRC_DRAW); + } + + GX2SetContextState(g_vid_originalContextSave); + + return real_GX2CopyColorBufferToScanBuffer(&g_vid_main_cbuf,target); +} + hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = { MAKE_MAGIC(__PPCExit, LIB_CORE_INIT, STATIC_FUNCTION), MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION), MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION), MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION), + MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2, STATIC_FUNCTION), + MAKE_MAGIC(GX2SetContextState, LIB_GX2, STATIC_FUNCTION), MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION), MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION), MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION), @@ -166,7 +333,6 @@ hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = { MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION), }; - uint32_t method_hooks_size_hooks_static __attribute__((section(".data"))) = sizeof(method_hooks_hooks_static) / sizeof(hooks_magic_t); //! buffer to store our instructions needed for our replacements diff --git a/src/utils.cpp b/src/utils.cpp index 0b5d81f..8de0b7d 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -131,11 +131,25 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed) ((void (*)(wups_loader_init_kernel_args_t))((uint32_t*)func_ptr) )(args); plugin_data->kernel_init_done = true; } - } else if(hook_type == WUPS_LOADER_HOOK_INIT_VID_MEM){ + } else if(hook_type == WUPS_LOADER_HOOK_INIT_VID_MEM) { wups_loader_init_vid_mem_args_t args; args.vid_mem_alloc_ptr = &MemoryUtils::alloc; args.vid_mem_free_ptr = &MemoryUtils::free; ((void (*)(wups_loader_init_vid_mem_args_t))((uint32_t*)func_ptr) )(args); + } else if(hook_type == WUPS_LOADER_HOOK_VID_DRC_DRAW) { + wups_loader_vid_buffer_t args; + args.color_buffer_ptr = &g_vid_main_cbuf; + args.tv_texture_ptr = &g_vid_tvTex; + args.drc_texture_ptr = &g_vid_drcTex; + args.sampler_ptr = &g_vid_sampler; + ((void (*)(wups_loader_vid_buffer_t))((uint32_t*)func_ptr) )(args); + } else if(hook_type == WUPS_LOADER_HOOK_VID_TV_DRAW) { + wups_loader_vid_buffer_t args; + args.color_buffer_ptr = &g_vid_main_cbuf; + args.tv_texture_ptr = &g_vid_tvTex; + args.drc_texture_ptr = &g_vid_drcTex; + args.sampler_ptr = &g_vid_sampler; + ((void (*)(wups_loader_vid_buffer_t))((uint32_t*)func_ptr) )(args); } else { DEBUG_FUNCTION_LINE("ERROR: HOOK TYPE WAS NOT IMPLEMENTED %08X \n",hook_type); }