From 3a8bde7ca8d08c21d4f3520a8242da90a05e5e8d Mon Sep 17 00:00:00 2001 From: Dniel97 Date: Wed, 14 Jan 2026 23:30:00 +0100 Subject: [PATCH] mercury: fix left touch board, window focus, launch params --- dist/mercury/launch.bat | 6 +-- dist/mercury/segatools.ini | 1 - games/mercuryhook/dllmain.c | 7 ++-- games/mercuryhook/elizabeth.c | 34 +++++++++++------ games/mercuryhook/io4.c | 2 +- games/mercuryhook/touch.c | 69 ++++++++++++++++++++--------------- 6 files changed, 68 insertions(+), 51 deletions(-) diff --git a/dist/mercury/launch.bat b/dist/mercury/launch.bat index 7445a6e..46caed9 100644 --- a/dist/mercury/launch.bat +++ b/dist/mercury/launch.bat @@ -2,14 +2,14 @@ pushd %~dp0 REM USA -REM start "AM Daemon" /min inject -d -k mercuryhook.dll amdaemon.exe -f -c config.json config_lan_install_client.json config_lan_install_server.json config_video_clone.json config_video_dual.json config_video_clone_flip.json config_video_dual_flip.json config_region_exp.json config_region_chn.json config_region_usa.json +REM start "AM Daemon" /min inject -d -k mercuryhook.dll amdaemon.exe -c config.json config_lan_install_client.json config_lan_install_server.json config_video_clone.json config_video_dual.json config_video_clone_flip.json config_video_dual_flip.json config_region_exp.json config_region_chn.json config_region_usa.json REM JP -start "AM Daemon" /min inject -d -k mercuryhook.dll amdaemon.exe -f -c config.json config_lan_install_client.json config_lan_install_server.json config_video_clone.json config_video_dual.json config_video_clone_flip.json config_video_dual_flip.json config_region_exp.json config_region_chn.json config_region_jpn.json +start "AM Daemon" /min inject -d -k mercuryhook.dll amdaemon.exe -c config.json config_lan_install_client.json config_lan_install_server.json config_video_clone.json config_video_dual.json config_video_clone_flip.json config_video_dual_flip.json config_region_exp.json config_region_chn.json config_region_jpn.json inject -d -k mercuryhook.dll ../WindowsNoEditor/Mercury/Binaries/Win64/Mercury-Win64-Shipping.exe taskkill /f /im amdaemon.exe > nul 2>&1 echo. echo Game processes have terminated -pause \ No newline at end of file +pause diff --git a/dist/mercury/segatools.ini b/dist/mercury/segatools.ini index 64e11d0..07fdffb 100644 --- a/dist/mercury/segatools.ini +++ b/dist/mercury/segatools.ini @@ -94,7 +94,6 @@ enable=1 ; Enable DPI awareness for the game process, preventing Windows from stretching the game window if a DPI scaling higher than 100% is used dpiAware=1 - ; Hooks related to the touch boards [touch] enable=1 diff --git a/games/mercuryhook/dllmain.c b/games/mercuryhook/dllmain.c index 11a5527..62261c6 100644 --- a/games/mercuryhook/dllmain.c +++ b/games/mercuryhook/dllmain.c @@ -57,10 +57,9 @@ static DWORD CALLBACK mercury_pre_startup(void) /* Hook Win32 APIs */ dvd_hook_init(&mercury_hook_cfg.dvd, mercury_hook_mod); - serial_hook_init(); - gfx_hook_init(&mercury_hook_cfg.gfx); gfx_d3d11_hook_init(&mercury_hook_cfg.gfx, mercury_hook_mod); + serial_hook_init(); /* Initialize emulation hooks */ @@ -106,9 +105,9 @@ static DWORD CALLBACK mercury_pre_startup(void) goto fail; } - /* Start elisabeth Hooks for the LED and IO Board DLLs */ - elizabeth_hook_init(&mercury_hook_cfg.elizabeth); + /* Start elizabeth hooks for the LED and IO board DLLs */ + elizabeth_hook_init(&mercury_hook_cfg.elizabeth); touch_hook_init(&mercury_hook_cfg.touch); /* Initialize debug helpers */ diff --git a/games/mercuryhook/elizabeth.c b/games/mercuryhook/elizabeth.c index 9fd4aaa..ffc7c26 100644 --- a/games/mercuryhook/elizabeth.c +++ b/games/mercuryhook/elizabeth.c @@ -1,4 +1,3 @@ -#include #include #include @@ -20,15 +19,24 @@ /* Hooks targeted DLLs dynamically loaded by elizabeth. */ static void dll_hook_insert_hooks(HMODULE target); -static FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name); + +/* Hook functions */ + +static FARPROC WINAPI hook_GetProcAddress(HMODULE hModule, const char *name); + +static int hook_USBIntLED_Init(); + +static int hook_USBIntLED_set(int data1, struct led_data data2); + +/* Link pointers */ + static FARPROC (WINAPI *next_GetProcAddress)(HMODULE hModule, const char *name); -static int my_USBIntLED_Init(); -static int my_USBIntLED_set(int data1, struct led_data data2); + static const struct hook_symbol win32_hooks[] = { { .name = "GetProcAddress", - .patch = my_GetProcAddress, + .patch = hook_GetProcAddress, .link = (void **) &next_GetProcAddress } }; @@ -38,8 +46,10 @@ HRESULT elizabeth_hook_init(struct elizabeth_config *cfg) if (!cfg->enable) { return S_OK; } + dll_hook_insert_hooks(NULL); - dprintf("elizabeth: Init\n"); + dprintf("Elizabeth: Init\n"); + return S_OK; } @@ -52,7 +62,7 @@ static void dll_hook_insert_hooks(HMODULE target) _countof(win32_hooks)); } -FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name) +FARPROC WINAPI hook_GetProcAddress(HMODULE hModule, const char *name) { uintptr_t ordinal = (uintptr_t) name; @@ -61,11 +71,11 @@ FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name) if (ordinal > 0xFFFF) { /* Import by name */ if (strcmp(name, "USBIntLED_Init") == 0) { - result = (FARPROC) my_USBIntLED_Init; + result = (FARPROC) hook_USBIntLED_Init; } if (strcmp(name, "USBIntLED_set") == 0) { - result = (FARPROC) my_USBIntLED_set; + result = (FARPROC) hook_USBIntLED_set; } } @@ -73,13 +83,13 @@ FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name) } /* Intercept the call to initialize the LED board. */ -static int my_USBIntLED_Init() +static int hook_USBIntLED_Init() { - dprintf("elizabeth: my_USBIntLED_Init hit!\n"); + dprintf("Elizabeth: hook_USBIntLED_Init hit!\n"); return 1; } -static int my_USBIntLED_set(int data1, struct led_data data2) +static int hook_USBIntLED_set(int data1, struct led_data data2) { assert(mercury_dll.set_leds != NULL); mercury_dll.set_leds(data2); diff --git a/games/mercuryhook/io4.c b/games/mercuryhook/io4.c index c34eb6f..a5bb088 100644 --- a/games/mercuryhook/io4.c +++ b/games/mercuryhook/io4.c @@ -25,7 +25,7 @@ HRESULT mercury_io4_hook_init(const struct io4_config* cfg) { assert(mercury_dll.init != NULL); - hr = io4_hook_init(cfg, &mercury_io4_ops, NULL, L"Mercury", false); + hr = io4_hook_init(cfg, &mercury_io4_ops, NULL, L"Mercury", true); if (FAILED(hr)) { return hr; diff --git a/games/mercuryhook/touch.c b/games/mercuryhook/touch.c index 3f73a2b..89189bb 100644 --- a/games/mercuryhook/touch.c +++ b/games/mercuryhook/touch.c @@ -41,10 +41,10 @@ static HRESULT touch_handle_mystery2(const struct touch_req *req); static HRESULT touch_handle_start_auto_scan(const struct touch_req *req); static void touch_res_auto_scan(const bool *state); -uint8_t input_frame_count_0 = 0x7b; -uint8_t input_frame_count_1 = 0x7b; -bool touch0_auto = false; -bool touch1_auto = false; +static uint8_t input_frame_count_0 = 0; +static uint8_t input_frame_count_1 = 0; +static bool touch0_auto = false; +static bool touch1_auto = false; static CRITICAL_SECTION touch0_lock; static struct uart touch0_uart; @@ -67,7 +67,7 @@ HRESULT touch_hook_init(const struct touch_config *cfg) InitializeCriticalSection(&touch0_lock); InitializeCriticalSection(&touch1_lock); - dprintf("Wacca touch: Init\n"); + dprintf("Wacca Touch: Init\n"); uart_init(&touch0_uart, 3); touch0_uart.written.bytes = touch0_written_bytes; @@ -113,11 +113,11 @@ static HRESULT touch0_handle_irp_locked(struct irp *irp) HRESULT hr; if (irp->op == IRP_OP_OPEN) { - dprintf("Wacca touch0: Starting backend\n"); + dprintf("Wacca Touch0: Starting backend\n"); hr = mercury_dll.touch_init(); if (FAILED(hr)) { - dprintf("Wacca touch: Backend error: %x\n", (int) hr); + dprintf("Wacca Touch: Backend error: %x\n", (int) hr); return hr; } @@ -138,7 +138,7 @@ static HRESULT touch0_handle_irp_locked(struct irp *irp) if (hr != S_OK) { if (FAILED(hr)) { - dprintf("Wacca touch: Deframe error: %x\n", (int) hr); + dprintf("Wacca Touch: Deframe error: %x\n", (int) hr); } return hr; @@ -147,7 +147,7 @@ static HRESULT touch0_handle_irp_locked(struct irp *irp) hr = touch_req_dispatch(&req); if (FAILED(hr)) { - dprintf("Wacca touch: Processing error: %x\n", (int) hr); + dprintf("Wacca Touch: Processing error: %x\n", (int) hr); } return hr; @@ -160,11 +160,11 @@ static HRESULT touch1_handle_irp_locked(struct irp *irp) HRESULT hr; if (irp->op == IRP_OP_OPEN) { - dprintf("Wacca touch1: Starting backend\n"); + dprintf("Wacca Touch1: Starting backend\n"); hr = mercury_dll.touch_init(); if (FAILED(hr)) { - dprintf("Wacca touch: Backend error: %x\n", (int) hr); + dprintf("Wacca Touch: Backend error: %x\n", (int) hr); return hr; } @@ -186,7 +186,7 @@ static HRESULT touch1_handle_irp_locked(struct irp *irp) if (hr != S_OK) { if (FAILED(hr)) { - dprintf("Wacca touch: Deframe error: %x\n", (int) hr); + dprintf("Wacca Touch: Deframe error: %x\n", (int) hr); } return hr; @@ -195,7 +195,7 @@ static HRESULT touch1_handle_irp_locked(struct irp *irp) hr = touch_req_dispatch(&req); if (FAILED(hr)) { - dprintf("Wacca touch: Processing error: %x\n", (int) hr); + dprintf("Wacca Touch: Processing error: %x\n", (int) hr); } return hr; @@ -218,13 +218,13 @@ static HRESULT touch_req_dispatch(const struct touch_req *req) case CMD_START_AUTO_SCAN: return touch_handle_start_auto_scan(req); case CMD_BEGIN_WRITE: - dprintf("Wacca touch: Begin write for side %d\n", req->side); + dprintf("Wacca Touch: Begin write for side %d\n", req->side); return S_OK; case CMD_NEXT_WRITE: - dprintf("Wacca touch: continue write for side %d\n", req->side); + dprintf("Wacca Touch: continue write for side %d\n", req->side); return S_OK; default: - dprintf("Wacca touch: Unhandled command %02x\n", req->cmd); + dprintf("Wacca Touch: Unhandled command %02x\n", req->cmd); return S_OK; } } @@ -272,7 +272,7 @@ static HRESULT touch_handle_next_read(const struct touch_req *req) rev = " 101 115 98 86 76 67 68 48 117 0 82 154 0 6 35 4"; break; default: - dprintf("Wacca touch: BAD READ REQUEST %2hx\n", req->data[2]); + dprintf("Wacca Touch: BAD READ REQUEST %2hx\n", req->data[2]); return 1; } @@ -294,13 +294,14 @@ static HRESULT touch_handle_get_unit_board_ver(const struct touch_req *req) struct touch_resp_get_unit_board_ver resp; HRESULT hr; memset(&resp, 0, sizeof(resp)); - dprintf("Wacca Touch%d: get unit board version\n", req->side); + dprintf("Wacca Touch%d: Get unit board version\n", req->side); memset(resp.version, 0, sizeof(resp.version)); memcpy(resp.version, SYNC_BOARD_VER, sizeof(SYNC_BOARD_VER)); - for (int i = 0; i < 6; i++ ) + for (int i = 0; i < 6; i++) { memcpy(&resp.version[7 + (6 * i)], UNIT_BOARD_VER, sizeof(UNIT_BOARD_VER)); + } resp.cmd = 0xa8; resp.checksum = 0; @@ -386,15 +387,17 @@ static HRESULT touch_handle_start_auto_scan(const struct touch_req *req) // but the game doesn't seem to mind that it's the same uint8_t data2[9] = { 0x0d, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00 }; - dprintf("Wacca Touch%d: Start Auto", req->side); + dprintf("Wacca Touch%d: Start Auto\n", req->side); #if defined(LOG_MERCURY_SLIDER) - for (int i = 0; i < req->data_length; i++) + for (int i = 0; i < req->data_length; i++) { dprintf("0x%02x ", req->data[i]); - #endif - dprintf("\n"); + } - resp.cmd = 0x9c; + dprintf("\n"); + #endif + + resp.cmd = 0xC9; resp.data = 0; resp.checksum = 0x49; @@ -416,6 +419,7 @@ static HRESULT touch_handle_start_auto_scan(const struct touch_req *req) } mercury_dll.touch_start(touch_res_auto_scan); + return hr; } @@ -434,11 +438,16 @@ static void touch_res_auto_scan(const bool *state) frame0.cmd = 0x81; frame0.count = input_frame_count_0++; - input_frame_count_0 %= 0x7f; + if (input_frame_count_0 > 127) { + input_frame_count_0 = 0; + } + frame1.cmd = 0x81; frame1.count = input_frame_count_1++; - input_frame_count_1 %= 0x7f; + if (input_frame_count_1 > 127) { + input_frame_count_1 = 0; + } for (int i = 0; i < 24; i++) { for (int j = 0; j < 5; j++) { @@ -465,14 +474,14 @@ static void touch_res_auto_scan(const bool *state) frame1.checksum = calc_checksum(&frame1, sizeof(frame1)); if (touch0_auto) { - //dprintf("Wacca touch: Touch0 auto frame #%2hx sent\n", frame0.count); + //dprintf("Wacca Touch: Touch0 auto frame #%2hx sent\n", frame0.count); EnterCriticalSection(&touch0_lock); iobuf_write(&touch0_uart.readable, &frame0, sizeof(frame0)); LeaveCriticalSection(&touch0_lock); } if (touch1_auto) { - //dprintf("Wacca touch: Touch1 auto frame #%2hx sent\n", frame0.count); + //dprintf("Wacca Touch: Touch1 auto frame #%2hx sent\n", frame0.count); EnterCriticalSection(&touch1_lock); iobuf_write(&touch1_uart.readable, &frame1, sizeof(frame1)); LeaveCriticalSection(&touch1_lock); @@ -510,9 +519,9 @@ static uint8_t calc_checksum(const void *ptr, size_t nbytes) src = ptr; for (size_t i = 0; i < nbytes; i++) { - //dprintf("Wacca touch: Calculating %2hx\n", src[i]); + //dprintf("Wacca Touch: Calculating %2hx\n", src[i]); checksum = checksum^(src[i]); } - //dprintf("Wacca touch: Checksum is %2hx\n", checksum&0x7f); + //dprintf("Wacca Touch: Checksum is %2hx\n", checksum&0x7f); return checksum&0x7f; }