diff --git a/dist/popnhax/popnhax.xml b/dist/popnhax/popnhax.xml
index e5c17a0..35c7a50 100644
--- a/dist/popnhax/popnhax.xml
+++ b/dist/popnhax/popnhax.xml
@@ -65,7 +65,9 @@
0
-
+
+ 0
+
0
0
diff --git a/popnhax/config.h b/popnhax/config.h
index 72ce67e..4798f37 100644
--- a/popnhax/config.h
+++ b/popnhax/config.h
@@ -31,6 +31,7 @@ struct popnhax_config {
char patch_xml_filename[MAX_PATH];
char force_datecode[11];
bool network_datecode;
+ bool disable_keysounds;
int8_t keysound_offset;
int8_t beam_brightness;
bool fps_uncap;
diff --git a/popnhax/dllmain.cc b/popnhax/dllmain.cc
index ad3ea19..e650c6b 100644
--- a/popnhax/dllmain.cc
+++ b/popnhax/dllmain.cc
@@ -141,6 +141,8 @@ PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_STR, struct popnhax_config, force_datecode,
"/popnhax/force_datecode")
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, network_datecode,
"/popnhax/network_datecode")
+PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, disable_keysounds,
+ "/popnhax/disable_keysounds")
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, keysound_offset,
"/popnhax/keysound_offset")
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, beam_brightness,
@@ -2135,6 +2137,96 @@ static bool patch_enhanced_polling(uint8_t debounce)
return true;
}
+void (*real_chart_load)();
+void patch_chart_load_old() {
+ __asm("cmp word ptr [edi+eax*8+4], 0x245\n");
+ __asm("jne not_keysound_old\n");
+ __asm("mov word ptr [edi+eax*8+4], 0x745\n");
+ __asm("not_keysound_old:\n");
+ real_chart_load();
+}
+void patch_chart_load() {
+ __asm("cmp word ptr [eax+4], 0x245\n");
+ __asm("jne patch_chart_load_end\n");
+
+ /* keysound event has been found, we need to convert timestamp */
+ __asm("mov word ptr [eax+4], 0x745\n"); // we'll undo it if we cannot apply it
+ __asm("push eax\n"); // chunk pointer (keysound timestamp at beginning)
+ __asm("push ecx\n"); // remaining chunks (add eax, C, sub ecx, 1, jne next_iter, end of file there
+ __asm("push ebx\n"); // we'll store a copy of our chunk pointer there
+ __asm("push edx\n"); // we'll store the button info there
+ /* check button associated with keysound, then look for next note event for this button */
+ __asm("mov dl, byte ptr [eax+7]\n");
+ __asm("shr edx, 4\n"); //dl now contains button value ( 00-08 )
+
+ __asm("mov ebx, eax\n"); //write timestamp into ebx when a match is found
+ __asm("look_for_note_event:\n");
+ __asm("add eax, 0xC\n");
+ __asm("sub ecx, 1\n");
+ __asm("jz end_of_chart\n");
+
+ __asm("cmp word ptr [eax+4], 0x145\n");
+ __asm("jne look_for_note_event\n");
+ /* note event */
+ __asm("cmp dl, byte ptr [eax+6]\n");
+ __asm("jne look_for_note_event\n");
+ /* note event with corresponding button! */
+ __asm("mov edx, dword ptr [eax]\n");
+ __asm("mov dword ptr [ebx], edx\n");
+ __asm("jmp keysound_handled\n");
+
+ __asm("end_of_chart:\n");
+ __asm("pop edx\n");
+ __asm("pop ebx\n");
+ __asm("pop ecx\n");
+ __asm("pop eax\n");
+ __asm("mov word ptr [eax+4], 0x245\n"); // no match found (ad-lib keysound?), restore opcode
+ __asm("jmp patch_chart_load_end\n");
+
+ __asm("keysound_handled:\n");
+ __asm("pop edx\n");
+ __asm("pop ebx\n");
+ __asm("pop ecx\n");
+ __asm("pop eax\n");
+
+ __asm("patch_chart_load_end:\n");
+ real_chart_load();
+}
+
+static bool patch_disable_keysound()
+{
+ DWORD dllSize = 0;
+ char *data = getDllData(g_game_dll_fn, &dllSize);
+
+ {
+ int64_t pattern_offset = search(data, dllSize, "\xB9\xFF\x1C\x00\x00", 5, 0);
+ if (pattern_offset == -1) {
+ LOG("popnhax: keysound disable: cannot find offset\n");
+ return false;
+ }
+
+ /* detect if usaneko+ */
+ uint64_t patch_addr = (int64_t)data + pattern_offset + 0x0B;
+ uint8_t check_byte = *((uint8_t *)(patch_addr + 1));
+
+ if (check_byte == 0x04)
+ {
+ LOG("popnhax: keysound disable: old game version\n");
+ MH_CreateHook((LPVOID)(patch_addr), (LPVOID)patch_chart_load_old,
+ (void **)&real_chart_load); //turn 0x0245 opcodes into 0x0745
+ }
+ else
+ {
+ MH_CreateHook((LPVOID)(patch_addr), (LPVOID)patch_chart_load,
+ (void **)&real_chart_load); //turn 0x0245 opcodes into 0x0745
+ }
+
+ LOG("popnhax: no more keysounds\n");
+ }
+
+ return true;
+}
+
static bool patch_keysound_offset(int8_t value)
{
DWORD dllSize = 0;
@@ -3330,6 +3422,10 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
force_show_fast_slow();
}
+ if (config.disable_keysounds){
+ patch_disable_keysound();
+ }
+
if (config.keysound_offset){
/* must be called _after_ force_hd_timing */
patch_keysound_offset(config.keysound_offset);