diff --git a/mercuryhook/mercury-dll.h b/mercuryhook/mercury-dll.h index b28b8ca..086fd92 100644 --- a/mercuryhook/mercury-dll.h +++ b/mercuryhook/mercury-dll.h @@ -11,7 +11,7 @@ struct mercury_dll { void (*get_opbtns)(uint8_t *opbtn); void (*get_gamebtns)(uint8_t *gamebtn); HRESULT (*touch_init)(void); - HRESULT (*touch_start)(void); + void (*touch_start)(mercury_io_touch_callback_t callback); }; struct mercury_dll_config { diff --git a/mercuryhook/touch.c b/mercuryhook/touch.c index 6c0c942..a32f6a2 100644 --- a/mercuryhook/touch.c +++ b/mercuryhook/touch.c @@ -37,8 +37,12 @@ static HRESULT touch_handle_get_unit_board_ver(const struct touch_req *req); static HRESULT touch_handle_mystery1(const struct touch_req *req); 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 uint8_t *state); -uint8_t input_frame_count = 0x7b; +uint8_t input_frame_count_0 = 0x7b; +uint8_t input_frame_count_1 = 0x7b; +bool touch0_auto = false; +bool touch1_auto = false; static CRITICAL_SECTION touch0_lock; static struct uart touch0_uart; @@ -235,6 +239,8 @@ static HRESULT touch_handle_get_sync_board_ver(const struct touch_req *req) // TODO: Why does strcpy_s here give a runtime warning and not work???? //strcpy_s(resp.version, sizeof(resp.version), "190523"); memcpy(resp.version, sync_board_ver, sizeof(sync_board_ver)); + resp.checksum = 0; + resp.checksum = calc_checksum(&resp, sizeof(resp)); if (req->side == 0) { @@ -290,6 +296,8 @@ static HRESULT touch_handle_startup(const struct touch_req *req) } memcpy(resp.data, rev, 80 * sizeof(uint8_t)); + resp.checksum = 0; + resp.checksum = calc_checksum(&resp, sizeof(resp)); if (req->side == 0) { hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp)); @@ -313,6 +321,8 @@ static HRESULT touch_handle_get_unit_board_ver(const struct touch_req *req) resp.cmd = 0xa8; memcpy(resp.version, unit_board_ver, sizeof(unit_board_ver)); + resp.checksum = 0; + resp.checksum = calc_checksum(&resp, sizeof(resp)); if (req->side == 0) { hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp)); @@ -333,6 +343,8 @@ static HRESULT touch_handle_mystery1(const struct touch_req *req) resp.cmd = 0xa2; resp.data = 0x3f; + resp.checksum = 0; + resp.checksum = calc_checksum(&resp, sizeof(resp)); if (req->side == 0) { hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp)); @@ -352,6 +364,8 @@ static HRESULT touch_handle_mystery2(const struct touch_req *req) resp.cmd = 0x94; resp.data = 0; + resp.checksum = 0; + resp.checksum = calc_checksum(&resp, sizeof(resp)); if (req->side == 0) { hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp)); @@ -376,20 +390,62 @@ static HRESULT touch_handle_start_auto_scan(const struct touch_req *req) resp.checksum = 0x49; resp.frame.cmd= 0x81; - resp.frame.count = input_frame_count++; memcpy(resp.frame.data1, data1, sizeof(data1)); memcpy(resp.frame.data2, data2, sizeof(data2)); + resp.frame.checksum = 0; resp.frame.checksum = calc_checksum(&resp.frame, sizeof(resp.frame)); if (req->side == 0) { + resp.frame.count = input_frame_count_0++; hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp)); + touch0_auto = true; } else { + resp.frame.count = input_frame_count_1++; hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp)); + touch1_auto = true; } + + //mercury_dll.touch_start(touch_res_auto_scan); return hr; } +static void touch_res_auto_scan(const uint8_t *state) +{ + struct touch_input_frame frame0; + //struct touch_input_frame frame1; + uint8_t data1[24] = { 0 }; + uint8_t data2[9] = { 0x0d, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00 }; + + frame0.cmd = 0x81; + if (input_frame_count_0 == 0x7f) { + frame0.count = 0x7f; + input_frame_count_0 = 0; + } + else { + frame0.count = input_frame_count_0++; + } + // for now return no data + memcpy(frame0.data1, data1, sizeof(data1)); + memcpy(frame0.data2, data2, sizeof(data2)); + frame0.checksum = 0; + frame0.checksum = calc_checksum(&frame0, sizeof(frame0)); + + if (touch0_auto) { + //dprintf("Wacca touch: Touch0 auto frame #%2hx sent\n", frame0.count); + EnterCriticalSection(&touch0_lock); + touch_frame_encode(&touch0_uart.readable, &frame0, sizeof(frame0)); + LeaveCriticalSection(&touch0_lock); + } + + if (touch1_auto) { + //dprintf("Wacca touch: Touch1 auto frame #%2hx sent\n", frame0.count); + EnterCriticalSection(&touch1_lock); + touch_frame_encode(&touch1_uart.readable, &frame0, sizeof(frame0)); + LeaveCriticalSection(&touch1_lock); + } +} + /* Decodes the response into a struct that's easier to work with. */ static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, int side) { @@ -412,16 +468,13 @@ static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, i static HRESULT touch_frame_encode(struct iobuf *dest, const void *ptr, size_t nbytes) { const uint8_t *src; - uint8_t checksum = 0; src = ptr; for (size_t i = 0; i < nbytes; i++) { dest->bytes[dest->pos++] = src[i]; - checksum = checksum^(src[i]); } - dest->bytes[dest->pos++] = checksum&0x7f; return S_OK; } @@ -438,8 +491,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]); checksum = checksum^(src[i]); } - + //dprintf("Wacca touch: Checksum is %2hx\n", checksum&0x7f); return checksum&0x7f; } diff --git a/mercuryhook/touch.h b/mercuryhook/touch.h index 6e79375..d98fc0b 100644 --- a/mercuryhook/touch.h +++ b/mercuryhook/touch.h @@ -26,9 +26,6 @@ struct touch_req { uint8_t data_length; // Size of the data including command byte }; -// The checksum is only calculated when we're about to send it so -// it's not part of any of these structs. Just note that the last -// byte of every response is a checksum struct touch_input_frame { uint8_t cmd; uint8_t data1[24]; @@ -40,25 +37,30 @@ struct touch_input_frame { struct touch_resp_get_sync_board_ver { uint8_t cmd; char version[6]; + uint8_t checksum; }; struct touch_resp_startup { char data[80]; + uint8_t checksum; }; struct touch_resp_get_unit_board_ver { uint8_t cmd; uint8_t version[43]; + uint8_t checksum; }; struct touch_resp_mystery1 { uint8_t cmd; uint8_t data; + uint8_t checksum; }; struct touch_resp_mystery2 { uint8_t cmd; uint8_t data; + uint8_t checksum; }; struct touch_resp_start_auto { diff --git a/mercuryio/mercuryio.c b/mercuryio/mercuryio.c index e51daf4..3d4a735 100644 --- a/mercuryio/mercuryio.c +++ b/mercuryio/mercuryio.c @@ -2,13 +2,18 @@ #include #include +#include #include "mercuryio/mercuryio.h" #include "mercuryio/config.h" +static unsigned int __stdcall mercury_io_touch_thread_proc(void *ctx); + static uint8_t mercury_opbtn; static uint8_t mercury_gamebtn; static struct mercury_io_config mercury_io_cfg; +static bool mercury_io_touch_stop_flag; +static HANDLE mercury_io_touch_thread; uint16_t mercury_io_get_api_version(void) { @@ -65,7 +70,42 @@ HRESULT mercury_io_touch_init(void) return S_OK; } -HRESULT mercury_io_touch_start(void) +void mercury_io_touch_start(mercury_io_touch_callback_t callback) { - return S_OK; + if (mercury_io_touch_thread != NULL) { + return; + } + + mercury_io_touch_thread = (HANDLE) _beginthreadex( + NULL, + 0, + mercury_io_touch_thread_proc, + callback, + 0, + NULL + ); +} + +static unsigned int __stdcall mercury_io_touch_thread_proc(void *ctx) +{ + mercury_io_touch_callback_t callback; + uint8_t pressure[240]; + size_t i; + + callback = ctx; + + while (!mercury_io_touch_stop_flag) { + for (i = 0 ; i < _countof(pressure) ; i++) { + if (GetAsyncKeyState(mercury_io_cfg.vk_cell[i]) & 0x8000) { + pressure[i] = 128; + } else { + pressure[i] = 0; + } + } + + callback(pressure); + Sleep(1); + } + + return 0; } diff --git a/mercuryio/mercuryio.h b/mercuryio/mercuryio.h index 07d14e3..6f32989 100644 --- a/mercuryio/mercuryio.h +++ b/mercuryio/mercuryio.h @@ -14,6 +14,7 @@ enum { MERCURY_IO_GAMEBTN_VOL_DOWN = 0x02, }; +typedef void (*mercury_io_touch_callback_t)(const uint8_t *state); /* Get the version of the Wacca IO API that this DLL supports. This function should return a positive 16-bit integer, where the high byte is the major version and the low byte is the minor version (as defined by the @@ -61,4 +62,4 @@ void mercury_io_get_gamebtns(uint8_t *gamebtn); HRESULT mercury_io_touch_init(void); -HRESULT mercury_io_touch_start(void); +void mercury_io_touch_start(mercury_io_touch_callback_t callback);