diff --git a/mercuryhook/config.c b/mercuryhook/config.c index 9a61aad8..3b31afd9 100644 --- a/mercuryhook/config.c +++ b/mercuryhook/config.c @@ -27,6 +27,20 @@ void mercury_dll_config_load( filename); } +void touch_config_load( + struct touch_config *cfg, + const wchar_t *filename) +{ + assert(cfg != NULL); + assert(filename != NULL); + + GetPrivateProfileIntW( + L"touch", + L"enable", + 1, + filename); +} + void mercury_hook_config_load( struct mercury_hook_config *cfg, const wchar_t *filename) @@ -40,4 +54,5 @@ void mercury_hook_config_load( io4_config_load(&cfg->io4, filename); gfx_config_load(&cfg->gfx, filename); mercury_dll_config_load(&cfg->dll, filename); + touch_config_load(&cfg->touch, filename); } diff --git a/mercuryhook/config.h b/mercuryhook/config.h index 627e69c4..1ead488d 100644 --- a/mercuryhook/config.h +++ b/mercuryhook/config.h @@ -8,6 +8,7 @@ #include "hooklib/gfx.h" #include "mercuryhook/mercury-dll.h" +#include "mercuryhook/touch.h" #include "platform/config.h" @@ -18,6 +19,7 @@ struct mercury_hook_config { struct io4_config io4; struct gfx_config gfx; struct mercury_dll_config dll; + struct touch_config touch; }; void mercury_dll_config_load( diff --git a/mercuryhook/dllmain.c b/mercuryhook/dllmain.c index 3c7786d4..7296c61f 100644 --- a/mercuryhook/dllmain.c +++ b/mercuryhook/dllmain.c @@ -13,6 +13,7 @@ #include "mercuryhook/io4.h" #include "mercuryhook/mercury-dll.h" #include "mercuryhook/elisabeth.h" +#include "mercuryhook/touch.h" #include "platform/platform.h" @@ -79,6 +80,8 @@ static DWORD CALLBACK mercury_pre_startup(void) /* Start elisabeth Hooks for the LED and IO Board DLLs */ elisabeth_hook_init(); + touch_hook_init(&mercury_hook_cfg.touch); + /* Initialize debug helpers */ spike_hook_init(L".\\segatools.ini"); diff --git a/mercuryhook/meson.build b/mercuryhook/meson.build index 6269e27e..ffa0f881 100644 --- a/mercuryhook/meson.build +++ b/mercuryhook/meson.build @@ -26,6 +26,8 @@ shared_library( 'mercury-dll.c', 'mercury-dll.h', 'elisabeth.h', - 'elisabeth.c' + 'elisabeth.c', + 'touch.h', + 'touch.c' ], ) diff --git a/mercuryhook/touch.c b/mercuryhook/touch.c new file mode 100644 index 00000000..60e7d96b --- /dev/null +++ b/mercuryhook/touch.c @@ -0,0 +1,164 @@ +#include + +#include +#include +#include +#include +#include + +#include "board/slider-cmd.h" +#include "board/slider-frame.h" + +#include "mercuryhook/mercury-dll.h" +#include "mercuryhook/touch.h" + +#include "hook/iobuf.h" +#include "hook/iohook.h" + +#include "hooklib/uart.h" + +#include "util/dprintf.h" +#include "util/dump.h" + +static HRESULT touch0_handle_irp(struct irp *irp); +static HRESULT touch0_handle_irp_locked(struct irp *irp); + +static HRESULT touch_req_dispatch(const union slider_req_any *req); + +static void touch_res_auto_scan(const uint8_t *state); + +static CRITICAL_SECTION touch0_lock; +static struct uart touch0_uart; +static uint8_t touch0_written_bytes[520]; +static uint8_t touch0_readable_bytes[520]; + +static CRITICAL_SECTION touch1_lock; +static struct uart touch1_uart; +static uint8_t touch1_written_bytes[520]; +static uint8_t touch1_readable_bytes[520]; + +HRESULT touch_hook_init(const struct touch_config *cfg) +{ + assert(cfg != NULL); + assert(mercury_dll.touch_init != NULL); + + // not sure why this always returns false... + /*if (!cfg->enable) { + return S_FALSE; + }*/ + + InitializeCriticalSection(&touch0_lock); + InitializeCriticalSection(&touch1_lock); + dprintf("Wacca touch: init\n"); + + uart_init(&touch0_uart, 3); + touch0_uart.written.bytes = touch0_written_bytes; + touch0_uart.written.nbytes = sizeof(touch0_written_bytes); + touch0_uart.readable.bytes = touch0_readable_bytes; + touch0_uart.readable.nbytes = sizeof(touch0_readable_bytes); + + uart_init(&touch1_uart, 4); + touch1_uart.written.bytes = touch1_written_bytes; + touch1_uart.written.nbytes = sizeof(touch1_written_bytes); + touch1_uart.readable.bytes = touch1_readable_bytes; + touch1_uart.readable.nbytes = sizeof(touch1_readable_bytes); + + return iohook_push_handler(touch0_handle_irp); +} + +static HRESULT touch0_handle_irp(struct irp *irp) +{ + HRESULT hr; + + assert(irp != NULL); + + if (!uart_match_irp(&touch0_uart, irp)) { + return iohook_invoke_next(irp); + } + + EnterCriticalSection(&touch0_lock); + hr = touch0_handle_irp_locked(irp); + LeaveCriticalSection(&touch0_lock); + + return hr; +} + +static HRESULT touch0_handle_irp_locked(struct irp *irp) +{ + union slider_req_any req; + struct iobuf req_iobuf; + HRESULT hr; + + if (irp->op == IRP_OP_OPEN) { + dprintf("Wacca touch: Starting backend\n"); + hr = mercury_dll.touch_init(); + + if (FAILED(hr)) { + dprintf("Wacca touch: Backend error: %x\n", (int) hr); + + return hr; + } + } + + hr = uart_handle_irp(&touch0_uart, irp); + + if (FAILED(hr) || irp->op != IRP_OP_WRITE) { + return hr; + } + + for (;;) { +#if 0 + dprintf("TX Buffer:\n"); + dump_iobuf(&touch0_uart.written); +#endif + + req_iobuf.bytes = req.bytes; + req_iobuf.nbytes = sizeof(req.bytes); + req_iobuf.pos = 0; + + hr = slider_frame_decode(&req_iobuf, &touch0_uart.written); + + if (hr != S_OK) { + if (FAILED(hr)) { + dprintf("Wacca touch: Deframe error: %x\n", (int) hr); + } + + return hr; + } + +#if 0 + dprintf("Deframe Buffer:\n"); + dump_iobuf(&req_iobuf); +#endif + + hr = touch_req_dispatch(&req); + + if (FAILED(hr)) { + dprintf("Wacca touch: Processing error: %x\n", (int) hr); + } + } +} + +static HRESULT touch_req_dispatch(const union slider_req_any *req) +{ + switch (req->hdr.cmd) { + default: + dprintf("Unhandled command %02x\n", req->hdr.cmd); + + return S_OK; + } +} + +static void slider_res_auto_scan(const uint8_t *state) +{ + struct slider_resp_auto_scan resp; + + resp.hdr.sync = SLIDER_FRAME_SYNC; + resp.hdr.cmd = SLIDER_CMD_AUTO_SCAN; + resp.hdr.nbytes = sizeof(resp.pressure); + memcpy(resp.pressure, state, sizeof(resp.pressure)); + + EnterCriticalSection(&touch0_lock); + slider_frame_encode(&touch0_uart.readable, &resp, sizeof(resp)); + LeaveCriticalSection(&touch0_lock); +} diff --git a/mercuryhook/touch.h b/mercuryhook/touch.h new file mode 100644 index 00000000..c3601fe6 --- /dev/null +++ b/mercuryhook/touch.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#include + +struct touch_config { + bool enable; +}; + +HRESULT touch_hook_init(const struct touch_config *cfg); diff --git a/mercuryio/config.c b/mercuryio/config.c index 3b627899..d2d173bc 100644 --- a/mercuryio/config.c +++ b/mercuryio/config.c @@ -14,9 +14,6 @@ void mercury_io_config_load( struct mercury_io_config *cfg, const wchar_t *filename) { - wchar_t key[16]; - int i; - assert(cfg != NULL); assert(filename != NULL);