From 9302893549f9fb9efccaf48190c1a4ebcffbba70 Mon Sep 17 00:00:00 2001 From: CrazyRedMachine Date: Wed, 22 Feb 2023 23:42:16 +0100 Subject: [PATCH] keysound offset --- dist/popnhax/popnhax.xml | 19 +++-- popnhax/config.h | 1 + popnhax/dllmain.cc | 153 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 7 deletions(-) diff --git a/dist/popnhax/popnhax.xml b/dist/popnhax/popnhax.xml index 12439e6..52b11d2 100644 --- a/dist/popnhax/popnhax.xml +++ b/dist/popnhax/popnhax.xml @@ -10,7 +10,7 @@ 0 0 - + 0 0 @@ -22,15 +22,20 @@ 0 0 - - + + 0 - - 0 - - 0 1 + + + + + 0 + + 0 + + 0 diff --git a/popnhax/config.h b/popnhax/config.h index 0888643..dc761d8 100644 --- a/popnhax/config.h +++ b/popnhax/config.h @@ -21,6 +21,7 @@ struct popnhax_config { bool disable_redirection; bool patch_xml_auto; char patch_xml_filename[MAX_PATH]; + int8_t keysound_offset; }; #endif diff --git a/popnhax/dllmain.cc b/popnhax/dllmain.cc index dc61325..5e76962 100644 --- a/popnhax/dllmain.cc +++ b/popnhax/dllmain.cc @@ -107,6 +107,8 @@ PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, patch_xml_auto "/popnhax/patch_xml_auto") PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_STR, struct popnhax_config, patch_xml_filename, "/popnhax/patch_xml_filename") +PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, keysound_offset, + "/popnhax/keysound_offset") PSMAP_END enum BufferIndexes { @@ -172,6 +174,13 @@ void quickexit_game_loop() real_game_loop(); } +int16_t g_keysound_offset = 0; +void (*real_eval_timing)(); +void patch_eval_timing() { + __asm("mov esi, %0\n": :"b"((int32_t)g_keysound_offset)); + real_eval_timing(); +} + uint32_t g_transition_addr = 0; uint32_t g_stage_addr = 0; void (*real_result_loop)(); @@ -1280,6 +1289,68 @@ static bool get_addr_timing_offset(uint32_t *res) return true; } +/* helper function to retrieve SD timing address */ +static bool get_addr_sd_timing(uint32_t *res) +{ + static uint32_t addr = 0; + + if (addr != 0) + { + *res = addr; + return true; + } + + DWORD dllSize = 0; + char *data = getDllData("popn22.dll", &dllSize); + + fuzzy_search_task task; + + FUZZY_START(task, 1) + FUZZY_CODE(task, 0, "\xB8\xC4\xFF\xFF\xFF", 5) + int64_t pattern_offset = find_block(data, dllSize, &task, 0); + if (pattern_offset == -1) { + return false; + } + + addr = (uint32_t) ((int64_t)data + pattern_offset + 1); +#if DEBUG == 1 + printf("SD TIMING MEMORYZONE %x\n", addr); +#endif + *res = addr; + return true; +} + +/* helper function to retrieve HD timing address */ +static bool get_addr_hd_timing(uint32_t *res) +{ + static uint32_t addr = 0; + + if (addr != 0) + { + *res = addr; + return true; + } + + DWORD dllSize = 0; + char *data = getDllData("popn22.dll", &dllSize); + + fuzzy_search_task task; + + FUZZY_START(task, 1) + FUZZY_CODE(task, 0, "\xB8\xB4\xFF\xFF\xFF", 5) + int64_t pattern_offset = find_block(data, dllSize, &task, 0); + if (pattern_offset == -1) { + return false; + } + + addr = (uint32_t) ((int64_t)data + pattern_offset + 1); +#if DEBUG == 1 + printf("HD TIMING MEMORYZONE %x\n", addr); +#endif + *res = addr; + return true; +} + static bool patch_hidden_is_offset() { DWORD dllSize = 0; @@ -1604,6 +1675,75 @@ static bool patch_quick_retire(bool pfree) return true; } +static bool patch_add_to_base_offset(int8_t delta) { + int32_t new_value = delta; + char *as_hex = (char *) &new_value; + + printf("popnhax: base offset: adding %d to base offset.\n",delta); + + /* call get_addr_timing_offset() so that it can still work after timing value is overwritten */ + uint32_t original_timing; + get_addr_timing_offset(&original_timing); + + uint32_t sd_timing_addr; + if (!get_addr_sd_timing(&sd_timing_addr)) + { + printf("popnhax: base offset: cannot find base SD timing\n"); + return false; + } + + int32_t current_value = *(int32_t *) sd_timing_addr; + new_value = current_value+delta; + patch_memory(sd_timing_addr, as_hex, 4); + printf("popnhax: base offset: SD offset is now %d.\n",new_value); + + + uint32_t hd_timing_addr; + if (!get_addr_hd_timing(&hd_timing_addr)) + { + printf("popnhax: base offset: cannot find base HD timing\n"); + return false; + } + current_value = *(int32_t *) hd_timing_addr; + new_value = current_value+delta; + patch_memory(hd_timing_addr, as_hex, 4); + printf("popnhax: base offset: HD offset is now %d.\n",new_value); + + return true; +} + +static bool patch_keysound_offset(int8_t value) +{ + DWORD dllSize = 0; + char *data = getDllData("popn22.dll", &dllSize); + g_keysound_offset = -1*value; + + patch_add_to_base_offset(value); + + { + fuzzy_search_task task; + + FUZZY_START(task, 1) + FUZZY_CODE(task, 0, "\x51\x53\x56\x57\x0f\xb7\xf8\x8b\x34\xfd", 10) + + int64_t pattern_offset = find_block(data, dllSize, &task, 0); + if (pattern_offset == -1) { + printf("popnhax: keysound offset: cannot prepatch\n"); + return false; + } + + uint64_t patch_addr = (int64_t)data + pattern_offset + 0x07; + patch_memory(patch_addr, (char *)"\x03", 1); + + MH_CreateHook((LPVOID)(patch_addr-0x03), (LPVOID)patch_eval_timing, + (void **)&real_eval_timing); + + printf("popnhax: keysound offset: timing offset by %d ms\n", value); + } + + return true; +} + static bool patch_base_offset(int32_t value) { char *as_hex = (char *) &value; bool res = true; @@ -1612,6 +1752,12 @@ static bool patch_base_offset(int32_t value) { uint32_t original_timing; get_addr_timing_offset(&original_timing); + uint32_t sd_timing_addr; + get_addr_sd_timing(&sd_timing_addr); + + uint32_t hd_timing_addr; + get_addr_hd_timing(&hd_timing_addr); + if (!patch_hex("\xB8\xC4\xFF\xFF\xFF", 5, 1, as_hex, 4)) { printf("popnhax: base offset: cannot patch base SD timing\n"); @@ -1627,6 +1773,8 @@ static bool patch_base_offset(int32_t value) { return res; } + + static bool patch_hd_on_sd(uint8_t mode) { if (mode > 2) { @@ -1693,6 +1841,11 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv patch_hidden_is_offset(); } + if (config.keysound_offset){ + /* must be called after hd_on_sd */ + patch_keysound_offset(config.keysound_offset); + } + if (config.event_mode) { patch_event_mode(); }