mirror of
https://gitea.tendokyu.moe/TeamTofuShop/taitools.git
synced 2026-09-22 22:28:06 +03:00
138 lines
3.6 KiB
C
138 lines
3.6 KiB
C
#include <windows.h>
|
|
|
|
#include <devioctl.h>
|
|
#include <hidclass.h>
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "board/guid.h"
|
|
#include "board/k9101258.h"
|
|
|
|
#include "hook/iobuf.h"
|
|
#include "hook/iohook.h"
|
|
|
|
#include "hooklib/winusb.h"
|
|
|
|
#include "util/dprintf.h"
|
|
|
|
// USB IO, A/B/C variants
|
|
|
|
static const uint8_t base_bfr[64] = {
|
|
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, // 6: gamebtns, 7: door sw, 4: game/opt btns
|
|
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, // 12 - coin count, 13 - coin jam (64)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 31 possibly analog in?
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38/39 system buttons?
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // Reader stuff?
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
static HRESULT winusb_handle_irp(struct irp *irp);
|
|
static void read_pipe(void *ctx, uint8_t *bfr, uint32_t bfr_len, uint32_t *len_tx);
|
|
static void write_pipe(void *ctx, uint8_t *bfr, uint32_t bfr_len, uint32_t *len_tx);
|
|
|
|
static const wchar_t usbio_path[] = L"$usbio";
|
|
|
|
static HANDLE usbio_fd;
|
|
static void *usbio_ops_ctx;
|
|
static struct usbio_ops ops = {
|
|
.digital_in = NULL,
|
|
.digital_out = NULL,
|
|
.analog_in = NULL,
|
|
.analog_out = NULL,
|
|
.reader_poll = NULL,
|
|
.reader_led_out = NULL,
|
|
};
|
|
|
|
HRESULT k9101258_hook_init(const struct usbio_ops *ioops, void *ctx)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = iohook_open_nul_fd(&usbio_fd);
|
|
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
ops.digital_in = ioops->digital_in;
|
|
usbio_ops_ctx = ctx;
|
|
|
|
// only idVendor, idProduct and bcdDevice are actually read it seems
|
|
struct _USB_DEVICE_DESCRIPTOR desc = {
|
|
.bLength = sizeof(USB_DEVICE_DESCRIPTOR),
|
|
.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE,
|
|
.bcdUSB = 0x0200,
|
|
.bDeviceClass = 0x00,
|
|
.bDeviceSubClass = 0x00,
|
|
.bDeviceProtocol = 0x00,
|
|
.bMaxPacketSize0 = 64,
|
|
.idVendor = 0x0AE4,
|
|
.idProduct = 0x0901,
|
|
.bcdDevice = 0x32, // Needs to be hex 32 (the game turns it to decimal and expects 32)
|
|
.iManufacturer = 1,
|
|
.iProduct = 2,
|
|
.iSerialNumber = 0,
|
|
.bNumConfigurations = 1,
|
|
};
|
|
|
|
struct winusb_dev dev = {
|
|
.fd = usbio_fd,
|
|
.path = L"$usbio",
|
|
.descriptor = desc,
|
|
.read_pipe = read_pipe,
|
|
.write_pipe = write_pipe,
|
|
};
|
|
|
|
hr = winusb_add_phantom_dev(&dev);
|
|
|
|
if (FAILED(hr)) {
|
|
return hr;
|
|
}
|
|
|
|
dprintf("K9101258: Init\n");
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static void read_pipe(void *ctx, uint8_t *bfr, uint32_t bfr_len, uint32_t *len_tx)
|
|
{
|
|
memcpy_s(bfr, bfr_len, base_bfr, sizeof(base_bfr));
|
|
*len_tx = sizeof(base_bfr);
|
|
|
|
uint32_t coinct = 0;
|
|
uint8_t buttons[4] = {0};
|
|
uint16_t analog[8] = {0};
|
|
uint8_t card_id[16] = {0};
|
|
|
|
if (ops.digital_in != NULL) {
|
|
ops.digital_in(usbio_ops_ctx, buttons, &coinct);
|
|
memcpy_s(bfr + 4, bfr_len - 4, buttons, sizeof(buttons));
|
|
bfr[12] = coinct % 255;
|
|
}
|
|
|
|
if (ops.analog_in != NULL) {
|
|
ops.analog_in(usbio_ops_ctx, analog);
|
|
}
|
|
|
|
if (ops.reader_poll != NULL) {
|
|
ops.reader_poll(usbio_ops_ctx, card_id);
|
|
memcpy_s(bfr + 48, bfr_len - 48, card_id, sizeof(card_id));
|
|
}
|
|
}
|
|
|
|
static void write_pipe(void *ctx, uint8_t *bfr, uint32_t bfr_len, uint32_t *len_tx)
|
|
{
|
|
*len_tx = 64;
|
|
#if 0
|
|
dprintf("K9101258: Write Pipe -");
|
|
for (int i = 0; i < bfr_len; i++) {
|
|
dprintf(" %02X",bfr[i]);
|
|
}
|
|
dprintf("\n");
|
|
#endif
|
|
}
|