From e463d211eab72ebc6570cba8541bbe932c956f8f Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Sat, 29 Jul 2023 02:51:58 -0400 Subject: [PATCH] taiko: fix USIO hooks --- board/usio.c | 327 ++++++++++++++++++++++++------------- board/usio.h | 33 +++- dist/taiko/bananatools.ini | 41 ++++- taikohook/bnusio.c | 279 ------------------------------- taikohook/bnusio.h | 11 -- taikohook/taiko-dll.c | 7 +- taikohook/taiko-dll.h | 2 +- taikohook/taikohook.def | 3 +- taikohook/usio.c | 50 +++++- taikoio/taikoio.c | 66 ++++---- taikoio/taikoio.def | 3 +- taikoio/taikoio.h | 10 +- 12 files changed, 364 insertions(+), 468 deletions(-) delete mode 100644 taikohook/bnusio.c delete mode 100644 taikohook/bnusio.h diff --git a/board/usio.c b/board/usio.c index f37f70b..d590e4f 100644 --- a/board/usio.c +++ b/board/usio.c @@ -15,45 +15,116 @@ #include "hook/iobuf.h" #include "hook/iohook.h" +#include "hook/table.h" +#include "hook/iohook.h" #include "hooklib/setupapi.h" #include "util/dprintf.h" #include "util/dump.h" -#pragma pack(push, 1) -enum { - USIO_CMD_SET_COMM_TIMEOUT = 0x01, - USIO_CMD_SET_SAMPLING_COUNT = 0x02, - USIO_CMD_CLEAR_BOARD_STATUS = 0x03, - USIO_CMD_SET_GENERAL_OUTPUT = 0x04, - USIO_CMD_SET_PWM_OUTPUT = 0x05, - USIO_CMD_UNIMPLEMENTED = 0x41, - USIO_CMD_UPDATE_FIRMWARE = 0x85, -}; -#pragma pack(pop) - -static HRESULT usio_handle_irp(struct irp *irp); -static HRESULT usio_handle_open(struct irp *irp); -static HRESULT usio_handle_close(struct irp *irp); -static HRESULT usio_handle_read(struct irp *irp); -static HRESULT usio_handle_write(struct irp *irp); -static HRESULT usio_handle_ioctl(struct irp *irp); - -static HRESULT usio_ioctl_get_manufacturer_string(struct irp *irp); -static HRESULT usio_ioctl_get_product_string(struct irp *irp); - static const wchar_t usio_path[] = L"$usio"; //static const wchar_t usio_path[] = L"USBIO_Device0"; +static int my_bnusio_Open(); +static int my_bnusio_Close(); +static int my_bnusio_GetFirmwareVersion(); +static int my_bnusio_SetSystemError(uint16_t err); +static int my_bnusio_ClearSram(); +static BOOL my_bnusio_ResetIoBoard(); +static int my_bnusio_Communication(uint64_t com); +static int my_bnusio_GetSystemError(); +static void my_bnusio_SetPLCounter(uint16_t pl_ct); +static int my_bnusio_SetGout(uint8_t id, uint8_t value); +static int my_bnusio_GetAnalogIn(uint8_t id); +static int my_bnusio_GetSwIn(); +static int my_bnusio_SetCoinLock(uint8_t id, char value); +static int my_bnusio_GetCoin(uint8_t id); +static int my_bnusio_GetCoinError(uint8_t id); +static int my_bnusio_GetService(uint8_t id); +static int my_bnusio_GetServiceError(uint8_t id); + +static const struct hook_symbol winusb_syms[] = { + { + .name = "bnusio_Open", + .patch = my_bnusio_Open + }, + { + .name = "bnusio_GetFirmwareVersion", + .patch = my_bnusio_GetFirmwareVersion + }, + { + .name = "bnusio_Close", + .patch = my_bnusio_Close + }, + { + .name = "bnusio_SetSystemError", + .patch = my_bnusio_SetSystemError + }, + { + .name = "bnusio_ClearSram", + .patch = my_bnusio_ClearSram + }, + { + .name = "bnusio_ResetIoBoard", + .patch = my_bnusio_ResetIoBoard + }, + { + .name = "bnusio_Communication", + .patch = my_bnusio_Communication + }, + { + .name = "bnusio_GetSystemError", + .patch = my_bnusio_GetSystemError + }, + { + .name = "bnusio_SetPLCounter", + .patch = my_bnusio_SetPLCounter + }, + { + .name = "bnusio_SetGout", + .patch = my_bnusio_SetGout + }, + { + .name = "bnusio_GetAnalogIn", + .patch = my_bnusio_GetAnalogIn + }, + { + .name = "bnusio_GetSwIn", + .patch = my_bnusio_GetSwIn + }, + { + .name = "bnusio_SetCoinLock", + .patch = my_bnusio_SetCoinLock + }, + { + .name = "bnusio_GetCoin", + .patch = my_bnusio_GetCoin + }, + { + .name = "bnusio_GetCoinError", + .patch = my_bnusio_GetCoinError + }, + { + .name = "bnusio_GetService", + .patch = my_bnusio_GetService + }, + { + .name = "bnusio_GetServiceError", + .patch = my_bnusio_GetServiceError + } +}; + static HANDLE usio_fd; static const struct usio_ops *usio_ops; static void *usio_ops_ctx; +static struct usio_state state; HRESULT usio_hook_init( const struct usio_config *cfg, const struct usio_ops *ops, - void *ctx) + void *ctx, + HMODULE target) { HRESULT hr; @@ -64,113 +135,149 @@ HRESULT usio_hook_init( return S_FALSE; } - hr = iohook_open_nul_fd(&usio_fd); - - if (FAILED(hr)) { - return hr; - } - usio_ops = ops; usio_ops_ctx = ctx; - iohook_push_handler(usio_handle_irp); - hr = setupapi_add_phantom_dev(&usio_guid, usio_path); - - if (FAILED(hr)) { - return hr; - } + hook_table_apply(target, "bnusio.dll", winusb_syms, _countof(winusb_syms)); + memset(&state, 0, sizeof(state)); dprintf("USIO: Init\n"); return S_OK; } -static HRESULT usio_handle_irp(struct irp *irp) +static int my_bnusio_Open() { - assert(irp != NULL); + dprintf("USIO: Open\n"); + return 0; +} - if (irp->op != IRP_OP_OPEN && irp->fd != usio_fd) { - return iohook_invoke_next(irp); +static int my_bnusio_GetFirmwareVersion() +{ + dprintf("USIO: GetFirmwareVersion\n"); + return 126; +} + +static int my_bnusio_Close() +{ + dprintf("USIO: Close\n"); + return 0; +} + +static int my_bnusio_SetSystemError(uint16_t err) +{ + dprintf("USIO: SetSystemError %d\n", err); + state.err = err; + return 0; +} + +static int my_bnusio_ClearSram() +{ + dprintf("USIO: ClearSram\n"); + return 0; +} + +static BOOL my_bnusio_ResetIoBoard() +{ + dprintf("USIO: ResetIoBoard\n"); + return false; +} + +static int my_bnusio_Communication(uint64_t com) +{ + //dprintf("USIO: Communication\n"); + return 0; +} + +static int my_bnusio_GetSystemError() +{ + dprintf("USIO: GetSystemError\n"); + return state.err; +} + +static void my_bnusio_SetPLCounter(uint16_t pl_ct) +{ + //dprintf("USIO: SetPLCounter\n"); + state.pl_count = pl_ct; +} + +static int my_bnusio_SetGout(uint8_t id, uint8_t value) +{ + //dprintf("USIO: SetGout ID %d Val %d\n", id, value); + if (id <= 32) { + state.gpio[id - 1] = value; + return 0; } - switch (irp->op) { - case IRP_OP_OPEN: return usio_handle_open(irp); - case IRP_OP_CLOSE: return usio_handle_close(irp); - case IRP_OP_READ: return usio_handle_read(irp); - case IRP_OP_WRITE: return usio_handle_write(irp); - case IRP_OP_IOCTL: return usio_handle_ioctl(irp); - default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); - } + return 0xFFFFFFEA; } -static HRESULT usio_handle_open(struct irp *irp) +static int my_bnusio_SetCoinLock(uint8_t id, char value) { - if (wcscmp(irp->open_filename, usio_path) != 0) { - return iohook_invoke_next(irp); + dprintf("USIO: SetCoinLock %d %x\n", id, value); + state.coins[id].is_lock = value; + return 0; +} + +static int my_bnusio_GetCoin(uint8_t id) +{ + //dprintf("USIO: GetCoin ID %d\n", id); + usio_ops->poll(usio_ops_ctx, &state); + if (id < 2) { + return state.coins[id].current_coin_count; + } + return 0; +} + +static int my_bnusio_GetCoinError(uint8_t id) +{ + //dprintf("USIO: GetCoinErrorID %d\n", id); + if (id >= _countof(state.coins)) { + return 0; + } + return state.coins[id].err; +} + +static int my_bnusio_GetService(uint8_t id) +{ + //dprintf("USIO: GetService ID %d\n", id); + usio_ops->poll(usio_ops_ctx, &state); + if (id < 1) { + return state.service.current_coin_count; + } + return 0; +} + +static int my_bnusio_GetServiceError(uint8_t id) +{ + // TODO: multiple service switches? + //dprintf("USIO: GetServiceError ID %d\n", id); + if (id < 1) { + return state.service.err; + } + return 0; +} + +static int my_bnusio_GetAnalogIn(uint8_t id) +{ + //dprintf("USIO: GetAnalogIn ID %d\n", id); + uint8_t gamebtns = 0; + usio_ops->poll(usio_ops_ctx, &state); + + if (id < 8) { + return state.analog[id]; } - dprintf("USIO: Device opened\n"); - irp->fd = usio_fd; - - return S_OK; + return 0; } -static HRESULT usio_handle_close(struct irp *irp) +static int my_bnusio_GetSwIn() { - dprintf("USIO: Device closed\n"); + //dprintf("USIO: GetSwitchIn\n"); + uint32_t opbtn_out = 0; + usio_ops->poll(usio_ops_ctx, &state); - return S_OK; -} - -static HRESULT usio_handle_read(struct irp *irp) -{ - dprintf("USIO: Read\n"); - dump_iobuf(&irp->read); - - return S_OK; -} - -static HRESULT usio_handle_write(struct irp *irp) -{ - dprintf("USIO: Write\n"); - dump_const_iobuf(&irp->write); - - return S_OK; -} - -static HRESULT usio_handle_ioctl(struct irp *irp) -{ - switch (irp->ioctl) { - case IOCTL_HID_GET_MANUFACTURER_STRING: - dprintf("USIO: Get Manufacturer String\n"); - //return usio_ioctl_get_manufacturer_string(irp); - - case IOCTL_HID_GET_PRODUCT_STRING: - dprintf("USIO: Get Product String\n"); - //return usio_ioctl_get_product_string(irp); - - case IOCTL_HID_GET_INPUT_REPORT: - dprintf("USIO: Control IN (untested!!)\n"); - - //return usio_handle_read(irp); - - case IOCTL_HID_SET_OUTPUT_REPORT: - dprintf("USIO: Control OUT (untested!!)\n"); - - //return usio_handle_write(irp); - - default: - dprintf("USIO: Unknown ioctl %#08x, write %i read %i\n", - irp->ioctl, - (int) irp->write.nbytes, - (int) irp->read.nbytes); -#if 1 - dprintf("USIO: Written\n"); - dump_const_iobuf(&irp->write); - dprintf("USIO: Read\n"); - dump_iobuf(&irp->read); -#endif - - return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); - } + opbtn_out = (state.p2_btns << 16) | (state.p1_btns << 8) | state.op_btns; + + return opbtn_out; } \ No newline at end of file diff --git a/board/usio.h b/board/usio.h index a5466d1..e0505a2 100644 --- a/board/usio.h +++ b/board/usio.h @@ -4,29 +4,46 @@ #include +#pragma pack(push,1) enum { /* System buttons in button[0] */ - - USIO_BUTTON_TEST = 1 << 9, - USIO_BUTTON_SERVICE = 1 << 6, + USIO_BUTTON_TEST = 1 << 7, + USIO_BUTTON_P1_ENTER = 1 << 9, + USIO_BUTTON_P1_DOWN = 1 << 12, + USIO_BUTTON_P1_UP = 1 << 13, + USIO_BUTTON_SERVICE = 1 << 14, }; struct usio_config { bool enable; }; +struct usio_coin_state { + uint16_t err; + uint16_t current_coin_count; + bool is_lock; +}; + struct usio_state { - uint16_t adcs[8]; - uint16_t spinners[4]; - uint16_t chutes[2]; - uint16_t buttons[2]; + uint16_t err; + uint16_t pl_count; + uint16_t analog[8]; + uint16_t encoders[4]; + uint8_t op_btns; + uint16_t p1_btns; + uint16_t p2_btns; + struct usio_coin_state coins[2]; + struct usio_coin_state service; + uint8_t gpio[32]; }; struct usio_ops { HRESULT (*poll)(void *ctx, struct usio_state *state); }; +#pragma pack(pop) HRESULT usio_hook_init( const struct usio_config *cfg, const struct usio_ops *ops, - void *ctx); \ No newline at end of file + void *ctx, + HMODULE target); diff --git a/dist/taiko/bananatools.ini b/dist/taiko/bananatools.ini index fdc6d40..1f5e642 100644 --- a/dist/taiko/bananatools.ini +++ b/dist/taiko/bananatools.ini @@ -1,13 +1,19 @@ ; Controls the virtual file system hooks. Redirects all drive to ; [path you set here]\\[drive letter] +; !! REQUIRED !! [vfs] path= +; Hooks for DNS (allnet, etc) +; Set 'default' to the IP/hostname of the server +; you're trying to connect to [dns] default=localhost ; Security dongle emulation, disable if you have a -; real dongle connected that you want to use +; real dongle connected that you want to use. Some games +; validate the S/N, some don't seem to care as long as it's +; formatted like below [dongle] enable=1 serial=12345678-90123456 @@ -24,6 +30,7 @@ windowed=1 framed=0 monitor=0 +; Banapass reader [reader] enable=1 access_code=00000000000000000000 @@ -36,4 +43,34 @@ game_cd=S121 am_game_ver=12.00 cacfg_game_ver=08.18 server_uri=localhost -server_host=localhost \ No newline at end of file +server_host=localhost + +; Controls for USIO buttons +; Test: Home +; Service: Delete +; Coin: Insert +; Up: Up arrow +; Down: Down arrow +; Enter: Enter +[usio] +enable=1 +test=0x24 +service=0x2E +coin=0x2D +up=0x26 +down=0x28 +enter=0x0D + +; Controls for the drum +; Player | Left Rim | Left Center | Right Center | Right Rim +; 1 | Z | X | C | V +; 2 | U | I | O | P +[drum] +p1_rim_l=0x5A +p1_center_l=0x58 +p1_center_r=0x43 +p1_rim_r=0x56 +p2_rim_l=0x55 +p2_center_l=0x49 +p2_center_r=0x +p2_rim_r=0x \ No newline at end of file diff --git a/taikohook/bnusio.c b/taikohook/bnusio.c deleted file mode 100644 index cc08498..0000000 --- a/taikohook/bnusio.c +++ /dev/null @@ -1,279 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -#include "taikohook/bnusio.h" -#include "taikohook/taiko-dll.h" - -#include "hook/table.h" - -#include "util/dprintf.h" - -/* Handles the USB IO board Ninjro and on use. - * Communicates with the game through AMFW, so - * we have to hook AMFW once it gets loaded by - * the game. Inputs are fairly streight forward, - * test switch, operator menu navigation buttons, - * and 8 analog inputs for the taiko drums. Analog - * ids are, from 0 to 7: - * Left Player Rim Left, - * Left Player Center Left, - * Left Player Center Right, - * Left Player Rim Right, - * Right Player Rim Left, - * Right Player Center Left, - * Right Player Center Right, - * Right Player Rim Right, -*/ - -uint16_t sys_err = 0; -uint16_t pl_count = 0; -bool mod_enabled = false; -bool testsw_state = false; -static int my_bnusio_Open(); -static int my_bnusio_Close(); -static int my_bnusio_GetFirmwareVersion(); -static int my_bnusio_SetSystemError(uint16_t err); -static int my_bnusio_ClearSram(); -static BOOL my_bnusio_ResetIoBoard(); -static int my_bnusio_Communication(uint64_t com); -static int my_bnusio_GetSystemError(); -static void my_bnusio_SetPLCounter(uint16_t pl_ct); -static int my_bnusio_SetGout(uint8_t id, uint8_t value); -static int my_bnusio_GetAnalogIn(uint8_t id); -static int my_bnusio_GetSwIn(); -static int my_bnusio_SetCoinLock(uint8_t id, char value); -static int my_bnusio_GetCoin(uint8_t id); -static int my_bnusio_GetCoinError(uint8_t id); -static int my_bnusio_GetService(uint8_t id); -static int my_bnusio_GetServiceError(uint8_t id); - -static const struct hook_symbol bnusio_hooks[] = { - { - .name = "bnusio_Open", - .patch = my_bnusio_Open - }, - { - .name = "bnusio_GetFirmwareVersion", - .patch = my_bnusio_GetFirmwareVersion - }, - { - .name = "bnusio_Close", - .patch = my_bnusio_Close - }, - { - .name = "bnusio_SetSystemError", - .patch = my_bnusio_SetSystemError - }, - { - .name = "bnusio_ClearSram", - .patch = my_bnusio_ClearSram - }, - { - .name = "bnusio_ResetIoBoard", - .patch = my_bnusio_ResetIoBoard - }, - { - .name = "bnusio_Communication", - .patch = my_bnusio_Communication - }, - { - .name = "bnusio_GetSystemError", - .patch = my_bnusio_GetSystemError - }, - { - .name = "bnusio_SetPLCounter", - .patch = my_bnusio_SetPLCounter - }, - { - .name = "bnusio_SetGout", - .patch = my_bnusio_SetGout - }, - { - .name = "bnusio_GetAnalogIn", - .patch = my_bnusio_GetAnalogIn - }, - { - .name = "bnusio_GetSwIn", - .patch = my_bnusio_GetSwIn - }, - { - .name = "bnusio_SetCoinLock", - .patch = my_bnusio_SetCoinLock - }, - { - .name = "bnusio_GetCoin", - .patch = my_bnusio_GetCoin - }, - { - .name = "bnusio_GetCoinError", - .patch = my_bnusio_GetCoinError - }, - { - .name = "bnusio_GetService", - .patch = my_bnusio_GetService - }, - { - .name = "bnusio_GetServiceError", - .patch = my_bnusio_GetServiceError - } -}; - -HRESULT bnusio_hook_init(const struct bnusio_config *cfg) -{ - mod_enabled = cfg->enable; - if (mod_enabled) { - dprintf("bnusio: Init\n"); - } - - return S_OK; -} - -void bnusio_insert_hooks(HMODULE target) -{ - if (mod_enabled) { - dprintf("bnusio: Apply hooks\n"); - hook_table_apply( - target, - "bnusio.dll", - bnusio_hooks, - _countof(bnusio_hooks)); - } -} - -static int my_bnusio_Open() -{ - dprintf("bnusio: Open\n"); - return 0; -} - -static int my_bnusio_GetFirmwareVersion() -{ - dprintf("bnusio: GetFirmwareVersion\n"); - return 126; -} - -static int my_bnusio_Close() -{ - dprintf("bnusio: Close\n"); - return 0; -} - -static int my_bnusio_SetSystemError(uint16_t err) -{ - dprintf("bnusio: SetSystemError %d\n", err); - sys_err = err; - return 0; -} - -static int my_bnusio_ClearSram() -{ - dprintf("bnusio: ClearSram\n"); - return 0; -} - -static BOOL my_bnusio_ResetIoBoard() -{ - dprintf("bnusio: ResetIoBoard\n"); - return false; -} - -static int my_bnusio_Communication(uint64_t com) -{ - return 0; -} - -static int my_bnusio_GetSystemError() -{ - dprintf("bnusio: SetSystemError %d\n", sys_err); - return sys_err; -} - -static void my_bnusio_SetPLCounter(uint16_t pl_ct) -{ - //dprintf("bnusio: SetPLCounter %d\n", pl_ct); - pl_count = pl_ct; -} - -static int my_bnusio_SetGout(uint8_t id, uint8_t value) -{ - return 0; -} - -static int my_bnusio_GetAnalogIn(uint8_t id) -{ - uint8_t gamebtns = 0; - - taiko_dll.poll(); - taiko_dll.get_gamebtns(&gamebtns); - - if (gamebtns & 1 << id) { - return 0xffff; - } - - return 0; -} - -static int my_bnusio_GetSwIn() -{ - uint8_t opbtn; - uint32_t opbtn_out = 0; - taiko_dll.poll(); - taiko_dll.get_opbtns(&opbtn); - - if (opbtn & 0x01) { - // TODO: Toggle so you don't have to hold down the button - opbtn_out |= 1 << 7; // Test - } - if (opbtn & 0x02) { - opbtn_out |= 1 << 14; // Service - } - if (opbtn & 0x04) { - opbtn_out |= 1 << 13; // Up - } - if (opbtn & 0x08) { - opbtn_out |= 1 << 12; // Down - } - if (opbtn & 0x10) { - opbtn_out |= 1 << 9; // Enter - } - return opbtn_out; -} - -static int my_bnusio_SetCoinLock(uint8_t id, char value) -{ - dprintf("bnusio: SetCoinLock %d %x\n", id, value); - return 0; -} - -static int my_bnusio_GetCoin(uint8_t id) -{ - uint16_t coins; - uint16_t services; - taiko_dll.read_coin_counter(&coins, &services); - return coins; -} - -static int my_bnusio_GetCoinError(uint8_t id) -{ - //dprintf("bnusio: GetCoinError %d\n", id); - return 0; -} - -static int my_bnusio_GetService(uint8_t id) -{ - uint16_t coins; - uint16_t services; - taiko_dll.read_coin_counter(&coins, &services); - return services; -} - -static int my_bnusio_GetServiceError(uint8_t id) -{ - //dprintf("bnusio: GetServiceError %d\n", id); - return 0; -} diff --git a/taikohook/bnusio.h b/taikohook/bnusio.h deleted file mode 100644 index ab723bf..0000000 --- a/taikohook/bnusio.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include -#include - -struct bnusio_config { - bool enable; -}; - -HRESULT bnusio_hook_init(const struct bnusio_config *cfg); -void bnusio_insert_hooks(HMODULE target); \ No newline at end of file diff --git a/taikohook/taiko-dll.c b/taikohook/taiko-dll.c index 6b5e45f..b7ea26c 100644 --- a/taikohook/taiko-dll.c +++ b/taikohook/taiko-dll.c @@ -12,9 +12,6 @@ const struct dll_bind_sym taiko_dll_syms[] = { { .sym = "taiko_io_init", .off = offsetof(struct taiko_dll, init), - }, { - .sym = "taiko_io_poll", - .off = offsetof(struct taiko_dll, poll), }, { .sym = "taiko_io_read_coin_counter", .off = offsetof(struct taiko_dll, read_coin_counter), @@ -22,8 +19,8 @@ const struct dll_bind_sym taiko_dll_syms[] = { .sym = "taiko_io_get_opbtns", .off = offsetof(struct taiko_dll, get_opbtns), }, { - .sym = "taiko_io_get_gamebtns", - .off = offsetof(struct taiko_dll, get_gamebtns), + .sym = "taiko_io_get_drum_analog", + .off = offsetof(struct taiko_dll, get_drum_analog), } }; diff --git a/taikohook/taiko-dll.h b/taikohook/taiko-dll.h index 24619ed..7e3e452 100644 --- a/taikohook/taiko-dll.h +++ b/taikohook/taiko-dll.h @@ -10,7 +10,7 @@ struct taiko_dll { HRESULT (*poll)(void); void (*read_coin_counter)(uint16_t *coins, uint16_t *services); void (*get_opbtns)(uint8_t *opbtn); - void (*get_gamebtns)(uint8_t *gamebtn); + void (*get_drum_analog)(uint8_t *gamebtn); }; struct taiko_dll_config { diff --git a/taikohook/taikohook.def b/taikohook/taikohook.def index 49a698f..e997678 100644 --- a/taikohook/taikohook.def +++ b/taikohook/taikohook.def @@ -3,7 +3,6 @@ LIBRARY taikohook EXPORTS taiko_io_get_api_version taiko_io_init - taiko_io_poll taiko_io_read_coin_counter - taiko_io_get_gamebtns + taiko_io_get_drum_analog taiko_io_get_opbtns \ No newline at end of file diff --git a/taikohook/usio.c b/taikohook/usio.c index 106d77f..b963a38 100644 --- a/taikohook/usio.c +++ b/taikohook/usio.c @@ -23,10 +23,16 @@ static const struct usio_ops taiko_usio_ops = { HRESULT taiko_usio_hook_init(const struct usio_config *cfg) { HRESULT hr; - + HANDLE modAmfw; assert(taiko_dll.init != NULL); - hr = usio_hook_init(cfg, &taiko_usio_ops, NULL); + modAmfw = GetModuleHandle("AMFrameWork.dll"); + if (modAmfw == NULL) { + dprintf("Taiko USIO: AMFrameWork.dll not loaded, cannot hook bnusio.\n"); + return S_OK; + } + + hr = usio_hook_init(cfg, &taiko_usio_ops, NULL, modAmfw); if (FAILED(hr)) { return hr; @@ -39,5 +45,45 @@ HRESULT taiko_usio_hook_init(const struct usio_config *cfg) static HRESULT taiko_usio_poll(void *ctx, struct usio_state *state) { + uint8_t opbtn_out = 0; + uint8_t analog_out = 0; + uint16_t coin_ct = 0; + uint16_t service_ct = 0; + taiko_dll.get_opbtns(&opbtn_out); + taiko_dll.get_drum_analog(&analog_out); + taiko_dll.read_coin_counter(&coin_ct, &service_ct); + + state->op_btns = 0; + state->p1_btns = 0; + state->p2_btns = 0; + + if (opbtn_out & 0x01) { + state->op_btns |= 0x80; // Test + } + if (opbtn_out & 0x02) { + state->p1_btns |= 0x40; // Service + } + if (opbtn_out & 0x04) { + state->p1_btns |= 0x20; // Up + } + if (opbtn_out & 0x08) { + state->p1_btns |= 0x10; // Down + } + if (opbtn_out & 0x10) { + state->p1_btns |= 0x02; // Enter + } + + for (int i = 0; i < _countof(state->analog); i++) { + if (analog_out & 1 << i) { + state->analog[i] = 0x3FFF; + } else { + state->analog[i] = 0x00; + } + + } + + state->coins[0].current_coin_count = coin_ct; + state->service.current_coin_count = service_ct; + return S_OK; } \ No newline at end of file diff --git a/taikoio/taikoio.c b/taikoio/taikoio.c index e399c60..2ea96f6 100644 --- a/taikoio/taikoio.c +++ b/taikoio/taikoio.c @@ -13,8 +13,7 @@ static bool taiko_io_coin = false; static bool taiko_io_service = false; static bool taiko_test_toggle = false; -static uint8_t taiko_opbtn = 0; -static uint16_t taiko_gamebtn = 0; +static bool taiko_test_last_state = false; static uint16_t taiko_coin_ct = 0; static uint16_t taiko_service_ct = 0; static struct taiko_input_config cfg; @@ -31,84 +30,77 @@ HRESULT taiko_io_init(void) return S_OK; } -HRESULT taiko_io_poll(void) +void taiko_io_get_opbtns(uint8_t *opbtn) { - taiko_opbtn = 0; - taiko_gamebtn = 0; - if ((GetAsyncKeyState(cfg.test) & 0x8000)) { - taiko_opbtn |= TAIKO_IO_OPBTN_TEST; + if (!taiko_test_last_state) { + taiko_test_toggle = !taiko_test_toggle; + } + taiko_test_last_state = true; + } else { + taiko_test_last_state = false; } if (GetAsyncKeyState(cfg.service) & 0x8000) { - taiko_opbtn |= TAIKO_IO_OPBTN_SERVICE; + *opbtn |= TAIKO_IO_OPBTN_SERVICE; } if (GetAsyncKeyState(cfg.up) & 0x8000) { - taiko_opbtn |= TAIKO_IO_OPBTN_UP; + *opbtn |= TAIKO_IO_OPBTN_UP; } if (GetAsyncKeyState(cfg.down) & 0x8000) { - taiko_opbtn |= TAIKO_IO_OPBTN_DOWN; + *opbtn |= TAIKO_IO_OPBTN_DOWN; } if (GetAsyncKeyState(cfg.enter) & 0x8000) { - taiko_opbtn |= TAIKO_IO_OPBTN_ENTER; + *opbtn |= TAIKO_IO_OPBTN_ENTER; } + if (taiko_test_toggle) { + *opbtn |= TAIKO_IO_OPBTN_TEST; + } +} + +void taiko_io_get_drum_analog(uint8_t *gamebtn) +{ if (GetAsyncKeyState(cfg.p1_rim_l) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P1_RIM_L; + *gamebtn |= TAIKO_IO_P1_RIM_L; } if (GetAsyncKeyState(cfg.p1_center_l) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P1_CENTER_L; + *gamebtn |= TAIKO_IO_P1_CENTER_L; } if (GetAsyncKeyState(cfg.p1_center_r) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P1_CENTER_R; + *gamebtn |= TAIKO_IO_P1_CENTER_R; } if (GetAsyncKeyState(cfg.p1_rim_r) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P1_RIM_R; + *gamebtn |= TAIKO_IO_P1_RIM_R; } if (GetAsyncKeyState(cfg.p2_rim_l) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P2_RIM_L; + *gamebtn |= TAIKO_IO_P2_RIM_L; } if (GetAsyncKeyState(cfg.p2_center_l) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P2_CENTER_L; + *gamebtn |= TAIKO_IO_P2_CENTER_L; } if (GetAsyncKeyState(cfg.p2_center_r) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P2_CENTER_R; + *gamebtn |= TAIKO_IO_P2_CENTER_R; } if (GetAsyncKeyState(cfg.p2_rim_r) & 0x8000) { - taiko_gamebtn |= TAIKO_IO_P2_RIM_R; - } - - return S_OK; -} - -void taiko_io_get_opbtns(uint8_t *opbtn) -{ - if (opbtn != NULL) { - *opbtn = taiko_opbtn; - } -} - -void taiko_io_get_gamebtns(uint8_t *gamebtn) -{ - if (gamebtn != NULL) { - *gamebtn = taiko_gamebtn; + *gamebtn |= TAIKO_IO_P2_RIM_R; } } void taiko_io_read_coin_counter(uint16_t *coins, uint16_t *services) { - if (GetAsyncKeyState(VK_INSERT) & 0x8000) { + if (GetAsyncKeyState(cfg.coin) & 0x8000) { if (!taiko_io_coin) { taiko_io_coin = true; taiko_coin_ct++; @@ -117,7 +109,7 @@ void taiko_io_read_coin_counter(uint16_t *coins, uint16_t *services) taiko_io_coin = false; } - if (GetAsyncKeyState(VK_DELETE) & 0x8000) { + if (GetAsyncKeyState(cfg.service) & 0x8000) { if (!taiko_io_service) { taiko_io_service = true; taiko_service_ct++; diff --git a/taikoio/taikoio.def b/taikoio/taikoio.def index 49a698f..e997678 100644 --- a/taikoio/taikoio.def +++ b/taikoio/taikoio.def @@ -3,7 +3,6 @@ LIBRARY taikohook EXPORTS taiko_io_get_api_version taiko_io_init - taiko_io_poll taiko_io_read_coin_counter - taiko_io_get_gamebtns + taiko_io_get_drum_analog taiko_io_get_opbtns \ No newline at end of file diff --git a/taikoio/taikoio.h b/taikoio/taikoio.h index 9dc514e..bdde896 100644 --- a/taikoio/taikoio.h +++ b/taikoio/taikoio.h @@ -14,7 +14,6 @@ enum { TAIKO_IO_OPBTN_ENTER = 0x10, }; -// Chagned to match xinput masks for ease of use enum { TAIKO_IO_P1_RIM_L = 0x0001, TAIKO_IO_P1_CENTER_L = 0x0002, @@ -44,13 +43,6 @@ uint16_t taiko_io_get_api_version(void); HRESULT taiko_io_init(void); -/* Send any queued outputs (of which there are currently none, though this may - change in subsequent API versions) and retrieve any new inputs. - - Minimum API version: 0x0100 */ - -HRESULT taiko_io_poll(void); - /* Get the state of the cabinet's operator buttons as of the last poll. See TAIKO_IO_OPBTN enum above: this contains bit mask definitions for button @@ -70,6 +62,6 @@ void taiko_io_get_opbtns(uint8_t *opbtn); Minimum API version: 0x0100 */ -void taiko_io_get_gamebtns(uint8_t *gamebtn); +void taiko_io_get_drum_analog(uint8_t *gamebtn); void taiko_io_read_coin_counter(uint16_t *coins, uint16_t *services); \ No newline at end of file