Files
TeamTofuShop_taitools/board/k9101258.c
T
2025-06-07 15:09:37 -04:00

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
}