progress dump

This commit is contained in:
Hay1tsme
2025-04-25 03:23:44 -04:00
parent 571534943e
commit 1a47c7d330
43 changed files with 4584 additions and 719 deletions
+9 -1
View File
@@ -29,6 +29,14 @@
"hidclass.h": "c",
"winusb.h": "c",
"setupapi.h": "c",
"table.h": "c"
"table.h": "c",
"k9101258.h": "c",
"iobuf.h": "c",
"spike.h": "c",
"dvd.h": "c",
"hoshi-dll.h": "c",
"usbio.h": "c",
"iohook.h": "c",
"jvs-cmd.h": "c"
}
}
+1 -2
View File
@@ -10,8 +10,7 @@ $(BUILD_DIR_ZIP)/siva.zip:
$(BUILD_DIR_ZIP)/siva
$(V)mv $(BUILD_DIR_ZIP)/siva/iDmacDrv.dll \
$(BUILD_DIR_ZIP)/siva/iDmacDrv64.dll
$(V)cp pki/client.cer \
pki/client.p12 \
$(V)cp pki/client.p12 \
$(BUILD_DIR_ZIP)/siva
$(V)strip $(BUILD_DIR_ZIP)/siva/*.{exe,dll}
$(V)cd $(BUILD_DIR_ZIP)/siva ; zip -r ../siva.zip *
+1 -1
View File
@@ -220,7 +220,7 @@ static HRESULT io3_cmd(
case JVS_CMD_READ_ANALOGS:
return io3_cmd_read_analogs(io3, req, resp);
case JVS_CMD_WRITE_GPIO:
case JVS_CMD_WRITE_GPIO1:
return io3_cmd_write_gpio(io3, req, resp);
case JVS_CMD_RESET:
-487
View File
@@ -1,487 +0,0 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "board/j9100628a.h"
#include "jvs/jvs-bus.h"
#include "jvs/jvs-cmd.h"
#include "jvs/jvs-util.h"
#include "util/dprintf.h"
#include "util/dump.h"
// JVS card reader
static const uint8_t j9100628a_ident[] = "taito;JVS-Reader;Ver1.00;JPN,Multipurpose";
static uint8_t j9100628a_features[] = {
/* Feature : 0x01 : Players and switches
Param1 : 1 : Number of players
Param2 : 18 : Number of switches per player
Param3 : 0 : N/A */
0x01,
0x01,
0x18,
0x00,
/* Feature : 0x02 : Coin slots
Param1 : 2 : Number of coin slots
Param2 : 0 : N/A
Param3 : 0 : N/A */
0x02,
0x00,
0x00,
0x00,
/* Feature : 0x03 : Analog inputs
Param1 : 8 : Number of ADC channels
Param2 : 10 : Effective bits of resolution per ADC
Param3 : 0 : N/A */
0x03,
0x00,
0x00,
0x00,
/* Feature : 0x04 : Rotary Input
Param1 : 4 : Number of Rotary channels
Param2 : 0 : N/A
Param3 : 0 : N/A */
0x04,
0x00,
0x00,
0x00,
/* Feature : 0x12 : GPIO outputs
Param1 : 3 : Number of ports (8 bits per port)
Param2 : 0 : N/A
Param3 : 0 : N/A
*/
0x12,
0x00,
0x00,
0x00,
/* Feature : 0x13 : Analog outputs
Param1 : 2 : Number of channels
Param2 : 0 : N/A
Param3 : 0 : N/A
*/
0x13,
0x00,
0x00,
0x00,
/* Feature : 0x14 : Character Output
Param1 : 0x50 : Width
Param2 : 0x19 : Height
Param3 : 0 : Type
*/
0x14,
0x50,
0x19,
0x00,
/* Feature : 0x00 : End of capabilities */
0x00,
};
static void j9100628a_transact(
struct jvs_node *node,
const void *bytes,
size_t nbytes,
struct iobuf *resp);
static bool j9100628a_sense(struct jvs_node *node);
static HRESULT j9100628a_cmd(
void *ctx,
struct const_iobuf *req,
struct iobuf *resp);
static HRESULT j9100628a_cmd_reset(struct j9100628a *j9100628a, struct const_iobuf *req_buf);
static HRESULT j9100628a_cmd_assign_addr(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_read_id(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_get_cmd_version(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_get_jvs_version(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_get_comm_version(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_get_features(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_read_misc_switches(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_read_dip_switches(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT j9100628a_cmd_write_gpio(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf);
void j9100628a_init(
struct j9100628a *j9100628a,
struct jvs_node *next,
const struct j9100628a_ops *ops,
void *ops_ctx)
{
assert(j9100628a != NULL);
assert(ops != NULL);
j9100628a->jvs.next = next;
j9100628a->jvs.transact = j9100628a_transact;
j9100628a->jvs.sense = j9100628a_sense;
j9100628a->jvs.sense_out = true;
j9100628a->addr = 0xFF;
j9100628a->ops = ops;
j9100628a->ops_ctx = ops_ctx;
}
struct jvs_node *j9100628a_to_jvs_node(struct j9100628a *j9100628a)
{
assert(j9100628a != NULL);
return &j9100628a->jvs;
}
static void j9100628a_transact(
struct jvs_node *node,
const void *bytes,
size_t nbytes,
struct iobuf *resp)
{
struct j9100628a *j9100628a;
assert(node != NULL);
assert(bytes != NULL);
assert(resp != NULL);
j9100628a = CONTAINING_RECORD(node, struct j9100628a, jvs);
jvs_crack_request(bytes, nbytes, resp, j9100628a->addr, j9100628a_cmd, j9100628a);
}
static bool j9100628a_sense(struct jvs_node *node)
{
struct j9100628a *j9100628a;
assert(node != NULL);
j9100628a = CONTAINING_RECORD(node, struct j9100628a, jvs);
return j9100628a->addr == 0xFF;
}
static HRESULT j9100628a_cmd(
void *ctx,
struct const_iobuf *req,
struct iobuf *resp)
{
struct j9100628a *j9100628a;
j9100628a = ctx;
switch (req->bytes[req->pos]) {
case JVS_CMD_RESET:
return j9100628a_cmd_reset(j9100628a, req);
case JVS_CMD_ASSIGN_ADDR:
return j9100628a_cmd_assign_addr(j9100628a, req, resp);
case JVS_CMD_READ_ID:
return j9100628a_cmd_read_id(j9100628a, req, resp);
case JVS_CMD_GET_CMD_VERSION:
return j9100628a_cmd_get_cmd_version(j9100628a, req, resp);
case JVS_CMD_GET_JVS_VERSION:
return j9100628a_cmd_get_jvs_version(j9100628a, req, resp);
case JVS_CMD_GET_COMM_VERSION:
return j9100628a_cmd_get_comm_version(j9100628a, req, resp);
case JVS_CMD_GET_FEATURES:
return j9100628a_cmd_get_features(j9100628a, req, resp);
case JVS_CMD_READ_MISC_SWITCHES:
return j9100628a_cmd_read_misc_switches(j9100628a, req, resp);
case JVS_CMD_TYPEX_READ_DIPSW:
return j9100628a_cmd_read_dip_switches(j9100628a, req, resp);
case JVS_CMD_TYPEX_POLL_AMIC:
// FIXME: seperate func
return j9100628a_cmd_read_dip_switches(j9100628a, req, resp);
case JVS_CMD_WRITE_GPIO:
return j9100628a_cmd_write_gpio(j9100628a, req, resp);
default:
dprintf("J9100628A: Node %02x: Unhandled command byte %02x\n",
j9100628a->addr,
req->bytes[req->pos]);
return E_NOTIMPL;
}
return S_OK;
}
static HRESULT j9100628a_cmd_reset(struct j9100628a *j9100628a, struct const_iobuf *req_buf)
{
struct jvs_req_reset req;
HRESULT hr;
hr = iobuf_read(req_buf, &req, sizeof(req));
if (FAILED(hr)) {
return hr;
}
dprintf("J9100628A: Reset (param %02x)\n", req.unknown);
j9100628a->addr = 0xFF;
j9100628a->jvs.sense_out = false; // ?
if (j9100628a->ops->reset != NULL) {
j9100628a->ops->reset(j9100628a->ops_ctx);
}
/* No ack for this since it really is addressed to everybody */
return S_OK;
}
static HRESULT j9100628a_cmd_assign_addr(
struct j9100628a *j9100628a,
struct const_iobuf *req_buf,
struct iobuf *resp_buf)
{
struct jvs_req_assign_addr req;
bool sense;
HRESULT hr;
hr = iobuf_read(req_buf, &req, sizeof(req));
if (FAILED(hr)) {
return hr;
}
sense = jvs_node_sense(j9100628a->jvs.next);
dprintf("J9100628A: Assign addr %02x sense %i\n", req.addr, sense);
if (sense) {
/* That address is for somebody else */
return S_OK;
}
j9100628a->addr = req.addr;
j9100628a->jvs.sense_out = true;
return iobuf_write_8(resp_buf, 0x01);
}
static HRESULT j9100628a_cmd_read_id(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("J9100628A: Read ID\n");
/* Write report byte */
hr = iobuf_write_8(resp_buf, 0x01);
if (FAILED(hr)) {
return hr;
}
/* Write the identification string. The NUL terminator at the end of this C
string is also sent, and it naturally terminates the response chunk. */
return iobuf_write(resp_buf, j9100628a_ident, sizeof(j9100628a_ident));
}
static HRESULT j9100628a_cmd_get_cmd_version(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("J9100628A: Get command format version\n");
resp[0] = 0x01; /* Report byte */
resp[1] = 0x13; /* Command format version BCD */
return iobuf_write(resp_buf, resp, sizeof(resp));
}
static HRESULT j9100628a_cmd_get_jvs_version(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("J9100628A: Get JVS format version\n");
resp[0] = 0x01; /* Report byte */
resp[1] = 0x30; /* JVS format version BCD */
return iobuf_write(resp_buf, resp, sizeof(resp));
}
static HRESULT j9100628a_cmd_get_comm_version(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("J9100628A: Get COMM format version\n");
resp[0] = 0x01; /* Report byte */
resp[1] = 0x10; /* COMM format version BCD */
return iobuf_write(resp_buf, resp, sizeof(resp));
}
static HRESULT j9100628a_cmd_get_features(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("J9100628A: Get reader features\n");
hr = iobuf_write_8(resp_buf, 0x01); /* Write report byte */
if (FAILED(hr)) {
return hr;
}
return iobuf_write(resp_buf, j9100628a_features, sizeof(j9100628a_features));
}
static HRESULT j9100628a_cmd_read_misc_switches(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
hr = iobuf_write_8(resp_buf, 0x01); /* Write report byte */
if (FAILED(hr)) {
return hr;
}
return iobuf_write_8(resp_buf, 0x00); /* Write switch byte */
}
static HRESULT j9100628a_cmd_read_dip_switches(struct j9100628a *j9100628a, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
hr = iobuf_write_8(resp_buf, 0x01); /* Write report byte */
if (FAILED(hr)) {
return hr;
}
return iobuf_write_8(resp_buf, 0x00); /* Write switch byte */
}
static HRESULT j9100628a_cmd_write_gpio(
struct j9100628a *j9100628a,
struct const_iobuf *req_buf,
struct iobuf *resp_buf)
{
uint8_t cmd;
uint8_t nbytes;
uint8_t bytes[3];
HRESULT hr;
/* Read request header */
hr = iobuf_read_8(req_buf, &cmd);
if (FAILED(hr)) {
return hr;
}
hr = iobuf_read_8(req_buf, &nbytes);
if (FAILED(hr)) {
return hr;
}
if (nbytes > 3) {
dprintf("J9100628A: Invalid GPIO write size %i\n", nbytes);
hr = iobuf_write_8(resp_buf, 0x02);
if (FAILED(hr)) {
return hr;
}
return E_FAIL;
}
/* Read payload */
memset(bytes, 0, sizeof(bytes));
hr = iobuf_read(req_buf, bytes, nbytes);
if (FAILED(hr)) {
return hr;
}
if (j9100628a->ops->write_led != NULL) {
j9100628a->ops->write_led(
j9100628a->ops_ctx,
bytes[0] | (bytes[1] << 8) | (bytes[2] << 16));
}
/* Write report byte */
return iobuf_write_8(resp_buf, 0x01);
}
-22
View File
@@ -1,22 +0,0 @@
#pragma once
#include <windows.h>
#include <stdint.h>
#pragma pack(push,1)
// needs to handle digital and analog reads and writes, coin stuff, and
// having an ad-on device (usually a card reader) and maybe an SD card??
// Mayhaps move this to a seperate thing in the event a second USB IO
// providor is needed?
//struct usbio_dev {
// TODO: populate with handler functions for various commands that
// come in via winusb
// It might also just do a mass bulk update, in which case we need
// a struct that encompases all the digital and analog I/O pins and
// their states.
//};
#pragma pack(pop)
HRESULT usbio_hook_init();
+34 -13
View File
@@ -9,7 +9,7 @@
#include <string.h>
#include "board/guid.h"
#include "board/j9100647a.h"
#include "board/k9101258.h"
#include "hook/iobuf.h"
#include "hook/iohook.h"
@@ -18,7 +18,20 @@
#include "util/dprintf.h"
// USB IO
// USB IO, A/B/C variants
static const uint8_t base_bfr[64] = {
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // 6: gamebtns, 7: door sw, 4: game/opt btns
0xFF, 0xFF, 0xFF, 0x00, 0x35, 0x00, 0x00, 0x00, // 12 - coin count, 13 - coin jam (64)
//0xF0, 0xCA, 0x79, 0xE0, 0x08, 0xE3, 0x70, 0xE2,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 31 possibly analog in?
//0x7C, 0xEB, 0x3C, 0xDB, 0x84, 0xDE, 0xF0, 0xD9,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38/39 system buttons?
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 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);
@@ -29,7 +42,7 @@ static const wchar_t usbio_path[] = L"$usbio";
static HANDLE usbio_fd;
static void *usbio_ops_ctx;
HRESULT usbio_hook_init()
HRESULT k9101258_hook_init()
{
HRESULT hr;
@@ -43,16 +56,16 @@ HRESULT usbio_hook_init()
struct _USB_DEVICE_DESCRIPTOR desc = {
.bLength = sizeof(USB_DEVICE_DESCRIPTOR),
.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE,
.bcdUSB = 301, // USB 3.01 spec (BCD makes no sense)
.bDeviceClass = 0x03, // HID
.bDeviceSubClass = 0x00, // ??
.bDeviceProtocol = 0x00, // ??
.bcdUSB = 0x0200,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 64,
.idVendor = 0x0AE4,
.idProduct = 0x0901,
.bcdDevice = 0x32, // Needs to be 32 after some processing by the game
.iManufacturer = 0,
.iProduct = 0,
.bcdDevice = 0x32, // Needs to be hex 32 (the game turns it to decimal and expects 32)
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 0,
.bNumConfigurations = 1,
};
@@ -71,17 +84,25 @@ HRESULT usbio_hook_init()
return hr;
}
dprintf("USBIO: Init\n");
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 = 64;
}
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
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include <windows.h>
#include <stdint.h>
#include <stdbool.h>
#pragma pack(push,1)
// needs to handle digital and analog reads and writes, coin stuff, and
// having an ad-on device (usually a card reader) and maybe an SD card??
// Mayhaps move this to a seperate thing in the event a second USB IO
// providor is needed?
struct usbio_ops {
void (*digital_in)(void *ctx, uint32_t *out);
void (*digital_out)(void *ctx); // TODO: digital outputs
void (*analog_in)(void *ctx, uint16_t out[8]);
bool (*is_coin_pressed)(void *ctx);
void (*reader_poll)(void *ctx); // TODO: reader struct?
void (*reader_led_out)(void *ctx); // TODO: reader struct?
};
#pragma pack(pop)
HRESULT k9101258_hook_init();
+422
View File
@@ -0,0 +1,422 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "board/k92x0249.h"
#include "jvs/jvs-bus.h"
#include "jvs/jvs-cmd.h"
#include "jvs/jvs-util.h"
#include "util/dprintf.h"
#include "util/dump.h"
// JVS card reader, A/B/C vairants
static const uint8_t k92x0249_ident[] = "TAITO CORP.;JVS Reader;Ver1.00;0000.00.00";
//static const uint8_t k92x0249_ident[] = "TAITO CORP.;JVS Reader;Ver0.20;0000.00.00";
static uint8_t k92x0249_features[] = {
/* Feature : 0x01 : Players and switches
Param1 : 1 : Number of players
Param2 : 18 : Number of switches per player
Param3 : 0 : N/A */
0x01,
0x01,
0x18,
0x00,
/* Feature : 0x02 : Coin slots
Param1 : 2 : Number of coin slots
Param2 : 0 : N/A
Param3 : 0 : N/A */
0x02,
0x00,
0x00,
0x00,
/* Feature : 0x03 : Analog inputs
Param1 : 8 : Number of ADC channels
Param2 : 10 : Effective bits of resolution per ADC
Param3 : 0 : N/A */
0x03,
0x00,
0x00,
0x00,
/* Feature : 0x04 : Rotary Input
Param1 : 4 : Number of Rotary channels
Param2 : 0 : N/A
Param3 : 0 : N/A */
0x04,
0x00,
0x00,
0x00,
/* Feature : 0x12 : GPIO outputs
Param1 : 3 : Number of ports (8 bits per port)
Param2 : 0 : N/A
Param3 : 0 : N/A
*/
0x12,
0x00,
0x00,
0x00,
/* Feature : 0x13 : Analog outputs
Param1 : 2 : Number of channels
Param2 : 0 : N/A
Param3 : 0 : N/A
*/
0x13,
0x00,
0x00,
0x00,
/* Feature : 0x14 : Character Output
Param1 : 0x50 : Width
Param2 : 0x19 : Height
Param3 : 0 : Type
*/
0x14,
0x50,
0x19,
0x00,
/* Feature : 0x00 : End of capabilities */
0x00,
};
static void k92x0249_transact(
struct jvs_node *node,
const void *bytes,
size_t nbytes,
struct iobuf *resp);
static bool k92x0249_sense(struct jvs_node *node);
static HRESULT k92x0249_cmd(
void *ctx,
struct const_iobuf *req,
struct iobuf *resp);
static HRESULT k92x0249_cmd_reset(struct k92x0249 *k92x0249, struct const_iobuf *req_buf);
static HRESULT k92x0249_cmd_assign_addr(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT k92x0249_cmd_read_id(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT k92x0249_cmd_get_cmd_version(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT k92x0249_cmd_get_jvs_version(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT k92x0249_cmd_get_comm_version(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT k92x0249_cmd_get_features(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf);
static HRESULT k92x0249_cmd_read_misc_switches(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, uint8_t req_len, struct iobuf *resp_buf);
void k92x0249_init(
struct k92x0249 *k92x0249,
struct jvs_node *next,
const struct k92x0249_ops *ops,
void *ops_ctx)
{
assert(k92x0249 != NULL);
assert(ops != NULL);
k92x0249->jvs.next = next;
k92x0249->jvs.transact = k92x0249_transact;
k92x0249->jvs.sense = k92x0249_sense;
k92x0249->jvs.sense_out = true;
k92x0249->addr = 0xFF;
k92x0249->ops = ops;
k92x0249->ops_ctx = ops_ctx;
}
struct jvs_node *k92x0249_to_jvs_node(struct k92x0249 *k92x0249)
{
assert(k92x0249 != NULL);
return &k92x0249->jvs;
}
static void k92x0249_transact(
struct jvs_node *node,
const void *bytes,
size_t nbytes,
struct iobuf *resp)
{
struct k92x0249 *k92x0249;
assert(node != NULL);
assert(bytes != NULL);
assert(resp != NULL);
k92x0249 = CONTAINING_RECORD(node, struct k92x0249, jvs);
jvs_crack_request(bytes, nbytes, resp, k92x0249->addr, k92x0249_cmd, k92x0249);
}
static bool k92x0249_sense(struct jvs_node *node)
{
struct k92x0249 *k92x0249;
assert(node != NULL);
k92x0249 = CONTAINING_RECORD(node, struct k92x0249, jvs);
return k92x0249->addr == 0xFF;
}
static HRESULT k92x0249_cmd(
void *ctx,
struct const_iobuf *req,
struct iobuf *resp)
{
struct k92x0249 *k92x0249;
uint8_t req_len;
iobuf_read_8(req, &req_len); // Read the length for variable-length commands
k92x0249 = ctx;
switch (req->bytes[req->pos]) {
case JVS_CMD_RESET:
return k92x0249_cmd_reset(k92x0249, req);
case JVS_CMD_ASSIGN_ADDR:
return k92x0249_cmd_assign_addr(k92x0249, req, resp);
case JVS_CMD_READ_ID:
return k92x0249_cmd_read_id(k92x0249, req, resp);
case JVS_CMD_GET_CMD_VERSION:
return k92x0249_cmd_get_cmd_version(k92x0249, req, resp);
case JVS_CMD_GET_JVS_VERSION:
return k92x0249_cmd_get_jvs_version(k92x0249, req, resp);
case JVS_CMD_GET_COMM_VERSION:
return k92x0249_cmd_get_comm_version(k92x0249, req, resp);
case JVS_CMD_GET_FEATURES:
return k92x0249_cmd_get_features(k92x0249, req, resp);
case JVS_CMD_READ_MISC_SWITCHES:
return k92x0249_cmd_read_misc_switches(k92x0249, req, req_len, resp);
default:
dprintf("K92X0249: Node %02x: Unhandled command byte %02x\n",
k92x0249->addr,
req->bytes[req->pos]);
return E_NOTIMPL;
}
return S_OK;
}
static HRESULT k92x0249_cmd_reset(struct k92x0249 *k92x0249, struct const_iobuf *req_buf)
{
struct jvs_req_reset req;
HRESULT hr;
hr = iobuf_read(req_buf, &req, sizeof(req));
if (FAILED(hr)) {
return hr;
}
dprintf("K92X0249: Reset (param %02x)\n", req.unknown);
k92x0249->addr = 0xFF;
k92x0249->jvs.sense_out = false; // ?
if (k92x0249->ops->reset != NULL) {
k92x0249->ops->reset(k92x0249->ops_ctx);
}
/* No ack for this since it really is addressed to everybody */
return S_OK;
}
static HRESULT k92x0249_cmd_assign_addr(
struct k92x0249 *k92x0249,
struct const_iobuf *req_buf,
struct iobuf *resp_buf)
{
struct jvs_req_assign_addr req;
bool sense;
HRESULT hr;
hr = iobuf_read(req_buf, &req, sizeof(req));
if (FAILED(hr)) {
return hr;
}
sense = jvs_node_sense(k92x0249->jvs.next);
dprintf("K92X0249: Assign addr %02x sense %i\n", req.addr, sense);
if (sense) {
/* That address is for somebody else */
return S_OK;
}
k92x0249->addr = req.addr;
k92x0249->jvs.sense_out = true;
return iobuf_write_8(resp_buf, 0x01);
}
static HRESULT k92x0249_cmd_read_id(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("K92X0249: Read ID\n");
/* Write report byte */
hr = iobuf_write_8(resp_buf, 0x01);
if (FAILED(hr)) {
return hr;
}
/* Write the identification string. The NUL terminator at the end of this C
string is also sent, and it naturally terminates the response chunk. */
return iobuf_write(resp_buf, k92x0249_ident, sizeof(k92x0249_ident));
}
static HRESULT k92x0249_cmd_get_cmd_version(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("K92X0249: Get command format version\n");
resp[0] = 0x01; /* Report byte */
resp[1] = 0x13; /* Command format version BCD */
return iobuf_write(resp_buf, resp, sizeof(resp));
}
static HRESULT k92x0249_cmd_get_jvs_version(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("K92X0249: Get JVS format version\n");
resp[0] = 0x01; /* Report byte */
resp[1] = 0x30; /* JVS format version BCD */
return iobuf_write(resp_buf, resp, sizeof(resp));
}
static HRESULT k92x0249_cmd_get_comm_version(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("K92X0249: Get COMM format version\n");
resp[0] = 0x01; /* Report byte */
resp[1] = 0x10; /* COMM format version BCD */
return iobuf_write(resp_buf, resp, sizeof(resp));
}
static HRESULT k92x0249_cmd_get_features(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, struct iobuf *resp_buf)
{
uint8_t req;
uint8_t resp[2];
HRESULT hr;
hr = iobuf_read_8(req_buf, &req);
if (FAILED(hr)) {
return hr;
}
dprintf("K92X0249: Get reader features\n");
hr = iobuf_write_8(resp_buf, 0x01); /* Write report byte */
if (FAILED(hr)) {
return hr;
}
return iobuf_write(resp_buf, k92x0249_features, sizeof(k92x0249_features));
}
static HRESULT k92x0249_cmd_read_misc_switches(struct k92x0249 *k92x0249, struct const_iobuf *req_buf, uint8_t req_len, struct iobuf *resp_buf)
{
uint8_t req[255];
HRESULT hr;
#if 0
dprintf("K92X0249: Read misc switches\n");
dump_const_iobuf(req_buf);
#endif
// data bytes: 01 61 32 01 80
hr = iobuf_read(req_buf, &req, req_len - 1); // duno what these bytes mean...
if (FAILED(hr)) {
return hr;
}
hr = iobuf_write_8(resp_buf, 0x01); /* Write report byte */
if (FAILED(hr)) {
return hr;
}
return iobuf_write_8(resp_buf, 0x00); /* Write switch byte */
// Below will trip a card request with blank info
// hr = iobuf_write(resp_buf, (uint8_t *)"7020000000000000", 16); /* Nesica ID */
// if (FAILED(hr)) {
// return hr;
// }
// hr = iobuf_write(resp_buf, (uint8_t *)"00000000000000000000", 20); /* Access Code */
// if (FAILED(hr)) {
// return hr;
// }
// return iobuf_write_8(resp_buf, 0x01); /* is AICC */
}
+7 -7
View File
@@ -3,23 +3,23 @@
#include "jvs/jvs-bus.h"
struct j9100628a_ops {
struct k92x0249_ops {
void (*reset)(void *ctx);
void (*write_led)(void *ctx, uint32_t state);
void (*poll_card)(void *ctx, char *serial);
};
struct j9100628a {
struct k92x0249 {
struct jvs_node jvs;
uint8_t addr;
const struct j9100628a_ops *ops;
const struct k92x0249_ops *ops;
void *ops_ctx;
};
void j9100628a_init(
struct j9100628a *j9100628a,
void k92x0249_init(
struct k92x0249 *k92x0249,
struct jvs_node *next,
const struct j9100628a_ops *ops,
const struct k92x0249_ops *ops,
void *ops_ctx);
struct jvs_node *j9100628a_to_jvs_node(struct j9100628a *j9100628a);
struct jvs_node *k92x0249_to_jvs_node(struct k92x0249 *k92x0249);
+4 -4
View File
@@ -16,10 +16,10 @@ board_lib = static_library(
'guid.h',
'io3.c',
'io3.h',
'j9100628a.c',
'j9100628a.h',
'j9100647a.c',
'j9100647a.h',
'k92x0249.c',
'k92x0249.h',
'k9101258.c',
'k9101258.h',
'io4.c',
'io4.h',
'sg-cmd.c',
-1
View File
@@ -2,7 +2,6 @@
pushd %~dp0
REM chcp 932
start inject.exe -d -k ll3hook.dll d_drive\Service\NesysService.exe -app
inject.exe -d -k ll3hook.dll ll3.exe -singlemonitor -windowmode -highquality
REM Comment above and uncomment below for terminal mode
+9
View File
@@ -3,3 +3,12 @@ d_drive=d_drive
[netenv]
enable=1
[syscfg]
log_level=0
[dns]
default=localhost
[cert]
path=client.p12
+9
View File
@@ -3,3 +3,12 @@ d_drive=d_drive
[netenv]
enable=1
[gfx]
enable=0
[dns]
default=localhost
[cert]
path=client.p12
+16 -76
View File
@@ -6,59 +6,7 @@ all games.
Keyboard binding settings use
[Virtual-Key Codes](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes).
## `[aimeio]`
Controls the card reader driver.
### `path`
Specify a path for a third-party card reader driver DLL. Default is empty
(use built-in emulation based on text files and keyboard input).
In previous versions of Taitools this was accomplished by replacing the
AIMEIO.DLL file that came with Taitools. Taitools no longer ships with a
separate AIMEIO.DLL file (its functionality is now built into the various hook
DLLs).
## `[aime]`
Controls emulation of the Aime card reader assembly.
### `enable`
Default: `1`
Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
reader (COM port number varies by game).
### `aimePath`
Default: `DEVICE\aime.txt`
Path to a text file containing a classic Nesica IC card ID. **This does not
currently work**.
### `felicaPath`
Default: `DEVICE\felica.txt`
Path to a text file containing a FeliCa e-cash card IDm serial number.
### `felicaGen`
Default: `1`
Whether to generate a random FeliCa ID if the file at `felicaPath` does not
exist.
### `scan`
Default: `0x0D` (`VK_RETURN`)
Virtual-key code. If this button is **held** then the emulated IC card reader
emulates an IC card in its proximity. A variety of different IC cards can be
emulated; the exact choice of card that is emulated depends on the presence or
absence of the configured card ID files.
For Raw Input, you're on your own for now.
## `[clock]`
@@ -110,34 +58,25 @@ Default: Empty string (i.e. use value from `default` setting)
Overrides the target of the `tenporouter.loc` and `bbrouter.loc` hostname
lookups.
### `startup`
Default: Empty string (i.e. use value from `default` setting)
Overrides the target of the `naominet.jp` host lookup.
### `billing`
Default: Empty string (i.e. use value from `default` setting)
Overrides the target of the `ib.naominet.jp` host lookup.
### `aimedb`
Default: Empty string (i.e. use value from `default` setting)
Overrides the target of the `aime.naominet.jp` host lookup.
## `[jvs]`
Configure emulation of the AMEX PCIe JVS *controller* (not IO board!)
Configure emulation of the iDMAC JVS port (usually the reader, NOT IO! For IO, see the FastIO section)
### `enable`
Default `1`
Enable JVS port emulation. Disable to use the JVS port on a real AMEX.
Enable JVS port emulation. Disable to use the JVS port on a real iDMAC card.
## `[fastio]`
Configure emulation of the iDMAC FastIO ports
### `enable`
Default `1`
Enable FastIO port emulation. Disable to use the JVS port on a real iDMAC card.
## `[netenv]`
@@ -243,5 +182,6 @@ If 1, hooks functions related to server and client certificate processing.
Default: ``
Path to a cert file (base64 with headers) that contains the client cert to be used for mTLS.
Leave this blank to disable mTLS, if the server you're connecting to supports it.
Path to a certificate file in either PEM or P12/PFX format that contains the client cert
to be used for mTLS. Leave this blank to disable mTLS, if the server you're connecting
to supports it.
+69
View File
@@ -0,0 +1,69 @@
# Theatrhythm (sivahook) configuration settings
Config options specific to Theatrhythm. Note that the system buttons
in the fastio section are only mapped to the keyboard via `GetAsyncKeyState`,
and are not exposed via Raw Input.
## `[fastio]`
### `test`
Default `0x24`(VK_HOME)
IO board "test" system button.
### `service`
Default `0x2E`(VK_DELETE)
IO board "service" system button.
### `select`
Default `0x23`(VK_END)
IO board "select" system button.
### `enter`
Default `0xA1`(VK_RSHIFT)
IO board "enter" system button.
### `coin`
Default `0x2D`(VK_INSERT)
Coin switch, adds a coin if you're not in free play
## `[deck]`
### `input_type`
Default `0`
0 for the legacy `GetAsyncKeyState` method of input polling,
1 for newer Raw Input polling. See above note for system buttons in
the `[fastio]` section.
### `device_num`
Default `0`
Index of the device on the list of Raw Input devices. Note that this value
may change as devices are connected and disconnected, and between system
reboots.
### `left_button`
Default `67`(C)
Left button on the control deck.
### `right_button`
Default `78`(N)
Right button on the control deck.
### TODO: the rest of the inputs. See [sivaio/config.c](../../sivaio/config.c) in the mean time.
+61
View File
@@ -1,11 +1,13 @@
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>
#include "hooklib/config.h"
#include "hooklib/dvd.h"
#include "hooklib/printer.h"
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename)
{
@@ -14,3 +16,62 @@ void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename)
cfg->enable = GetPrivateProfileIntW(L"dvd", L"enable", 1, filename);
}
void printer_config_load(struct printer_config *cfg, const wchar_t *filename)
{
assert(cfg != NULL);
assert(filename != NULL);
wchar_t tmpstr[16];
cfg->enable = GetPrivateProfileIntW(L"printer", L"enable", 0, filename);
cfg->rotate_180 = GetPrivateProfileIntW(L"printer", L"rotate180", 0, filename);
GetPrivateProfileStringW(
L"printer",
L"serial_no",
L"5A-A123",
tmpstr,
_countof(tmpstr),
filename);
size_t n = wcstombs(cfg->serial_no, tmpstr, sizeof(cfg->serial_no));
for (int i = n; i < sizeof(cfg->serial_no); i++)
{
cfg->serial_no[i] = '\0';
}
GetPrivateProfileStringW(
L"printer",
L"mainFwPath",
L"d_drive\\printer_main_fw.bin",
cfg->main_fw_path,
_countof(cfg->main_fw_path),
filename);
GetPrivateProfileStringW(
L"printer",
L"dspFwPath",
L"d_drive\\printer_dsp_fw.bin",
cfg->dsp_fw_path,
_countof(cfg->dsp_fw_path),
filename);
GetPrivateProfileStringW(
L"printer",
L"paramFwPath",
L"d_drive\\printer_param_fw.bin",
cfg->param_fw_path,
_countof(cfg->param_fw_path),
filename);
GetPrivateProfileStringW(
L"printer",
L"printerOutPath",
L"d_drive\\print",
cfg->printer_out_path,
_countof(cfg->printer_out_path),
filename);
cfg->wait_time = GetPrivateProfileIntW(L"printer", L"waitTime", 0, filename);
}
+2
View File
@@ -3,5 +3,7 @@
#include <stddef.h>
#include "hooklib/dvd.h"
#include "hooklib/printer.h"
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename);
void printer_config_load(struct printer_config *cfg, const wchar_t *filename);
+7 -7
View File
@@ -20,16 +20,16 @@ static const struct hook_symbol cursor_syms[] = {
.name = "SetCursor",
.patch = my_SetCursor,
.link = (void **) &next_SetCursor
},/*{
}, {
.name = "SetCursorPos",
.patch = my_SetCursorPos,
},*/ {
}, {
.name = "SetPhysicalCursorPos",
.patch = my_SetPhysicalCursorPos
}, /*{
}, {
.name = "ShowCursor",
.patch = my_ShowCursor
}*/
}
};
void cursor_hook_init()
@@ -45,13 +45,13 @@ void cursor_hook_init()
static BOOL my_SetCursorPos(int x, int y)
{
dprintf("my_SetCursorPos Hit! x %d y %d\n", x, y);
//dprintf("my_SetCursorPos Hit! x %d y %d\n", x, y);
return true;
}
static BOOL my_SetPhysicalCursorPos(int x, int y)
{
dprintf("my_SetPhysicalCursorPos Hit! x %d y %d\n", x, y);
//dprintf("my_SetPhysicalCursorPos Hit! x %d y %d\n", x, y);
return true;
}
@@ -63,7 +63,7 @@ static int my_ShowCursor(BOOL bShow)
static HCURSOR my_SetCursor(HCURSOR hCursor)
{
dprintf("my_SetCursor Hit!\n");
//dprintf("my_SetCursor Hit!\n");
HCURSOR fake_cursor;
if ( hCursor )
+2
View File
@@ -23,6 +23,8 @@ hooklib_lib = static_library(
'fdshark.h',
'path.c',
'path.h',
'printer.c',
'printer.h',
'reg.c',
'reg.h',
'setupapi.c',
+3472
View File
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
struct printer_config {
bool enable;
bool rotate_180;
char serial_no[8];
wchar_t main_fw_path[MAX_PATH];
wchar_t dsp_fw_path[MAX_PATH];
wchar_t param_fw_path[MAX_PATH];
wchar_t printer_out_path[MAX_PATH];
uint32_t wait_time;
};
void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self);
void printer_hook_insert_hooks(HMODULE target);
void printer_set_dimensions(int width, int height);
int WINAPI fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult);
int WINAPI fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResult);
int WINAPI fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rResult);
+21 -7
View File
@@ -6,6 +6,7 @@
#include "hook/table.h"
#include "hook/iohook.h"
#include "hook/procaddr.h"
#include "board/guid.h"
#include "hooklib/setupapi.h"
@@ -228,6 +229,12 @@ void winusb_hook_insert_hooks(HMODULE target)
"WINUSB.dll",
winusb_syms,
_countof(winusb_syms));
proc_addr_table_push(
target,
"WINUSB.dll",
winusb_syms,
_countof(winusb_syms));
}
static HRESULT winusb_handle_irp(struct irp *irp)
@@ -287,13 +294,11 @@ BOOL my_WinUsb_QueryPipe(WINUSB_INTERFACE_HANDLE InterfaceHandle, UCHAR Alternat
if (!this_pipeid) {
return false;
}
//PipeInformation = (PWINUSB_PIPE_INFORMATION)malloc(sizeof(WINUSB_PIPE_INFORMATION));
PipeInformation->PipeType = UsbdPipeTypeBulk;
PipeInformation->PipeId = this_pipeid;
PipeInformation->Interval = 0xff; // never checked?
PipeInformation->MaximumPacketSize = 128; // never checked?
PipeInformation->Interval = 0x00; // never checked?
PipeInformation->MaximumPacketSize = 0x40; // never checked?
return true;
}
@@ -307,7 +312,16 @@ BOOL my_WinUsb_QueryInterfaceSettings(WINUSB_INTERFACE_HANDLE InterfaceHandle, U
return next_WinUsb_QueryInterfaceSettings(InterfaceHandle, AlternateInterfaceNumber, UsbAltInterfaceDescriptor);
}*/
UsbAltInterfaceDescriptor->bLength = 9;
UsbAltInterfaceDescriptor->bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE;
UsbAltInterfaceDescriptor->bInterfaceNumber = 0;
UsbAltInterfaceDescriptor->bAlternateSetting = 0;
UsbAltInterfaceDescriptor->bNumEndpoints = 2; // nothing else is checked
UsbAltInterfaceDescriptor->bInterfaceClass = 255;
UsbAltInterfaceDescriptor->bInterfaceSubClass = 0;
UsbAltInterfaceDescriptor->bInterfaceProtocol = 0;
UsbAltInterfaceDescriptor->iInterface = 0;
return true;
}
@@ -371,10 +385,10 @@ BOOL my_WinUsb_WritePipe(
Overlapped
);
}*/
#if 1
#if 0
dprintf("WritePipe %d\t", (int)BufferLength);
for (int i = 0; i < BufferLength; i++) {
dprintf("%02X", (char)Buffer[i]);
dprintf("%02X ", (uint8_t)Buffer[i]);
}
dprintf("\n");
#endif
@@ -415,7 +429,7 @@ BOOL my_WinUsb_ReadPipe(
Overlapped
);
}*/
#if 1
#if 0
dprintf("ReadPipe %d\n", (int)BufferLength);
#endif
winusb_classes[idx].read_pipe(NULL, Buffer, BufferLength, (uint32_t *)LengthTransferred);
+32 -15
View File
@@ -1,21 +1,38 @@
#pragma once
enum {
JVS_CMD_TYPEX_READ_DIPSW = 0x01,
JVS_CMD_READ_ID = 0x10,
JVS_CMD_GET_CMD_VERSION = 0x11,
JVS_CMD_GET_JVS_VERSION = 0x12,
JVS_CMD_GET_COMM_VERSION = 0x13,
JVS_CMD_GET_FEATURES = 0x14,
JVS_CMD_READ_SWITCHES = 0x20,
JVS_CMD_READ_COIN = 0x21,
JVS_CMD_READ_ANALOGS = 0x22,
JVS_CMD_READ_MISC_SWITCHES = 0x26,
JVS_CMD_WRITE_GPIO = 0x32,
JVS_CMD_TYPEX_POLL_AMIC = 0x61,
JVS_CMD_TYPEX_POLL_CARD = 0x66,
JVS_CMD_RESET = 0xF0,
JVS_CMD_ASSIGN_ADDR = 0xF1,
JVS_CMD_TAITO_READ_DIPSW = 0x01,
JVS_CMD_READ_ID = 0x10,
JVS_CMD_GET_CMD_VERSION = 0x11,
JVS_CMD_GET_JVS_VERSION = 0x12,
JVS_CMD_GET_COMM_VERSION = 0x13,
JVS_CMD_GET_FEATURES = 0x14,
JVS_CMD_SET_MAIN_ID = 0x15,
JVS_CMD_READ_SWITCHES = 0x20,
JVS_CMD_READ_COIN = 0x21,
JVS_CMD_READ_ANALOGS = 0x22,
JVS_CMD_READ_ROTARY = 0x23,
JVS_CMD_READ_KEYCODE = 0x24,
JVS_CMD_READ_SCREEN_POS = 0x25,
JVS_CMD_READ_MISC_SWITCHES = 0x26,
JVS_CMD_WRITE_PAYOUT_REMAIN = 0x2E,
JVS_CMD_DATA_RETRANSMIT = 0x2F,
JVS_CMD_DEC_COIN_CT = 0x30,
JVS_CMD_INC_PAYOUTT = 0x31,
JVS_CMD_WRITE_GPIO1 = 0x32,
JVS_CMD_WRITE_ANALOG_OUT = 0x33,
JVS_CMD_WRITE_CHAR_OUT = 0x34,
JVS_CMD_INC_COIN_CT = 0x35,
JVS_CMD_DEC_PAYOUTT = 0x36,
JVS_CMD_WRITE_GPIO2 = 0x37,
JVS_CMD_WRITE_GPIO3 = 0x38,
JVS_CMD_RESET = 0xF0,
JVS_CMD_ASSIGN_ADDR = 0xF1,
JVS_CMD_CHANGE_COMM_METHOD = 0xF2,
};
#pragma pack(push, 1)
+10 -1
View File
@@ -10,6 +10,7 @@
#include "jvs/jvs-util.h"
#include "util/dprintf.h"
#include "util/dump.h"
typedef HRESULT (*jvs_dispatch_fn_t)(
void *ctx,
@@ -26,6 +27,7 @@ void jvs_crack_request(
{
uint8_t req_bytes[128];
uint8_t resp_bytes[128];
uint8_t req_bytenum = 0;
struct iobuf decode;
struct iobuf encode;
struct const_iobuf segments;
@@ -56,7 +58,9 @@ void jvs_crack_request(
}
iobuf_flip(&segments, &decode);
segments.pos = 2;
//segments.pos = 2;
segments.pos = 1; // We want to pass the length to the dispatch as well
encode.bytes = resp_bytes;
encode.nbytes = sizeof(resp_bytes);
@@ -69,6 +73,11 @@ void jvs_crack_request(
while (segments.pos + 1 < segments.nbytes) {
hr = dispatch_fn(dispatch_ctx, &segments, &encode);
if (segments.nbytes != segments.pos + 1) {
dprintf("JVS: Unconsumed buffer!\n");
dump_const_iobuf(&segments);
}
if (FAILED(hr)) {
break;
}
+1
View File
@@ -32,4 +32,5 @@ void ll3_hook_config_load(
platform_config_load(&cfg->platform, filename);
ll3_dll_config_load(&cfg->dll, filename);
gfx_config_load(&cfg->gfx, filename);
printer_config_load(&cfg->printer, filename);
}
+2
View File
@@ -7,11 +7,13 @@
#include "platform/config.h"
#include "gfxhook/config.h"
#include "board/config.h"
#include "hooklib/config.h"
struct ll3_hook_config {
struct platform_config platform;
struct ll3_dll_config dll;
struct gfx_config gfx;
struct printer_config printer;
};
void ll3_hook_config_load(
+5 -2
View File
@@ -1,12 +1,13 @@
#include <windows.h>
#include <stdlib.h>
#include "board/j9100647a.h"
#include "board/k9101258.h"
#include "hook/process.h"
#include "hooklib/serial.h"
#include "hooklib/spike.h"
#include "hooklib/printer.h"
#include "gfxhook/gfx.h"
#include "gfxhook/d3d11.h"
@@ -40,7 +41,9 @@ static DWORD CALLBACK ll3_pre_startup(void)
gfx_hook_init(&ll3_hook_cfg.gfx);
gfx_d3d11_hook_init(&ll3_hook_cfg.gfx, ll3_hook_mod);
hr = usbio_hook_init();
printer_hook_init(&ll3_hook_cfg.printer, 0, ll3_hook_mod);
hr = k9101258_hook_init();
if (FAILED(hr)) {
goto fail;
}
+1 -1
View File
@@ -67,7 +67,7 @@ HRESULT ll3_dll_init(const struct ll3_dll_config *cfg, HINSTANCE self)
if (ll3_dll.api_version >= 0x0200) {
hr = E_NOTIMPL;
dprintf("ll3 IO: Custom IO DLL implements an unsupported "
"API version (%#04x). Please update Segatools.\n",
"API version (%#04x). Please update Taitools.\n",
ll3_dll.api_version);
goto end;
+5
View File
@@ -32,6 +32,11 @@ if meson.get_compiler('c').get_id() != 'msvc'
'-static-libgcc',
language: 'c',
)
else
add_project_arguments(
'/wd4090', # different 'const' qualifiers
language: 'c',
)
endif
cc = meson.get_compiler('c')
+87 -25
View File
@@ -1,4 +1,6 @@
@echo off
setlocal enabledelayedexpansion
set BUILD_DIR=build
set BUILD_DIR_32=%BUILD_DIR%\build32
set BUILD_DIR_64=%BUILD_DIR%\build64
@@ -6,11 +8,33 @@ set BUILD_DIR_ZIP=%BUILD_DIR%\zip
set DIST_DIR=dist
set DOC_DIR=doc
REM Set Your Visual Studio install path if this one was wrong
if "%VS_INSTALLATION%"=="" set VS_INSTALLATION=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools
REM Set your Visual Studio install path if Visual Studio installation can not be detected
set VS_INSTALLATION=C:\Program Files\Microsoft Visual Studio\2022\Community
if /I "%1"=="build" (
call :build
call :detect-visual-studio
if ERRORLEVEL 2 exit /b
if ERRORLEVEL 1 (
echo Failed to detect Visual Studio installation path.
echo.
echo If Visual Studio is installed then edit VS_INSTALLATION in this file
echo to manually specify Visual Studio install path.
exit /b
)
call :detect-meson
if ERRORLEVEL 1 (
echo Meson is not installed.
exit /b
)
set VSVARSALL=!VSVARSALL!
set MESON=!MESON!
call :build %2
echo.
echo Build done!
exit /b
)
if /I "%1"=="zip" (
@@ -18,56 +42,94 @@ if /I "%1"=="zip" (
exit /b
)
echo %~nx0 [action]
echo %~nx0 [action] [switch]
echo build: Build the for both x86 and x64
echo /PROJECTONLY: Only create projects
echo.
echo zip: Make zip file
echo.
exit /b
:build (
REM Check VC++
set VSVARALL="%VS_INSTALLATION%\VC\Auxiliary\Build\vcvarsall.bat"
if not exist %VSVARALL% (
echo Build tools for Microsoft Visual C++ 2022 is not Installed
echo Edit this file to change the VS_INSTALLATION if you are installed the Visual Studio in other path
goto end
rem This should works for Visual Studio 2017+
:detect-visual-studio (
rem Fall back to x86 program directory for MSVC standalone if it can't be found in x64, because even though it's x64 compilers, they install in x86 program files for whatever dumb reason
set VSWHERE="%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe"
if not exist %VSWHERE% (
set VSWHERE="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
)
REM Check Meson
if exist %VSWHERE% (
REM get vcvarsall by using vswhere
set VSVARSALL=""
for /f "tokens=* usebackq" %%i in (`%VSWHERE% -products * -find VC\Auxiliary\Build\vcvarsall.bat`) do set VSVARSALL="%%i"
) else (
REM fallback to old method
set VSVARSALL="%VS_INSTALLATION%\VC\Auxiliary\Build\vcvarsall.bat"
)
:check-vcvarsall
if /i %VSVARSALL%=="" (
echo Microsoft Visual C++ Component is not installed
echo Install it from Visual Studio Installer
exit /b 2
)
rem if a path is returned by vswhere, then it's sure that the result path exists
rem if path not exists than it was assumed from VS_INSTALLATION
if not exist %VSVARSALL% (
echo vsvarsall.bat not exists in VS_INSTALLATION,
echo either Visual C++ Component is not installed
echo or VS_INSTALLATION is wrong.
exit /b 1
)
exit /b 0
)
:detect-meson (
set MESON=""
for /f "tokens=* usebackq" %%i in (`where meson`) do set MESON="%%i"
if not exist %MESON% (
echo Meson is not Installed
goto end
exit /b 1
)
exit /b 0
)
:build (
:build_x64 (
call %VSVARALL% x64
call %VSVARSALL% x64
if exist %BUILD_DIR_64% (
%MESON% setup %BUILD_DIR_64% --backend vs --buildtype release --reconfigure
%MESON% setup %BUILD_DIR_64% --buildtype release --reconfigure
) else (
%MESON% setup %BUILD_DIR_64% --backend vs --buildtype release
)
pushd %BUILD_DIR_64%
msbuild /m /p:Configuration=release /p:Platform=x64 taitools.sln
popd
if /I not "%1"=="/PROJECTONLY" (
pushd %BUILD_DIR_64%
msbuild /m /p:Configuration=release /p:Platform=x64 taitools.sln
popd
)
)
:build_x86 (
call %VSVARALL% x86
call %VSVARSALL% x86
if exist %BUILD_DIR_32% (
%MESON% setup %BUILD_DIR_32% --backend vs --buildtype release --reconfigure
%MESON% setup %BUILD_DIR_32% --buildtype release --reconfigure
) else (
%MESON% setup %BUILD_DIR_32% --backend vs --buildtype release
)
pushd %BUILD_DIR_32%
msbuild /m /p:Configuration=release /p:Platform=Win32 taitools.sln
popd
if /I not "%1"=="/PROJECTONLY" (
pushd %BUILD_DIR_32%
msbuild /m /p:Configuration=release /p:Platform=Win32 taitools.sln
popd
)
)
:end (
endlocal
exit /b
)
)
+17 -13
View File
@@ -26,10 +26,10 @@
static CRITICAL_SECTION cert_lock;
static wchar_t path[MAX_PATH];
HCERTSTORE p12store;
PCCERT_CONTEXT client_cert_ctx = NULL;
static HCERTSTORE p12store;
static PCCERT_CONTEXT client_cert_ctx = NULL;
PCCERT_CONTEXT WINAPI my_CertFindCertificateInStore(
static PCCERT_CONTEXT WINAPI my_CertFindCertificateInStore(
HCERTSTORE hCertStore,
DWORD dwCertEncodingType,
DWORD dwFindFlags,
@@ -38,7 +38,7 @@ PCCERT_CONTEXT WINAPI my_CertFindCertificateInStore(
PCCERT_CONTEXT pPrevCertContext
);
HCERTSTORE WINAPI my_CertOpenStore(
static HCERTSTORE WINAPI my_CertOpenStore(
LPCSTR lpszStoreProvider,
DWORD dwEncodingType,
HCRYPTPROV_LEGACY hCryptProv,
@@ -53,7 +53,7 @@ static BOOL my_WinHttpSetOption(
DWORD dwBufferLength
);
PCCERT_CONTEXT (WINAPI *next_CertFindCertificateInStore)(
static PCCERT_CONTEXT (WINAPI *next_CertFindCertificateInStore)(
HCERTSTORE hCertStore,
DWORD dwCertEncodingType,
DWORD dwFindFlags,
@@ -62,7 +62,7 @@ PCCERT_CONTEXT (WINAPI *next_CertFindCertificateInStore)(
PCCERT_CONTEXT pPrevCertContext
);
HCERTSTORE (WINAPI *next_CertOpenStore)(
static HCERTSTORE (WINAPI *next_CertOpenStore)(
LPCSTR lpszStoreProvider,
DWORD dwEncodingType,
HCRYPTPROV_LEGACY hCryptProv,
@@ -77,7 +77,7 @@ static BOOL (*next_WinHttpSetOption)(
DWORD dwBufferLength
);
void ca_error_cb(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
static void ca_error_cb(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
static const struct hook_symbol cert_syms[] = {
{
@@ -200,7 +200,7 @@ void cert_hook_insert_hooks(HMODULE target)
_countof(winhttp_syms));
}
PCCERT_CONTEXT WINAPI my_CertFindCertificateInStore(
static PCCERT_CONTEXT WINAPI my_CertFindCertificateInStore(
HCERTSTORE hCertStore,
DWORD dwCertEncodingType,
DWORD dwFindFlags,
@@ -239,7 +239,7 @@ PCCERT_CONTEXT WINAPI my_CertFindCertificateInStore(
);
}
HCERTSTORE WINAPI my_CertOpenStore(
static HCERTSTORE WINAPI my_CertOpenStore(
LPCSTR lpszStoreProvider,
DWORD dwEncodingType,
HCRYPTPROV_LEGACY hCryptProv,
@@ -290,8 +290,12 @@ static BOOL my_WinHttpSetOption(
}
// Some games don't call WINHTTP_OPTION_SECURITY_FLAGS, so we do it here
int value = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
next_WinHttpSetOption(hInternet, WINHTTP_OPTION_SECURITY_FLAGS, &value, dwBufferLength);
int value = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
next_WinHttpSetOption(hInternet, WINHTTP_OPTION_SECURITY_FLAGS, &value, 4);
if (p12store == NULL && client_cert_ctx == NULL) {
return next_WinHttpSetOption(hInternet, dwOption, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0);
}
}
else if (dwOption == WINHTTP_OPTION_SECURITY_FLAGS) {
dprintf("Cert: Add all security ignore flags\n");
@@ -303,7 +307,7 @@ static BOOL my_WinHttpSetOption(
SetLastError(0);
}
int value = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID; // the kitchen sink
int value = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE; // the kitchen sink
return next_WinHttpSetOption(hInternet, dwOption, &value, dwBufferLength);
} else {
dprintf("Cert: my_WinHttpSetOption %p %08X\n", hInternet, (int)dwOption);
@@ -312,7 +316,7 @@ static BOOL my_WinHttpSetOption(
return next_WinHttpSetOption(hInternet, dwOption, lpBuffer, dwBufferLength);
}
void ca_error_cb(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
static void ca_error_cb(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
{
dprintf("Cert: HTTP Secure connection failure: %04lX\n", *(DWORD *)lpvStatusInformation);
}
+60 -18
View File
@@ -16,10 +16,14 @@ static WNDCLASSEX ri_wndclass;
static HANDLE selected_ri_dev = (HANDLE)-1;
static uintptr_t ri_thread;
static ri_mouse_cb_t mouse_cb = NULL;
static ri_kb_cb_t kb_cb = NULL;
static ri_hid_cb_t hid_cb = NULL;
LRESULT CALLBACK ri_win_proc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lParam);
static unsigned int __stdcall ri_thread_proc(void *ctx);
HRESULT ri_init(uint8_t dev_num)
HRESULT ri_init(uint8_t dev_num, ri_mouse_cb_t in_mouse_cb, ri_kb_cb_t in_kb_cb, ri_hid_cb_t in_hid_cb)
{
wchar_t ri_dev_name[MAX_PATH] = L"\0";
wchar_t hid_prod_name[MAX_PATH] = L"\0";
@@ -28,6 +32,10 @@ HRESULT ri_init(uint8_t dev_num)
DWORD err = 0;
PRAWINPUTDEVICELIST ri_devs = NULL;
mouse_cb = in_mouse_cb;
kb_cb = in_kb_cb;
hid_cb = in_hid_cb;
if (GetRawInputDeviceList(NULL, &num_ri_devs, sizeof(RAWINPUTDEVICELIST)) != 0) {
err = GetLastError();
dprintf("RawInput: GetRawInputDeviceList failed to get number of devices %08lX\n", err);
@@ -118,25 +126,25 @@ static unsigned int __stdcall ri_thread_proc(void *ctx)
ri_hwnd = CreateWindowExA(0, ri_wndclass.lpszClassName, "Taitools Input", 0, 0, 0, 0, 0, NULL, NULL, ri_wndclass.hInstance, NULL);
RAWINPUTDEVICE Rid[4];
Rid[0].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
Rid[0].usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE
Rid[0].dwFlags = RIDEV_NOLEGACY; // adds mouse and also ignores legacy mouse messages
Rid[0].hwndTarget = ri_hwnd;
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
Rid[0].dwFlags = RIDEV_NOLEGACY; // adds mouse and also ignores legacy mouse messages
Rid[0].hwndTarget = ri_hwnd;
Rid[1].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
Rid[1].usUsage = 0x06; // HID_USAGE_GENERIC_KEYBOARD
Rid[1].dwFlags = RIDEV_NOLEGACY; // adds keyboard and also ignores legacy keyboard messages
Rid[1].hwndTarget = ri_hwnd;
Rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[1].usUsage = HID_USAGE_GENERIC_KEYBOARD;
Rid[1].dwFlags = RIDEV_NOLEGACY; // adds keyboard and also ignores legacy keyboard messages
Rid[1].hwndTarget = ri_hwnd;
Rid[2].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
Rid[2].usUsage = 0x05; // HID_USAGE_GENERIC_GAMEPAD
Rid[2].dwFlags = 0; // adds game pad
Rid[2].hwndTarget = ri_hwnd;
Rid[2].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[2].usUsage = HID_USAGE_GENERIC_GAMEPAD;
Rid[2].dwFlags = 0; // adds game pad
Rid[2].hwndTarget = ri_hwnd;
Rid[3].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
Rid[3].usUsage = 0x04; // HID_USAGE_GENERIC_JOYSTICK
Rid[3].dwFlags = 0; // adds joystick
Rid[3].hwndTarget = ri_hwnd;
Rid[3].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[3].usUsage = HID_USAGE_GENERIC_JOYSTICK;
Rid[3].dwFlags = 0; // adds joystick
Rid[3].hwndTarget = ri_hwnd;
if (!RegisterRawInputDevices(Rid, 4, sizeof(Rid[0]))) {
dprintf("RawInput: Failed to register RI devices\n");
@@ -161,7 +169,41 @@ LRESULT CALLBACK ri_win_proc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lParam)
switch (msg) {
case WM_INPUT:
//dprintf("RawInput: Got input\n");
break;
UINT pdata_size = 0;
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &pdata_size, sizeof(RAWINPUTHEADER)) != -1 && pdata_size > 0) {
PRAWINPUT ridata = (PRAWINPUT)malloc(pdata_size);
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, ridata, &pdata_size, sizeof(RAWINPUTHEADER));
if (ridata->header.hDevice != selected_ri_dev) {
free(ridata);
return (LRESULT)0;
}
switch (ridata->header.dwType) {
case RIM_TYPEMOUSE:
if (mouse_cb != NULL) {
mouse_cb(&ridata->data.mouse);
}
break;
case RIM_TYPEKEYBOARD:
if (kb_cb != NULL) {
kb_cb(&ridata->data.keyboard);
}
break;
case RIM_TYPEHID:
if (hid_cb != NULL) {
hid_cb(&ridata->data.hid);
}
break;
}
free(ridata);
}
return (LRESULT)0;
case WM_QUIT:
dprintf("RI: Exit requested\n");
ExitProcess(0);
return (LRESULT)0;
}
return DefWindowProc(hWnd, msg, wparam, lParam);
+5 -1
View File
@@ -2,5 +2,9 @@
#include <windows.h>
#include <stdint.h>
HRESULT ri_init(uint8_t dev_num);
typedef void (*ri_mouse_cb_t)(PRAWMOUSE);
typedef void (*ri_kb_cb_t)(PRAWKEYBOARD);
typedef void (*ri_hid_cb_t)(PRAWHID);
HRESULT ri_init(uint8_t dev_num, ri_mouse_cb_t in_mouse_cb, ri_kb_cb_t in_kb_cb, ri_hid_cb_t in_hid_cb);
void ri_exit();
+2
View File
@@ -8,6 +8,7 @@
#include "hooklib/serial.h"
#include "hooklib/spike.h"
#include "hooklib/cursor.h"
#include "idmac/idmac.h"
@@ -82,6 +83,7 @@ static DWORD CALLBACK siva_pre_startup(void)
}
unity_hook_init();
cursor_hook_init();
/* Initialize debug helpers */
spike_hook_init(L".\\taitools.ini");
+48
View File
@@ -50,6 +50,54 @@ static void siva_fastio_digital_read(void *ctx, uint32_t *out)
if (btn & BTN_SERVICE) {
*out |= SIVA_SWITCH_SYS_SERVICE;
}
if (btn & BTN_SELECT) {
*out |= SIVA_SWITCH_SYS_SELECT;
}
if (btn & BTN_ENTER) {
*out |= SIVA_SWITCH_SYS_ENTER;
}
if (btn & BTN_LEFT) {
*out |= SIVA_SWITCH_LEFT_BUTTON;
}
if (btn & BTN_RIGHT) {
*out |= SIVA_SWITCH_RIGHT_BUTTON;
}
if (stick & STICK_LEFT_UP) {
*out |= SIVA_SWITCH_LEFT_UP;
}
if (stick & STICK_LEFT_DOWN) {
*out |= SIVA_SWITCH_LEFT_DOWN;
}
if (stick & STICK_LEFT_LEFT) {
*out |= SIVA_SWITCH_LEFT_LEFT;
}
if (stick & STICK_LEFT_RIGHT) {
*out |= SIVA_SWITCH_LEFT_RIGHT;
}
if (stick & STICK_RIGHT_UP) {
*out |= SIVA_SWITCH_RIGHT_UP;
}
if (stick & STICK_RIGHT_DOWN) {
*out |= SIVA_SWITCH_RIGHT_DOWN;
}
if (stick & STICK_RIGHT_LEFT) {
*out |= SIVA_SWITCH_RIGHT_LEFT;
}
if (stick & STICK_RIGHT_RIGHT) {
*out |= SIVA_SWITCH_RIGHT_RIGHT;
}
}
static void siva_fastio_coin_read(void *ctx, uint8_t slot_no, uint32_t *out)
+5 -5
View File
@@ -3,7 +3,7 @@
#include "jvs/jvs-bus.h"
#include "idmac/jvs.h"
#include "board/j9100628a.h"
#include "board/k92x0249.h"
#include "sivahook/reader.h"
#include "sivahook/siva-dll.h"
@@ -13,12 +13,12 @@
static void reader_jvs_write_led(void *ctx, uint32_t state);
static void reader_jvs_poll_card(void *ctx, char *serial);
static const struct j9100628a_ops siva_jvs_reader_ops = {
static const struct k92x0249_ops siva_jvs_reader_ops = {
.write_led = reader_jvs_write_led,
.poll_card = reader_jvs_poll_card,
};
static struct j9100628a siva_jvs_reader;
static struct k92x0249 siva_jvs_reader;
HRESULT siva_reader_init(struct jvs_node **out)
{
@@ -28,8 +28,8 @@ HRESULT siva_reader_init(struct jvs_node **out)
dprintf("Siva Nesica Reader: Init\n");
j9100628a_init(&siva_jvs_reader, NULL, &siva_jvs_reader_ops, NULL);
*out = j9100628a_to_jvs_node(&siva_jvs_reader);
k92x0249_init(&siva_jvs_reader, NULL, &siva_jvs_reader_ops, NULL);
*out = k92x0249_to_jvs_node(&siva_jvs_reader);
return S_OK;
}
+1 -1
View File
@@ -67,7 +67,7 @@ HRESULT siva_dll_init(const struct siva_dll_config *cfg, HINSTANCE self)
if (siva_dll.api_version >= 0x0200) {
hr = E_NOTIMPL;
dprintf("Siva IO: Custom IO DLL implements an unsupported "
"API version (%#04x). Please update Segatools.\n",
"API version (%#04x). Please update Taitools.\n",
siva_dll.api_version);
goto end;
+6 -4
View File
@@ -8,11 +8,13 @@
void siva_io_config_load(struct siva_input_config *cfg, const wchar_t *filename)
{
cfg->test = GetPrivateProfileIntW(L"jvs", L"test", VK_HOME, filename);
cfg->service = GetPrivateProfileIntW(L"jvs", L"service", VK_DELETE, filename);
cfg->coin = GetPrivateProfileIntW(L"jvs", L"coin", VK_INSERT, filename);
cfg->test = GetPrivateProfileIntW(L"fastio", L"test", VK_HOME, filename);
cfg->service = GetPrivateProfileIntW(L"fastio", L"service", VK_DELETE, filename);
cfg->select = GetPrivateProfileIntW(L"fastio", L"select", VK_END, filename);
cfg->enter = GetPrivateProfileIntW(L"fastio", L"enter", VK_RSHIFT, filename);
cfg->coin = GetPrivateProfileIntW(L"fastio", L"coin", VK_INSERT, filename);
cfg->is_ri = GetPrivateProfileIntW(L"deck", L"input_type", 0, filename); // 0 for KB, 1 for RI
cfg->is_ri = GetPrivateProfileIntW(L"deck", L"input_type", 0, filename); // 0 for KB, 1 for RI
cfg->device_num = GetPrivateProfileIntW(L"deck", L"device_num", 1, filename);
cfg->btn_l = GetPrivateProfileIntW(L"deck", L"left_button", 'C', filename);
+3
View File
@@ -10,7 +10,10 @@ struct siva_input_config {
uint8_t test;
uint8_t service;
uint8_t select;
uint8_t enter;
uint8_t coin;
uint8_t btn_l;
uint8_t btn_r;
+84 -5
View File
@@ -16,6 +16,11 @@ static bool siva_io_service = false;
static uint16_t siva_coin_ct = 0;
static uint16_t siva_service_ct = 0;
static struct siva_input_config cfg;
static CRITICAL_SECTION ri_critsec;
void ri_mouse_input_cb(PRAWMOUSE mouse);
void ri_kb_input_cb(PRAWKEYBOARD kb);
void ri_hid_input_cb(PRAWHID hid);
uint16_t siva_io_get_api_version(void)
{
@@ -28,7 +33,8 @@ HRESULT siva_io_init(void)
siva_io_config_load(&cfg, L".\\taitools.ini");
if (cfg.is_ri) {
return ri_init(cfg.device_num);
InitializeCriticalSection(&ri_critsec);
return ri_init(cfg.device_num, ri_mouse_input_cb, ri_kb_input_cb, ri_hid_input_cb);
}
return S_OK;
}
@@ -36,9 +42,53 @@ HRESULT siva_io_init(void)
void siva_io_get_btns(uint8_t *btn, uint8_t *stick)
{
if (GetAsyncKeyState(VK_MENU) && GetAsyncKeyState(VK_F4)) {
ri_exit();
return;
// if (GetAsyncKeyState(VK_MENU) && GetAsyncKeyState(VK_F4)) {
// ri_exit();
// return;
// }
if (cfg.is_ri) {
} else {
if (GetAsyncKeyState(cfg.btn_l) & 0x8000) {
*btn |= BTN_LEFT;
}
if (GetAsyncKeyState(cfg.btn_r) & 0x8000) {
*btn |= BTN_RIGHT;
}
if (GetAsyncKeyState(cfg.stick_l_up) & 0x8000) {
*stick |= STICK_LEFT_UP;
}
if (GetAsyncKeyState(cfg.stick_l_down) & 0x8000) {
*stick |= STICK_LEFT_DOWN;
}
if (GetAsyncKeyState(cfg.stick_l_left) & 0x8000) {
*stick |= STICK_LEFT_LEFT;
}
if (GetAsyncKeyState(cfg.stick_l_right) & 0x8000) {
*stick |= STICK_LEFT_RIGHT;
}
if (GetAsyncKeyState(cfg.stick_r_up) & 0x8000) {
*stick |= STICK_RIGHT_UP;
}
if (GetAsyncKeyState(cfg.stick_r_down) & 0x8000) {
*stick |= STICK_RIGHT_DOWN;
}
if (GetAsyncKeyState(cfg.stick_r_left) & 0x8000) {
*stick |= STICK_RIGHT_LEFT;
}
if (GetAsyncKeyState(cfg.stick_r_right) & 0x8000) {
*stick |= STICK_RIGHT_RIGHT;
}
}
if (GetAsyncKeyState(cfg.test) & 0x8000) {
@@ -49,6 +99,14 @@ void siva_io_get_btns(uint8_t *btn, uint8_t *stick)
*btn |= BTN_SERVICE;
}
if (GetAsyncKeyState(cfg.select) & 0x8000) {
*btn |= BTN_SELECT;
}
if (GetAsyncKeyState(cfg.enter) & 0x8000) {
*btn |= BTN_ENTER;
}
}
void siva_io_read_coin_counter(uint16_t *coins, uint16_t *services)
@@ -73,4 +131,25 @@ void siva_io_read_coin_counter(uint16_t *coins, uint16_t *services)
*coins = siva_coin_ct;
*services = siva_service_ct;
}
}
void ri_mouse_input_cb(PRAWMOUSE mouse)
{
}
void ri_kb_input_cb(PRAWKEYBOARD kb)
{
}
void ri_hid_input_cb(PRAWHID hid)
{
DWORD bfr_size = hid->dwCount * hid->dwSizeHid;
dprintf("SivaIO: HID input - %d elements * %d bytes per element = %d\n", (int)hid->dwCount, (int)hid->dwSizeHid, (int)bfr_size);
for (int i = 0; i < bfr_size; i++) {
dprintf(" %02X", hid->bRawData[i]);
}
dprintf("\n");
}
+10
View File
@@ -0,0 +1,10 @@
#include "env.h"
const wchar_t* get_config_path() {
static wchar_t path[MAX_PATH];
if (!GetEnvironmentVariableW(L"TAITOOLS_CONFIG_PATH", path, MAX_PATH)) {
return L".\\taitools.ini";
}
return path;
}
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#include <windows.h>
const wchar_t* get_config_path();
+2
View File
@@ -10,6 +10,8 @@ util_lib = static_library(
'async.h',
'crc.c',
'crc.h',
'env.c',
'env.h',
'dll-bind.c',
'dll-bind.h',
'dprintf.c',