diff --git a/src/main.cpp b/src/main.cpp index 922a8ad..c2967bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,6 +52,7 @@ #include "Application.h" #include "patcher/function_patcher.h" #include "patcher/hooks_patcher.h" +#include "patcher/hooks_patcher_static.h" #include "plugin/dynamic_linking_defines.h" #include "myutils/mocha.h" #include "myutils/libntfs.h" @@ -136,6 +137,9 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) { } + DEBUG_FUNCTION_LINE("Patch own stuff\n"); + PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static); + DEBUG_FUNCTION_LINE("Do relocations\n"); std::vector relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations(); @@ -190,6 +194,7 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) { } void ApplyPatchesAndCallHookStartingApp() { + PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static); PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks); for(int32_t plugin_index=0; plugin_indexangle stores the rotations per axis since the app started. - // Each full rotation add/subtracts 1.0f (depending on the direction). - - // Check for rotation every only 5 frames. - angleX_frameCounter++; - if(angleX_frameCounter >= 5) { - // Get how much the gamepad rotated within the last 5 frames. - float diff_angle = -(buffer->angle.x - angleX_last); - // We want the gamepad to make (on average) at least 0.16% (1/6) of a full rotation per 5 frames (for 6 times in a row). - float target_diff = (0.16f); - // Calculate if rotated enough in this step (including the delta from the last step). - float total_diff = (diff_angle + angleX_delta) - target_diff; - if(total_diff > 0.0f) { - // The rotation in this step was enough. - angleX_counter++; - // When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation! - if(angleX_counter > 5) { - ConfigUtils::openConfigMenu(); - // reset stuff. - angleX_counter = 0; - angleX_delta = 0.0f; - } else { - // Save difference as it will be added on the next check. - angleX_delta = total_diff; - } - } else { - // reset counter if it stopped rotating. - angleX_counter = 0; - } - angleX_frameCounter = 0; - angleX_last = buffer->angle.x; - } - -} - -DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) { - int32_t result = real_VPADRead(chan, buffer, buffer_size, error); - - if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { - if(MemoryMapping::isMemoryMapped()) { - MemoryMapping::readTestValuesFromMemory(); - } else { - DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n"); - } - vpadPressCooldown = 0x3C; - } - - if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { - ConfigUtils::openConfigMenu(); - vpadPressCooldown = 0x3C; - } else if(result > 0 && OSIsHomeButtonMenuEnabled()) { - checkMagic(buffer); - } - - if(vpadPressCooldown > 0) { - vpadPressCooldown--; - } - return result; -} - - hooks_magic_t method_hooks_hooks[] __attribute__((section(".data"))) = { - MAKE_MAGIC(__PPCExit, LIB_CORE_INIT, STATIC_FUNCTION), - MAKE_MAGIC(ProcUIProcessMessages, LIB_PROC_UI, DYNAMIC_FUNCTION), - MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION), - MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION), - MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION), - MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION), + MAKE_MAGIC(ProcUIProcessMessages, LIB_PROC_UI, DYNAMIC_FUNCTION), }; diff --git a/src/patcher/hooks_patcher_static.cpp b/src/patcher/hooks_patcher_static.cpp new file mode 100644 index 0000000..7411ddd --- /dev/null +++ b/src/patcher/hooks_patcher_static.cpp @@ -0,0 +1,174 @@ +#include +#include +#include +#include "common/retain_vars.h" +#include "hooks_patcher.h" +#include "myutils/overlay_helper.h" +#include "myutils/ConfigUtils.h" +#include "main.h" +#include "utils.h" +#include "mymemory/memory_mapping.h" + +DECL(void, __PPCExit, void) { + // Only continue if we are in the "right" application. + //if(OSGetTitleID() == gGameTitleID) { + //DEBUG_FUNCTION_LINE("__PPCExit\n"); + //CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION); + //DeInit(); + //} + + real___PPCExit(); +} + +DECL_FUNCTION(uint32_t, __OSPhysicalToEffectiveCached, uint32_t phyiscalAddress) { + uint32_t result = real___OSPhysicalToEffectiveCached(phyiscalAddress); + if(result == 0){ + result = MemoryMapping::PhysicalToEffective(phyiscalAddress); + //DEBUG_FUNCTION_LINE("__OSPhysicalToEffectiveCached in %08X out %08X\n",phyiscalAddress,result); + } + return result; +} + +DECL_FUNCTION(uint32_t, __OSPhysicalToEffectiveUncached, uint32_t phyiscalAddress) { + uint32_t result = real___OSPhysicalToEffectiveUncached(phyiscalAddress); + if(result == 0){ + result = MemoryMapping::PhysicalToEffective(phyiscalAddress); + //DEBUG_FUNCTION_LINE("__OSPhysicalToEffectiveUncached in %08X out %08X\n",phyiscalAddress,result); + return result; + } + return result; +} + + +DECL_FUNCTION(uint32_t, OSEffectiveToPhysical, uint32_t virtualAddress) { + uint32_t result = real_OSEffectiveToPhysical(virtualAddress); + if(result == 0){ + result = MemoryMapping::EffectiveToPhysical(virtualAddress); + //DEBUG_FUNCTION_LINE("OSEffectiveToPhysical in %08X out %08X\n",virtualAddress,result); + return result; + } + return result; +} + +DECL_FUNCTION(int32_t, OSIsAddressValid, uint32_t virtualAddress){ + int32_t result = real_OSIsAddressValid(virtualAddress); + if(result == 0){ + result = (MemoryMapping::EffectiveToPhysical(virtualAddress) > 0); + //DEBUG_FUNCTION_LINE("OSIsAddressValid in %08X out %d\n",virtualAddress,result); + return result; + } + return result; +} + +DECL(void, GX2SetTVBuffer, void *buffer, uint32_t buffer_size, int32_t tv_render_mode, int32_t format, int32_t buffering_mode) { + tv_store.buffer = buffer; + tv_store.buffer_size = buffer_size; + tv_store.mode = tv_render_mode; + tv_store.surface_format = format; + tv_store.buffering_mode = buffering_mode; + + return real_GX2SetTVBuffer(buffer,buffer_size,tv_render_mode,format,buffering_mode); +} + +DECL(void, GX2SetDRCBuffer, void *buffer, uint32_t buffer_size, int32_t drc_mode, int32_t surface_format, int32_t buffering_mode) { + drc_store.buffer = buffer; + drc_store.buffer_size = buffer_size; + drc_store.mode = drc_mode; + drc_store.surface_format = surface_format; + drc_store.buffering_mode = buffering_mode; + + return real_GX2SetDRCBuffer(buffer,buffer_size,drc_mode,surface_format,buffering_mode); +} + +DECL(void, GX2WaitForVsync, void) { + CallHook(WUPS_LOADER_HOOK_VSYNC); + real_GX2WaitForVsync(); +} + +uint8_t vpadPressCooldown = 0xFF; + +uint8_t angleX_counter = 0; +float angleX_delta = 0.0f; +float angleX_last = 0.0f; +uint8_t angleX_frameCounter = 0; + +bool checkMagic(VPADData *buffer) { + // buffer->angle stores the rotations per axis since the app started. + // Each full rotation add/subtracts 1.0f (depending on the direction). + + // Check for rotation every only 5 frames. + angleX_frameCounter++; + if(angleX_frameCounter >= 5) { + // Get how much the gamepad rotated within the last 5 frames. + float diff_angle = -(buffer->angle.x - angleX_last); + // We want the gamepad to make (on average) at least 0.16% (1/6) of a full rotation per 5 frames (for 6 times in a row). + float target_diff = (0.16f); + // Calculate if rotated enough in this step (including the delta from the last step). + float total_diff = (diff_angle + angleX_delta) - target_diff; + if(total_diff > 0.0f) { + // The rotation in this step was enough. + angleX_counter++; + // When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation! + if(angleX_counter > 5) { + ConfigUtils::openConfigMenu(); + // reset stuff. + angleX_counter = 0; + angleX_delta = 0.0f; + } else { + // Save difference as it will be added on the next check. + angleX_delta = total_diff; + } + } else { + // reset counter if it stopped rotating. + angleX_counter = 0; + } + angleX_frameCounter = 0; + angleX_last = buffer->angle.x; + } + +} + +DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) { + int32_t result = real_VPADRead(chan, buffer, buffer_size, error); + + if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { + if(MemoryMapping::isMemoryMapped()) { + MemoryMapping::readTestValuesFromMemory(); + } else { + DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n"); + } + vpadPressCooldown = 0x3C; + } + + if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) { + ConfigUtils::openConfigMenu(); + vpadPressCooldown = 0x3C; + } else if(result > 0 && OSIsHomeButtonMenuEnabled()) { + checkMagic(buffer); + } + + if(vpadPressCooldown > 0) { + vpadPressCooldown--; + } + return result; +} + + +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(VPADRead, LIB_VPAD, STATIC_FUNCTION), + MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION), + MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION), + MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION), + 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 +volatile uint32_t method_calls_hooks_static[sizeof(method_hooks_hooks_static) / sizeof(hooks_magic_t) * FUNCTION_PATCHER_METHOD_STORE_SIZE] __attribute__((section(".data"))); + diff --git a/src/patcher/hooks_patcher_static.h b/src/patcher/hooks_patcher_static.h new file mode 100644 index 0000000..16ea7ad --- /dev/null +++ b/src/patcher/hooks_patcher_static.h @@ -0,0 +1,18 @@ +#ifndef _HOOKS_STATIC_FUNCTION_PATCHER_H +#define _HOOKS_STATIC_FUNCTION_PATCHER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern hooks_magic_t method_hooks_hooks_static[]; +extern uint32_t method_hooks_size_hooks_static; +extern volatile uint32_t method_calls_hooks_static[]; + +#ifdef __cplusplus +} +#endif + +#endif /* _HOOKS_STATIC_FUNCTION_PATCHER_H */