mercury: fix left touch board, window focus, launch params

This commit is contained in:
Dniel97 2026-01-14 23:30:00 +01:00
parent 2475b48ef3
commit 3a8bde7ca8
No known key found for this signature in database
GPG Key ID: DE105D481972329C
6 changed files with 68 additions and 51 deletions

View File

@ -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
pause

View File

@ -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

View File

@ -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 */

View File

@ -1,4 +1,3 @@
#include <initguid.h>
#include <windows.h>
#include <assert.h>
@ -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);

View File

@ -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;

View File

@ -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;
}