taiko: fix USIO hooks

This commit is contained in:
Hay1tsme 2023-07-29 02:51:58 -04:00
parent e20eca9137
commit e463d211ea
12 changed files with 364 additions and 468 deletions

View File

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

View File

@ -4,29 +4,46 @@
#include <stdint.h>
#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);
void *ctx,
HMODULE target);

View File

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

View File

@ -1,279 +0,0 @@
#include <windows.h>
#include <assert.h>
#include <synchapi.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#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;
}

View File

@ -1,11 +0,0 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
struct bnusio_config {
bool enable;
};
HRESULT bnusio_hook_init(const struct bnusio_config *cfg);
void bnusio_insert_hooks(HMODULE target);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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