taiko: fix USIO hooks
This commit is contained in:
parent
e20eca9137
commit
e463d211ea
319
board/usio.c
319
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);
|
||||
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != usio_fd) {
|
||||
return iohook_invoke_next(irp);
|
||||
dprintf("USIO: Open\n");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_open(struct irp *irp)
|
||||
static int my_bnusio_GetFirmwareVersion()
|
||||
{
|
||||
if (wcscmp(irp->open_filename, usio_path) != 0) {
|
||||
return iohook_invoke_next(irp);
|
||||
dprintf("USIO: GetFirmwareVersion\n");
|
||||
return 126;
|
||||
}
|
||||
|
||||
dprintf("USIO: Device opened\n");
|
||||
irp->fd = usio_fd;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_close(struct irp *irp)
|
||||
static int my_bnusio_Close()
|
||||
{
|
||||
dprintf("USIO: Device closed\n");
|
||||
|
||||
return S_OK;
|
||||
dprintf("USIO: Close\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_read(struct irp *irp)
|
||||
static int my_bnusio_SetSystemError(uint16_t err)
|
||||
{
|
||||
dprintf("USIO: Read\n");
|
||||
dump_iobuf(&irp->read);
|
||||
|
||||
return S_OK;
|
||||
dprintf("USIO: SetSystemError %d\n", err);
|
||||
state.err = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_write(struct irp *irp)
|
||||
static int my_bnusio_ClearSram()
|
||||
{
|
||||
dprintf("USIO: Write\n");
|
||||
dump_const_iobuf(&irp->write);
|
||||
|
||||
return S_OK;
|
||||
dprintf("USIO: ClearSram\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT usio_handle_ioctl(struct irp *irp)
|
||||
static BOOL my_bnusio_ResetIoBoard()
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
return 0xFFFFFFEA;
|
||||
}
|
||||
|
||||
static int my_bnusio_SetCoinLock(uint8_t id, char value)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int my_bnusio_GetSwIn()
|
||||
{
|
||||
//dprintf("USIO: GetSwitchIn\n");
|
||||
uint32_t opbtn_out = 0;
|
||||
usio_ops->poll(usio_ops_ctx, &state);
|
||||
|
||||
opbtn_out = (state.p2_btns << 16) | (state.p1_btns << 8) | state.op_btns;
|
||||
|
||||
return opbtn_out;
|
||||
}
|
33
board/usio.h
33
board/usio.h
@ -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);
|
||||
|
39
dist/taiko/bananatools.ini
vendored
39
dist/taiko/bananatools.ini
vendored
@ -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
|
||||
@ -37,3 +44,33 @@ am_game_ver=12.00
|
||||
cacfg_game_ver=08.18
|
||||
server_uri=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
|
@ -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;
|
||||
}
|
@ -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);
|
@ -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),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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++;
|
||||
|
@ -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
|
@ -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);
|
Loading…
Reference in New Issue
Block a user