forked from Hay1tsme/segatools
Compare commits
1 Commits
2024-08-20
...
2024-02-22
Author | SHA1 | Date | |
---|---|---|---|
d118ef614c
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -18,6 +18,3 @@ build/
|
|||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
subprojects/capnhook
|
subprojects/capnhook
|
||||||
|
|
||||||
# For enabling debug logging on local builds
|
|
||||||
MesonLocalOptions.mk
|
|
||||||
|
9
Makefile
9
Makefile
@ -11,11 +11,6 @@ DOC_DIR := doc
|
|||||||
|
|
||||||
DIST_DIR := dist
|
DIST_DIR := dist
|
||||||
|
|
||||||
# Add "-D[option]=[value]" here as necessary
|
|
||||||
MESON_OPTIONS :=
|
|
||||||
# For options that shouldn't be committed
|
|
||||||
-include MesonLocalOptions.mk
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Targets
|
# Targets
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@ -24,9 +19,9 @@ include Package.mk
|
|||||||
|
|
||||||
.PHONY: build # Build the project
|
.PHONY: build # Build the project
|
||||||
build:
|
build:
|
||||||
$(V)meson setup $(MESON_OPTIONS) --cross cross-mingw-32.txt $(BUILD_DIR_32)
|
$(V)meson --cross cross-mingw-32.txt $(BUILD_DIR_32)
|
||||||
$(V)ninja -C $(BUILD_DIR_32)
|
$(V)ninja -C $(BUILD_DIR_32)
|
||||||
$(V)meson setup $(MESON_OPTIONS) --cross cross-mingw-64.txt $(BUILD_DIR_64)
|
$(V)meson --cross cross-mingw-64.txt $(BUILD_DIR_64)
|
||||||
$(V)ninja -C $(BUILD_DIR_64)
|
$(V)ninja -C $(BUILD_DIR_64)
|
||||||
|
|
||||||
.PHONY: dist # Build and create a zip distribution package
|
.PHONY: dist # Build and create a zip distribution package
|
||||||
|
17
Package.mk
17
Package.mk
@ -203,22 +203,6 @@ $(BUILD_DIR_ZIP)/cm.zip:
|
|||||||
$(V)strip $(BUILD_DIR_ZIP)/cm/*.{exe,dll}
|
$(V)strip $(BUILD_DIR_ZIP)/cm/*.{exe,dll}
|
||||||
$(V)cd $(BUILD_DIR_ZIP)/cm ; zip -r ../cm.zip *
|
$(V)cd $(BUILD_DIR_ZIP)/cm ; zip -r ../cm.zip *
|
||||||
|
|
||||||
$(BUILD_DIR_ZIP)/tokyo.zip:
|
|
||||||
$(V)echo ... $@
|
|
||||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/tokyo
|
|
||||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/tokyo/DEVICE
|
|
||||||
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
|
|
||||||
$(BUILD_DIR_64)/tokyohook/tokyohook.dll \
|
|
||||||
$(DIST_DIR)/tokyo/config_hook.json \
|
|
||||||
$(DIST_DIR)/tokyo/segatools.ini \
|
|
||||||
$(DIST_DIR)/tokyo/start.bat \
|
|
||||||
$(BUILD_DIR_ZIP)/tokyo
|
|
||||||
$(V)cp pki/billing.pub \
|
|
||||||
pki/ca.crt \
|
|
||||||
$(BUILD_DIR_ZIP)/tokyo/DEVICE
|
|
||||||
$(V)strip $(BUILD_DIR_ZIP)/tokyo/*.{exe,dll}
|
|
||||||
$(V)cd $(BUILD_DIR_ZIP)/tokyo ; zip -r ../tokyo.zip *
|
|
||||||
|
|
||||||
$(BUILD_DIR_ZIP)/doc.zip: \
|
$(BUILD_DIR_ZIP)/doc.zip: \
|
||||||
$(DOC_DIR)/config \
|
$(DOC_DIR)/config \
|
||||||
$(DOC_DIR)/chunihook.md \
|
$(DOC_DIR)/chunihook.md \
|
||||||
@ -241,7 +225,6 @@ $(BUILD_DIR_ZIP)/segatools.zip: \
|
|||||||
$(BUILD_DIR_ZIP)/mu3.zip \
|
$(BUILD_DIR_ZIP)/mu3.zip \
|
||||||
$(BUILD_DIR_ZIP)/mai2.zip \
|
$(BUILD_DIR_ZIP)/mai2.zip \
|
||||||
$(BUILD_DIR_ZIP)/cm.zip \
|
$(BUILD_DIR_ZIP)/cm.zip \
|
||||||
$(BUILD_DIR_ZIP)/tokyo.zip \
|
|
||||||
$(BUILD_DIR_ZIP)/fgo.zip \
|
$(BUILD_DIR_ZIP)/fgo.zip \
|
||||||
CHANGELOG.md \
|
CHANGELOG.md \
|
||||||
README.md \
|
README.md \
|
||||||
|
28
README.md
28
README.md
@ -1,33 +1,29 @@
|
|||||||
# Segatools
|
# Segatools
|
||||||
|
|
||||||
Version: `2024-08-20`
|
Version: `2024-02-22`
|
||||||
|
|
||||||
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
|
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
|
||||||
|
|
||||||
## List of supported games
|
## List of supported games
|
||||||
|
|
||||||
* Card Maker
|
|
||||||
* starting from Card Maker
|
|
||||||
* CHUNITHM
|
* CHUNITHM
|
||||||
* up to [CHUNITHM PARADISE LOST](doc/chunihook.md)
|
* up to [CHUNITHM PARADISE LOST](doc/chunihook.md)
|
||||||
* starting from CHUNITHM NEW!!
|
* starting from CHUNITHM NEW!!
|
||||||
* crossbeats REV.
|
|
||||||
* up to crossbeats REV. SUNRISE
|
|
||||||
* Fate/Grand Order
|
|
||||||
* Fate/Grand Order Arcade
|
|
||||||
* Hatsune Miku: Project DIVA Arcade
|
|
||||||
* up to Future Tone
|
|
||||||
* Initial D
|
* Initial D
|
||||||
* [Initial D Arcade Stage Zero](doc/idzhook.md)
|
* [Initial D Arcade Stage Zero](doc/idzhook.md)
|
||||||
* Initial D THE ARCADE
|
* Initial D THE ARCADE
|
||||||
* maimai DX
|
* Hatsune Miku: Project DIVA Arcade
|
||||||
* starting from maimai DX
|
* up to Future Tone
|
||||||
* Mario & Sonic
|
|
||||||
* Mario & Sonic at the Tokyo 2020 Olympics Arcade
|
|
||||||
* O.N.G.E.K.I.
|
|
||||||
* starting from O.N.G.E.K.I.
|
|
||||||
* SEGA World Drivers Championship
|
* SEGA World Drivers Championship
|
||||||
* SEGA World Drivers Championship 2019
|
* SEGA World Drivers Championship 2019
|
||||||
|
* Fate/Grand Order
|
||||||
|
* Fate/Grand Order Arcade
|
||||||
|
* O.N.G.E.K.I.
|
||||||
|
* starting from O.N.G.E.K.I.
|
||||||
|
* maimai DX
|
||||||
|
* starting from maimai DX
|
||||||
|
* Card Maker
|
||||||
|
* starting from Card Maker
|
||||||
* WACCA
|
* WACCA
|
||||||
* starting from WACCA
|
* starting from WACCA
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ static void aime_io_config_read(
|
|||||||
cfg->felica_path,
|
cfg->felica_path,
|
||||||
_countof(cfg->felica_path),
|
_countof(cfg->felica_path),
|
||||||
filename);
|
filename);
|
||||||
|
// dprintf("NFC: felicaPath GetLastError %lx\n", GetLastError());
|
||||||
|
|
||||||
cfg->felica_gen = GetPrivateProfileIntW(
|
cfg->felica_gen = GetPrivateProfileIntW(
|
||||||
L"aime",
|
L"aime",
|
||||||
|
@ -185,14 +185,14 @@ static HRESULT jvs_ioctl_sense(struct irp *irp)
|
|||||||
|
|
||||||
static HRESULT jvs_ioctl_transact(struct irp *irp)
|
static HRESULT jvs_ioctl_transact(struct irp *irp)
|
||||||
{
|
{
|
||||||
#if defined(LOG_JVS)
|
#if 0
|
||||||
dprintf("\nJVS Port: Outbound frame:\n");
|
dprintf("\nJVS Port: Outbound frame:\n");
|
||||||
dump_const_iobuf(&irp->write);
|
dump_const_iobuf(&irp->write);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
jvs_bus_transact(jvs_root, irp->write.bytes, irp->write.nbytes, &irp->read);
|
jvs_bus_transact(jvs_root, irp->write.bytes, irp->write.nbytes, &irp->read);
|
||||||
|
|
||||||
#if defined(LOG_JVS)
|
#if 0
|
||||||
dprintf("JVS Port: Inbound frame:\n");
|
dprintf("JVS Port: Inbound frame:\n");
|
||||||
dump_iobuf(&irp->read);
|
dump_iobuf(&irp->read);
|
||||||
dprintf("\n");
|
dprintf("\n");
|
||||||
|
71
board/io3.c
71
board/io3.c
@ -79,11 +79,6 @@ static HRESULT io3_cmd_read_analogs(
|
|||||||
struct const_iobuf *req_buf,
|
struct const_iobuf *req_buf,
|
||||||
struct iobuf *resp_buf);
|
struct iobuf *resp_buf);
|
||||||
|
|
||||||
static HRESULT io3_cmd_read_rotarys(
|
|
||||||
struct io3 *io3,
|
|
||||||
struct const_iobuf *req_buf,
|
|
||||||
struct iobuf *resp_buf);
|
|
||||||
|
|
||||||
static HRESULT io3_cmd_write_gpio(
|
static HRESULT io3_cmd_write_gpio(
|
||||||
struct io3 *io3,
|
struct io3 *io3,
|
||||||
struct const_iobuf *req_buf,
|
struct const_iobuf *req_buf,
|
||||||
@ -121,13 +116,6 @@ static uint8_t io3_features[] = {
|
|||||||
|
|
||||||
0x03, 8, 10, 0,
|
0x03, 8, 10, 0,
|
||||||
|
|
||||||
/* Feature : 0x04 : Rotary inputs
|
|
||||||
Param1 : 4 : Number of rotary channels
|
|
||||||
Param2 : 0 : N/A
|
|
||||||
Param3 : 0 : N/A */
|
|
||||||
|
|
||||||
0x04, 4, 0, 0,
|
|
||||||
|
|
||||||
/* Feature : 0x12 : GPIO outputs
|
/* Feature : 0x12 : GPIO outputs
|
||||||
Param1 : 3 : Number of ports (8 bits per port)
|
Param1 : 3 : Number of ports (8 bits per port)
|
||||||
Param2 : 0 : N/A
|
Param2 : 0 : N/A
|
||||||
@ -231,9 +219,6 @@ static HRESULT io3_cmd(
|
|||||||
case JVS_CMD_READ_ANALOGS:
|
case JVS_CMD_READ_ANALOGS:
|
||||||
return io3_cmd_read_analogs(io3, req, resp);
|
return io3_cmd_read_analogs(io3, req, resp);
|
||||||
|
|
||||||
case JVS_CMD_READ_ROTARYS:
|
|
||||||
return io3_cmd_read_rotarys(io3, req, resp);
|
|
||||||
|
|
||||||
case JVS_CMD_WRITE_GPIO:
|
case JVS_CMD_WRITE_GPIO:
|
||||||
return io3_cmd_write_gpio(io3, req, resp);
|
return io3_cmd_write_gpio(io3, req, resp);
|
||||||
|
|
||||||
@ -390,7 +375,7 @@ static HRESULT io3_cmd_read_switches(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(LOG_IO3)
|
#if 0
|
||||||
dprintf("JVS I/O: Read switches, np=%i, bpp=%i\n",
|
dprintf("JVS I/O: Read switches, np=%i, bpp=%i\n",
|
||||||
req.num_players,
|
req.num_players,
|
||||||
req.bytes_per_player);
|
req.bytes_per_player);
|
||||||
@ -551,60 +536,6 @@ static HRESULT io3_cmd_read_analogs(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT io3_cmd_read_rotarys(
|
|
||||||
struct io3 *io3,
|
|
||||||
struct const_iobuf *req_buf,
|
|
||||||
struct iobuf *resp_buf)
|
|
||||||
{
|
|
||||||
struct jvs_req_read_rotarys req;
|
|
||||||
uint16_t rotarys[4];
|
|
||||||
uint8_t i;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
/* Read req */
|
|
||||||
|
|
||||||
hr = iobuf_read(req_buf, &req, sizeof(req));
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.nrotarys > _countof(rotarys)) {
|
|
||||||
dprintf("JVS I/O: Invalid analog count %i\n", req.nrotarys);
|
|
||||||
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//dprintf("JVS I/O: Read rotarys, nrotarys=%i\n", req.nrotarys);
|
|
||||||
|
|
||||||
/* Write report byte */
|
|
||||||
|
|
||||||
hr = iobuf_write_8(resp_buf, 0x01);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write analogs */
|
|
||||||
|
|
||||||
memset(rotarys, 0, sizeof(rotarys));
|
|
||||||
|
|
||||||
if (io3->ops->read_rotarys != NULL) {
|
|
||||||
io3->ops->read_rotarys(io3->ops_ctx, rotarys, req.nrotarys);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0 ; i < req.nrotarys ; i++) {
|
|
||||||
hr = iobuf_write_be16(resp_buf, rotarys[i]);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT io3_cmd_write_gpio(
|
static HRESULT io3_cmd_write_gpio(
|
||||||
struct io3 *io3,
|
struct io3 *io3,
|
||||||
struct const_iobuf *req_buf,
|
struct const_iobuf *req_buf,
|
||||||
|
@ -18,7 +18,6 @@ struct io3_ops {
|
|||||||
void (*write_gpio)(void *ctx, uint32_t state);
|
void (*write_gpio)(void *ctx, uint32_t state);
|
||||||
void (*read_switches)(void *ctx, struct io3_switch_state *out);
|
void (*read_switches)(void *ctx, struct io3_switch_state *out);
|
||||||
void (*read_analogs)(void *ctx, uint16_t *analogs, uint8_t nanalogs);
|
void (*read_analogs)(void *ctx, uint16_t *analogs, uint8_t nanalogs);
|
||||||
void (*read_rotarys)(void *ctx, uint16_t *rotaries, uint8_t nrotaries);
|
|
||||||
void (*read_coin_counter)(void *ctx, uint8_t slot_no, uint16_t *out);
|
void (*read_coin_counter)(void *ctx, uint8_t slot_no, uint16_t *out);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ static_assert(sizeof(struct io4_report_in) == 0x40, "IO4 IN report size");
|
|||||||
struct io4_report_out {
|
struct io4_report_out {
|
||||||
uint8_t report_id;
|
uint8_t report_id;
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
uint8_t payload[IO4_REPORT_OUT_PAYLOAD_LEN];
|
uint8_t payload[62];
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(struct io4_report_out) == 0x40, "IO4 OUT report size");
|
static_assert(sizeof(struct io4_report_out) == 0x40, "IO4 OUT report size");
|
||||||
@ -223,11 +223,7 @@ static HRESULT io4_handle_write(struct irp *irp)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
case IO4_CMD_SET_GENERAL_OUTPUT:
|
case IO4_CMD_SET_GENERAL_OUTPUT:
|
||||||
// dprintf("USB I/O: GPIO Out\n");
|
dprintf("USB I/O: GPIO Out\n");
|
||||||
|
|
||||||
if (io4_ops->write_gpio != NULL) {
|
|
||||||
return io4_ops->write_gpio(out.payload, IO4_REPORT_OUT_PAYLOAD_LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define IO4_REPORT_OUT_PAYLOAD_LEN 62
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/* System buttons in button[0] */
|
/* System buttons in button[0] */
|
||||||
|
|
||||||
@ -26,7 +24,6 @@ struct io4_state {
|
|||||||
|
|
||||||
struct io4_ops {
|
struct io4_ops {
|
||||||
HRESULT (*poll)(void *ctx, struct io4_state *state);
|
HRESULT (*poll)(void *ctx, struct io4_state *state);
|
||||||
HRESULT (*write_gpio)(uint8_t* payload, size_t len);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT io4_hook_init(
|
HRESULT io4_hook_init(
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "board/led15070-frame.h"
|
|
||||||
|
|
||||||
/* Command IDs */
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LED_15070_CMD_RESET = 0x10,
|
|
||||||
LED_15070_CMD_SET_INPUT = 0x28, // No known use case
|
|
||||||
LED_15070_CMD_SET_NORMAL_12BIT = 0x30, // TODO
|
|
||||||
LED_15070_CMD_SET_NORMAL_8BIT = 0x31,
|
|
||||||
LED_15070_CMD_SET_MULTI_FLASH_8BIT = 0x32,
|
|
||||||
LED_15070_CMD_SET_MULTI_FADE_8BIT = 0x33,
|
|
||||||
LED_15070_CMD_SET_PALETTE_7_NORMAL_LED = 0x34, // No known use case
|
|
||||||
LED_15070_CMD_SET_PALETTE_6_FLASH_LED = 0x35, // No known use case
|
|
||||||
LED_15070_CMD_SET_15DC_OUT = 0x36, // No known use case
|
|
||||||
LED_15070_CMD_SET_15GS_OUT = 0x37, // No known use case
|
|
||||||
LED_15070_CMD_SET_PSC_MAX = 0x38, // No known use case
|
|
||||||
LED_15070_CMD_SET_FET_OUTPUT = 0x39,
|
|
||||||
LED_15070_CMD_SET_GS_PALETTE = 0x3A,
|
|
||||||
LED_15070_CMD_DC_UPDATE = 0x3B,
|
|
||||||
LED_15070_CMD_GS_UPDATE = 0x3C,
|
|
||||||
LED_15070_CMD_ROTATE = 0x3E, // No known use case, wtf is this?
|
|
||||||
LED_15070_CMD_SET_DC_DATA = 0x3F,
|
|
||||||
LED_15070_CMD_EEPROM_WRITE = 0x7B,
|
|
||||||
LED_15070_CMD_EEPROM_READ = 0x7C,
|
|
||||||
LED_15070_CMD_ACK_ON = 0x7D,
|
|
||||||
LED_15070_CMD_ACK_OFF = 0x7E,
|
|
||||||
LED_15070_CMD_BOARD_INFO = 0xF0,
|
|
||||||
LED_15070_CMD_BOARD_STATUS = 0xF1,
|
|
||||||
LED_15070_CMD_FW_SUM = 0xF2,
|
|
||||||
LED_15070_CMD_PROTOCOL_VER = 0xF3,
|
|
||||||
LED_15070_CMD_TO_BOOT_MODE = 0xFD,
|
|
||||||
LED_15070_CMD_FW_UPDATE = 0xFE,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Response codes */
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LED_15070_STATUS_OK = 0x01,
|
|
||||||
LED_15070_STATUS_SUM_ERR = 0x02,
|
|
||||||
LED_15070_STATUS_PARITY_ERR = 0x03,
|
|
||||||
LED_15070_STATUS_FRAMING_ERR = 0x04,
|
|
||||||
LED_15070_STATUS_OVERRUN_ERR = 0x05,
|
|
||||||
LED_15070_STATUS_BUFFER_OVERFLOW = 0x06,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LED_15070_REPORT_OK = 0x01,
|
|
||||||
LED_15070_REPORT_WAIT = 0x02,
|
|
||||||
LED_15070_REPORT_ERR1 = 0x03,
|
|
||||||
LED_15070_REPORT_ERR2 = 0x04,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Request data structures */
|
|
||||||
|
|
||||||
struct led15070_req_any {
|
|
||||||
struct led15070_hdr hdr;
|
|
||||||
uint8_t cmd;
|
|
||||||
uint8_t payload[256];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Response data structures */
|
|
||||||
|
|
||||||
struct led15070_resp_any {
|
|
||||||
struct led15070_hdr hdr;
|
|
||||||
uint8_t status;
|
|
||||||
uint8_t cmd;
|
|
||||||
uint8_t report;
|
|
||||||
uint8_t data[32];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct led15070_resp_board_info {
|
|
||||||
struct led15070_hdr hdr;
|
|
||||||
uint8_t status;
|
|
||||||
uint8_t cmd;
|
|
||||||
uint8_t report;
|
|
||||||
char board_num[8];
|
|
||||||
uint8_t endcode; // Always 0xFF
|
|
||||||
uint8_t fw_ver;
|
|
||||||
};
|
|
@ -1,194 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "board/led15070-frame.h"
|
|
||||||
|
|
||||||
#include "hook/iobuf.h"
|
|
||||||
|
|
||||||
static void led15070_frame_sync(struct iobuf *src);
|
|
||||||
static HRESULT led15070_frame_accept(const struct iobuf *dest);
|
|
||||||
static HRESULT led15070_frame_encode_byte(struct iobuf *dest, uint8_t byte);
|
|
||||||
|
|
||||||
/* Frame structure:
|
|
||||||
|
|
||||||
[0] Sync byte (0xE0)
|
|
||||||
[1] Destination address
|
|
||||||
[2] Source Address
|
|
||||||
[3] Length of data/payload
|
|
||||||
[4] Data/payload
|
|
||||||
For requests (host to board):
|
|
||||||
[0] Command
|
|
||||||
... Payload
|
|
||||||
For responses (board to host):
|
|
||||||
[0] Status
|
|
||||||
[1] Command
|
|
||||||
[2] Report
|
|
||||||
... Payload
|
|
||||||
[n] Checksum: Sum of all prior bytes (excluding sync byte)
|
|
||||||
|
|
||||||
Byte stuffing:
|
|
||||||
|
|
||||||
0xD0 is an escape byte. Un-escape the subsequent byte by adding 1. */
|
|
||||||
|
|
||||||
static void led15070_frame_sync(struct iobuf *src)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0 ; i < src->pos && src->bytes[i] != 0xE0 ; i++);
|
|
||||||
|
|
||||||
src->pos -= i;
|
|
||||||
memmove(&src->bytes[0], &src->bytes[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT led15070_frame_accept(const struct iobuf *dest)
|
|
||||||
{
|
|
||||||
uint8_t checksum;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (dest->pos < 3 || dest->pos != dest->bytes[3] + 5) {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
checksum = 0;
|
|
||||||
|
|
||||||
for (i = 1 ; i < dest->pos - 1 ; i++) {
|
|
||||||
checksum += dest->bytes[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//dprintf("LED checksum %02x, expected %02x\n", checksum, dest->bytes[dest->pos - 1]);
|
|
||||||
|
|
||||||
if (checksum != dest->bytes[dest->pos - 1]) {
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_CRC);
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT led15070_frame_decode(struct iobuf *dest, struct iobuf *src)
|
|
||||||
{
|
|
||||||
uint8_t byte;
|
|
||||||
bool escape;
|
|
||||||
size_t i;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
assert(dest != NULL);
|
|
||||||
assert(dest->bytes != NULL || dest->nbytes == 0);
|
|
||||||
assert(dest->pos <= dest->nbytes);
|
|
||||||
assert(src != NULL);
|
|
||||||
assert(src->bytes != NULL || src->nbytes == 0);
|
|
||||||
assert(src->pos <= src->nbytes);
|
|
||||||
|
|
||||||
led15070_frame_sync(src);
|
|
||||||
|
|
||||||
dest->pos = 0;
|
|
||||||
escape = false;
|
|
||||||
|
|
||||||
for (i = 0, hr = S_FALSE ; i < src->pos && hr == S_FALSE ; i++) {
|
|
||||||
/* Step the FSM to unstuff another byte */
|
|
||||||
|
|
||||||
byte = src->bytes[i];
|
|
||||||
|
|
||||||
if (dest->pos >= dest->nbytes) {
|
|
||||||
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
|
||||||
} else if (i == 0) {
|
|
||||||
dest->bytes[dest->pos++] = byte;
|
|
||||||
} else if (byte == 0xE0) {
|
|
||||||
hr = E_FAIL;
|
|
||||||
} else if (byte == 0xD0) {
|
|
||||||
if (escape) {
|
|
||||||
hr = E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
escape = true;
|
|
||||||
} else if (escape) {
|
|
||||||
dest->bytes[dest->pos++] = byte + 1;
|
|
||||||
escape = false;
|
|
||||||
} else {
|
|
||||||
dest->bytes[dest->pos++] = byte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to accept the packet we've built up so far */
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = led15070_frame_accept(dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle FSM terminal state */
|
|
||||||
|
|
||||||
if (hr != S_FALSE) {
|
|
||||||
/* Frame was either accepted or rejected, remove it from src */
|
|
||||||
memmove(&src->bytes[0], &src->bytes[i], src->pos - i);
|
|
||||||
src->pos -= i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT led15070_frame_encode(
|
|
||||||
struct iobuf *dest,
|
|
||||||
const void *ptr,
|
|
||||||
size_t nbytes)
|
|
||||||
{
|
|
||||||
const uint8_t *src;
|
|
||||||
uint8_t checksum;
|
|
||||||
uint8_t byte;
|
|
||||||
size_t i;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
assert(dest != NULL);
|
|
||||||
assert(dest->bytes != NULL || dest->nbytes == 0);
|
|
||||||
assert(dest->pos <= dest->nbytes);
|
|
||||||
assert(ptr != NULL);
|
|
||||||
|
|
||||||
src = ptr;
|
|
||||||
|
|
||||||
assert(nbytes >= 3 && src[0] == 0xE0 && src[3] + 4 == nbytes);
|
|
||||||
|
|
||||||
if (dest->pos >= dest->nbytes) {
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
dest->bytes[dest->pos++] = 0xE0;
|
|
||||||
checksum = 0;
|
|
||||||
// dprintf("%02x ", 0xe0);
|
|
||||||
|
|
||||||
for (i = 1 ; i < nbytes ; i++) {
|
|
||||||
byte = src[i];
|
|
||||||
checksum += byte;
|
|
||||||
// dprintf("%02x ", byte);
|
|
||||||
|
|
||||||
hr = led15070_frame_encode_byte(dest, byte);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// dprintf("%02x \n", checksum);
|
|
||||||
|
|
||||||
return led15070_frame_encode_byte(dest, checksum);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT led15070_frame_encode_byte(struct iobuf *dest, uint8_t byte)
|
|
||||||
{
|
|
||||||
if (byte == 0xE0 || byte == 0xD0) {
|
|
||||||
if (dest->pos + 2 > dest->nbytes) {
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
dest->bytes[dest->pos++] = 0xD0;
|
|
||||||
dest->bytes[dest->pos++] = byte - 1;
|
|
||||||
} else {
|
|
||||||
if (dest->pos + 1 > dest->nbytes) {
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
dest->bytes[dest->pos++] = byte;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "hook/iobuf.h"
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LED_15070_FRAME_SYNC = 0xE0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct led15070_hdr {
|
|
||||||
uint8_t sync;
|
|
||||||
uint8_t dest_adr;
|
|
||||||
uint8_t src_adr;
|
|
||||||
uint8_t nbytes;
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT led15070_frame_decode(struct iobuf *dest, struct iobuf *src);
|
|
||||||
|
|
||||||
HRESULT led15070_frame_encode(
|
|
||||||
struct iobuf *dest,
|
|
||||||
const void *ptr,
|
|
||||||
size_t nbytes);
|
|
1250
board/led15070.c
1250
board/led15070.c
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct led15070_config {
|
|
||||||
bool enable;
|
|
||||||
unsigned int port_no;
|
|
||||||
char board_number[8];
|
|
||||||
uint8_t fw_ver;
|
|
||||||
uint16_t fw_sum;
|
|
||||||
wchar_t eeprom_path[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef HRESULT (*io_led_init_t)(void);
|
|
||||||
typedef void (*io_led_set_fet_output_t)(const uint8_t *rgb);
|
|
||||||
typedef void (*io_led_dc_update_t)(const uint8_t *rgb);
|
|
||||||
typedef void (*io_led_gs_update_t)(const uint8_t *rgb);
|
|
||||||
|
|
||||||
HRESULT led15070_hook_init(
|
|
||||||
const struct led15070_config *cfg,
|
|
||||||
io_led_init_t _led_init,
|
|
||||||
io_led_set_fet_output_t _led_set_fet_output,
|
|
||||||
io_led_dc_update_t _led_dc_update,
|
|
||||||
io_led_gs_update_t _led_gs_update,
|
|
||||||
unsigned int first_port,
|
|
||||||
unsigned int num_boards);
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
SEGA 837-15093-XX LED Controller Board emulator
|
SEGA 837-15093-XX LED Controller Board emulator
|
||||||
|
|
||||||
Supported variants:
|
Supported variants:
|
||||||
|
|
||||||
837-15093
|
837-15093
|
||||||
@ -106,7 +106,7 @@ static uint8_t led15093_host_adr = 1;
|
|||||||
static io_led_init_t led_init;
|
static io_led_init_t led_init;
|
||||||
static io_led_set_leds_t set_leds;
|
static io_led_set_leds_t set_leds;
|
||||||
|
|
||||||
HRESULT led15093_hook_init(const struct led15093_config *cfg, io_led_init_t _led_init,
|
HRESULT led15093_hook_init(const struct led15093_config *cfg, io_led_init_t _led_init,
|
||||||
io_led_set_leds_t _set_leds, unsigned int first_port, unsigned int num_boards, uint8_t board_adr, uint8_t host_adr)
|
io_led_set_leds_t _set_leds, unsigned int first_port, unsigned int num_boards, uint8_t board_adr, uint8_t host_adr)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -236,12 +236,12 @@ static HRESULT led15093_handle_irp_locked(int board, struct irp *irp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (irp->op == IRP_OP_OPEN) {
|
if (irp->op == IRP_OP_OPEN) {
|
||||||
dprintf("LED 15093: Starting backend DLL\n");
|
dprintf("LED 15093: Starting backend DLL\n");
|
||||||
// int res = led_init();
|
// int res = led_init();
|
||||||
hr = led_init();
|
hr = led_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
dprintf("LED 15093: Backend error, LED board disconnected: "
|
dprintf("LED 15093: Backend error, LED board disconnected: "
|
||||||
@ -267,7 +267,7 @@ static HRESULT led15093_handle_irp_locked(int board, struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(LOG_LED15093)
|
#if 0
|
||||||
dprintf("TX Buffer:\n");
|
dprintf("TX Buffer:\n");
|
||||||
dump_iobuf(&boarduart->written);
|
dump_iobuf(&boarduart->written);
|
||||||
#endif
|
#endif
|
||||||
@ -294,7 +294,7 @@ static HRESULT led15093_handle_irp_locked(int board, struct irp *irp)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(LOG_LED15093)
|
#if 0
|
||||||
dprintf("Deframe Buffer:\n");
|
dprintf("Deframe Buffer:\n");
|
||||||
dump_iobuf(&req_iobuf);
|
dump_iobuf(&req_iobuf);
|
||||||
#endif
|
#endif
|
||||||
@ -717,7 +717,7 @@ static HRESULT led15093_req_set_imm_led(int board, const struct led15093_req_set
|
|||||||
resp.status = v->status_code;
|
resp.status = v->status_code;
|
||||||
if (req->cmd == LED_15093_CMD_SET_IMM_LED) {
|
if (req->cmd == LED_15093_CMD_SET_IMM_LED) {
|
||||||
resp.cmd = LED_15093_CMD_SET_IMM_LED;
|
resp.cmd = LED_15093_CMD_SET_IMM_LED;
|
||||||
}
|
}
|
||||||
// else {
|
// else {
|
||||||
// resp.cmd = LED_15093_CMD_SET_IMM_LED_LEGACY;
|
// resp.cmd = LED_15093_CMD_SET_IMM_LED_LEGACY;
|
||||||
// }
|
// }
|
||||||
|
@ -25,11 +25,6 @@ board_lib = static_library(
|
|||||||
'led15093-frame.h',
|
'led15093-frame.h',
|
||||||
'led15093.c',
|
'led15093.c',
|
||||||
'led15093.h',
|
'led15093.h',
|
||||||
'led15070-cmd.h',
|
|
||||||
'led15070-frame.c',
|
|
||||||
'led15070-frame.h',
|
|
||||||
'led15070.c',
|
|
||||||
'led15070.h',
|
|
||||||
'sg-cmd.c',
|
'sg-cmd.c',
|
||||||
'sg-cmd.h',
|
'sg-cmd.h',
|
||||||
'sg-frame.c',
|
'sg-frame.c',
|
||||||
|
@ -25,13 +25,6 @@ struct sg_res_header {
|
|||||||
uint8_t payload_len;
|
uint8_t payload_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct to save the version string with its length
|
|
||||||
to fix NUL terminator issues */
|
|
||||||
struct version_info {
|
|
||||||
const char *version;
|
|
||||||
uint8_t length;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef HRESULT (*sg_dispatch_fn_t)(
|
typedef HRESULT (*sg_dispatch_fn_t)(
|
||||||
void *ctx,
|
void *ctx,
|
||||||
const void *req,
|
const void *req,
|
||||||
|
@ -27,11 +27,11 @@ static HRESULT sg_led_cmd_set_color(
|
|||||||
const struct sg_led *led,
|
const struct sg_led *led,
|
||||||
const struct sg_led_req_set_color *req);
|
const struct sg_led_req_set_color *req);
|
||||||
|
|
||||||
static const struct version_info led_version[] = {
|
const char *sg_led_info[] = {
|
||||||
{"15084\xFF\x10\x00\x12", 9},
|
"15084\xFF\x10\x00\x12",
|
||||||
{"000-00000\xFF\x11\x40", 12},
|
"000-00000\xFF\x11\x40",
|
||||||
// maybe the same?
|
// maybe the same?
|
||||||
{"000-00000\xFF\x11\x40", 12}
|
"000-00000\xFF\x11\x40"
|
||||||
};
|
};
|
||||||
|
|
||||||
void sg_led_init(
|
void sg_led_init(
|
||||||
@ -156,10 +156,10 @@ static HRESULT sg_led_cmd_get_info(
|
|||||||
{
|
{
|
||||||
sg_led_dprintf(led, "Get info\n");
|
sg_led_dprintf(led, "Get info\n");
|
||||||
|
|
||||||
const struct version_info *fw = &led_version[led->gen - 1];
|
unsigned int len = strlen(sg_led_info[led->gen - 1]);
|
||||||
|
|
||||||
sg_res_init(&res->res, req, fw->length);
|
sg_res_init(&res->res, req, len);
|
||||||
memcpy(res->payload, fw->version, fw->length);
|
memcpy(res->payload, sg_led_info[led->gen - 1], len);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -65,16 +65,16 @@ static HRESULT sg_nfc_cmd_dummy(
|
|||||||
const struct sg_req_header *req,
|
const struct sg_req_header *req,
|
||||||
struct sg_res_header *res);
|
struct sg_res_header *res);
|
||||||
|
|
||||||
static const struct version_info hw_version[] = {
|
static const char *hw_version[] = {
|
||||||
{"TN32MSEC003S H/W Ver3.0", 23},
|
"TN32MSEC003S H/W Ver3.0",
|
||||||
{"837-15286", 9},
|
"837-15286",
|
||||||
{"837-15396", 9}
|
"837-15396"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct version_info fw_version[] = {
|
static const char *fw_version[] = {
|
||||||
{"TN32MSEC003S F/W Ver1.2", 23},
|
"TN32MSEC003S F/W Ver1.2",
|
||||||
{"\x94", 1},
|
"\x94",
|
||||||
{"\x94", 1}
|
"\x94"
|
||||||
};
|
};
|
||||||
|
|
||||||
void sg_nfc_init(
|
void sg_nfc_init(
|
||||||
@ -217,11 +217,11 @@ static HRESULT sg_nfc_cmd_get_fw_version(
|
|||||||
const struct sg_req_header *req,
|
const struct sg_req_header *req,
|
||||||
struct sg_nfc_res_get_fw_version *res)
|
struct sg_nfc_res_get_fw_version *res)
|
||||||
{
|
{
|
||||||
const struct version_info *fw = &fw_version[nfc->gen - 1];
|
unsigned int len = strlen(fw_version[nfc->gen - 1]);
|
||||||
|
|
||||||
/* Dest version is not NUL terminated, this is intentional */
|
/* Dest version is not NUL terminated, this is intentional */
|
||||||
sg_res_init(&res->res, req, fw->length);
|
sg_res_init(&res->res, req, len);
|
||||||
memcpy(res->version, fw->version, fw->length);
|
memcpy(res->version, fw_version[nfc->gen - 1], len);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@ -231,11 +231,11 @@ static HRESULT sg_nfc_cmd_get_hw_version(
|
|||||||
const struct sg_req_header *req,
|
const struct sg_req_header *req,
|
||||||
struct sg_nfc_res_get_hw_version *res)
|
struct sg_nfc_res_get_hw_version *res)
|
||||||
{
|
{
|
||||||
const struct version_info *hw = &hw_version[nfc->gen - 1];
|
unsigned int len = strlen(hw_version[nfc->gen - 1]);
|
||||||
|
|
||||||
/* Dest version is not NUL terminated, this is intentional */
|
/* Dest version is not NUL terminated, this is intentional */
|
||||||
sg_res_init(&res->res, req, hw->length);
|
sg_res_init(&res->res, req, len);
|
||||||
memcpy(res->version, hw->version, hw->length);
|
memcpy(res->version, hw_version[nfc->gen - 1], len);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@ -420,7 +420,7 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
|||||||
f_res.nbytes = sizeof(res->payload);
|
f_res.nbytes = sizeof(res->payload);
|
||||||
f_res.pos = 1;
|
f_res.pos = 1;
|
||||||
|
|
||||||
#if defined(LOG_NFC)
|
#if 0
|
||||||
dprintf("FELICA OUTBOUND:\n");
|
dprintf("FELICA OUTBOUND:\n");
|
||||||
dump_const_iobuf(&f_req);
|
dump_const_iobuf(&f_req);
|
||||||
#endif
|
#endif
|
||||||
@ -434,7 +434,7 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
|||||||
sg_res_init(&res->res, &req->req, f_res.pos);
|
sg_res_init(&res->res, &req->req, f_res.pos);
|
||||||
res->payload[0] = f_res.pos;
|
res->payload[0] = f_res.pos;
|
||||||
|
|
||||||
#if defined(LOG_NFC)
|
#if 0
|
||||||
dprintf("FELICA INBOUND:\n");
|
dprintf("FELICA INBOUND:\n");
|
||||||
dump_iobuf(&f_res);
|
dump_iobuf(&f_res);
|
||||||
#endif
|
#endif
|
||||||
|
@ -115,14 +115,14 @@ static HRESULT sg_reader_handle_irp_locked(struct irp *irp)
|
|||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
#if defined(LOG_NFC)
|
#if 0
|
||||||
if (irp->op == IRP_OP_WRITE) {
|
if (irp->op == IRP_OP_WRITE) {
|
||||||
dprintf("WRITE:\n");
|
dprintf("WRITE:\n");
|
||||||
dump_const_iobuf(&irp->write);
|
dump_const_iobuf(&irp->write);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LOG_NFC)
|
#if 0
|
||||||
if (irp->op == IRP_OP_READ) {
|
if (irp->op == IRP_OP_READ) {
|
||||||
dprintf("READ:\n");
|
dprintf("READ:\n");
|
||||||
dump_iobuf(&sg_reader_uart.readable);
|
dump_iobuf(&sg_reader_uart.readable);
|
||||||
|
58
board/vfd.c
58
board/vfd.c
@ -26,7 +26,6 @@ static HRESULT vfd_handle_irp(struct irp *irp);
|
|||||||
static struct uart vfd_uart;
|
static struct uart vfd_uart;
|
||||||
static uint8_t vfd_written[512];
|
static uint8_t vfd_written[512];
|
||||||
static uint8_t vfd_readable[512];
|
static uint8_t vfd_readable[512];
|
||||||
UINT codepage;
|
|
||||||
|
|
||||||
HRESULT vfd_hook_init(const struct vfd_config *cfg, unsigned int port_no)
|
HRESULT vfd_hook_init(const struct vfd_config *cfg, unsigned int port_no)
|
||||||
{
|
{
|
||||||
@ -42,7 +41,6 @@ HRESULT vfd_hook_init(const struct vfd_config *cfg, unsigned int port_no)
|
|||||||
vfd_uart.readable.bytes = vfd_readable;
|
vfd_uart.readable.bytes = vfd_readable;
|
||||||
vfd_uart.readable.nbytes = sizeof(vfd_readable);
|
vfd_uart.readable.nbytes = sizeof(vfd_readable);
|
||||||
|
|
||||||
codepage = GetACP();
|
|
||||||
dprintf("VFD: hook enabled.\n");
|
dprintf("VFD: hook enabled.\n");
|
||||||
|
|
||||||
return iohook_push_handler(vfd_handle_irp);
|
return iohook_push_handler(vfd_handle_irp);
|
||||||
@ -64,60 +62,8 @@ static HRESULT vfd_handle_irp(struct irp *irp)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t cmd = 0;
|
dprintf("VFD TX:\n");
|
||||||
uint8_t str_1[512];
|
dump_iobuf(&vfd_uart.written);
|
||||||
uint8_t str_2[512];
|
|
||||||
uint8_t str_1_len = 0;
|
|
||||||
uint8_t str_2_len = 0;
|
|
||||||
for (size_t i = 0; i < vfd_uart.written.pos; i++) {
|
|
||||||
if (vfd_uart.written.bytes[i] == 0x1B) {
|
|
||||||
i++;
|
|
||||||
cmd = vfd_uart.written.bytes[i];
|
|
||||||
if (cmd == 0x30) {
|
|
||||||
i += 3;
|
|
||||||
}
|
|
||||||
else if (cmd == 0x50) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (cmd == 0x30) {
|
|
||||||
str_1[str_1_len++] = vfd_uart.written.bytes[i];
|
|
||||||
}
|
|
||||||
else if (cmd == 0x50) {
|
|
||||||
str_2[str_2_len++] = vfd_uart.written.bytes[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str_1_len) {
|
|
||||||
str_1[str_1_len++] = '\0';
|
|
||||||
if (codepage != 932) {
|
|
||||||
WCHAR buffer[512];
|
|
||||||
MultiByteToWideChar(932, 0, (LPCSTR)str_1, str_1_len, buffer, str_1_len);
|
|
||||||
char str_recode[str_1_len * 3];
|
|
||||||
WideCharToMultiByte(codepage, 0, buffer, str_1_len, str_recode, str_1_len * 3, NULL, NULL);
|
|
||||||
dprintf("VFD: %s\n", str_recode);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dprintf("VFD: %s\n", str_1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str_2_len) {
|
|
||||||
str_2[str_2_len++] = '\0';
|
|
||||||
if (codepage != 932) {
|
|
||||||
WCHAR buffer[512];
|
|
||||||
MultiByteToWideChar(932, 0, (LPCSTR)str_2, str_2_len, buffer, str_2_len);
|
|
||||||
char str_recode[str_2_len * 3];
|
|
||||||
WideCharToMultiByte(codepage, 0, buffer, str_2_len, str_recode, str_2_len * 3, NULL, NULL);
|
|
||||||
dprintf("VFD: %s\n", str_recode);
|
|
||||||
} else {
|
|
||||||
dprintf("VFD: %s\n", str_2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dprintf("VFD TX:\n");
|
|
||||||
// dump_iobuf(&vfd_uart.written);
|
|
||||||
vfd_uart.written.pos = 0;
|
vfd_uart.written.pos = 0;
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -78,7 +78,7 @@ static HRESULT controlbd_frame_decode(struct controlbd_req_any *req, struct iobu
|
|||||||
uint8_t checksum_pos = src->pos - 1;
|
uint8_t checksum_pos = src->pos - 1;
|
||||||
uint8_t calculated_checksum = 0;
|
uint8_t calculated_checksum = 0;
|
||||||
uint8_t checksum = 0;
|
uint8_t checksum = 0;
|
||||||
|
|
||||||
if (src->pos < 6) {
|
if (src->pos < 6) {
|
||||||
dprintf("Control Board: Decode Error, request too short (pos is 0x%08X)\n", (int)src->pos);
|
dprintf("Control Board: Decode Error, request too short (pos is 0x%08X)\n", (int)src->pos);
|
||||||
return SEC_E_BUFFER_TOO_SMALL;
|
return SEC_E_BUFFER_TOO_SMALL;
|
||||||
@ -137,7 +137,7 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (controlbd_uart.written.bytes[0] == 0xE0) {
|
if (controlbd_uart.written.bytes[0] == 0xE0) {
|
||||||
#if defined(LOG_CAROL_CONTROL_BD)
|
#if 0
|
||||||
dprintf("Control Board: TX Buffer:\n");
|
dprintf("Control Board: TX Buffer:\n");
|
||||||
dump_iobuf(&controlbd_uart.written);
|
dump_iobuf(&controlbd_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -147,12 +147,12 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = controlbd_req_dispatch(&req);
|
hr = controlbd_req_dispatch(&req);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dprintf("Control Board: Dispatch Error: 0X%X\n", (int) hr);
|
dprintf("Control Board: Dispatch Error: 0X%X\n", (int) hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
#if defined(LOG_CAROL_CONTROL_BD)
|
#if 0
|
||||||
dprintf("Control Board: RX Buffer:\n");
|
dprintf("Control Board: RX Buffer:\n");
|
||||||
dump_iobuf(&controlbd_uart.readable);
|
dump_iobuf(&controlbd_uart.readable);
|
||||||
#endif
|
#endif
|
||||||
@ -206,7 +206,7 @@ static HRESULT controlbd_req_dispatch(const struct controlbd_req_any *req)
|
|||||||
case CONTROLBD_CMD_FIRM_SUM:
|
case CONTROLBD_CMD_FIRM_SUM:
|
||||||
return controlbd_req_firmware_checksum();
|
return controlbd_req_firmware_checksum();
|
||||||
|
|
||||||
case CONTROLBD_CMD_TIMEOUT:
|
case CONTROLBD_CMD_TIMEOUT:
|
||||||
dprintf("Control Board: Acknowledge Timeout\n");
|
dprintf("Control Board: Acknowledge Timeout\n");
|
||||||
return controlbd_req_ack_any(req->hdr.cmd);
|
return controlbd_req_ack_any(req->hdr.cmd);
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ static HRESULT controlbd_req_get_board_info(void)
|
|||||||
resp.rev = 0x90;
|
resp.rev = 0x90;
|
||||||
resp.bfr_size = 0x0001;
|
resp.bfr_size = 0x0001;
|
||||||
resp.ack = 1;
|
resp.ack = 1;
|
||||||
|
|
||||||
strcpy_s(resp.bd_no, sizeof(resp.bd_no), "15312 ");
|
strcpy_s(resp.bd_no, sizeof(resp.bd_no), "15312 ");
|
||||||
strcpy_s(resp.chip_no, sizeof(resp.chip_no), "6699 ");
|
strcpy_s(resp.chip_no, sizeof(resp.chip_no), "6699 ");
|
||||||
resp.chip_no[5] = 0xFF;
|
resp.chip_no[5] = 0xFF;
|
||||||
@ -317,7 +317,7 @@ static HRESULT controlbd_req_polling(const struct controlbd_req_any *req)
|
|||||||
resp.unk7 = 3;
|
resp.unk7 = 3;
|
||||||
resp.unk8 = 1;
|
resp.unk8 = 1;
|
||||||
resp.unk9 = 1;
|
resp.unk9 = 1;
|
||||||
|
|
||||||
resp.btns_pressed = 0; // bit 1 is pen button, bit 2 is dodge
|
resp.btns_pressed = 0; // bit 1 is pen button, bit 2 is dodge
|
||||||
resp.coord_x = 0x0;
|
resp.coord_x = 0x0;
|
||||||
resp.coord_y = 0x0;
|
resp.coord_y = 0x0;
|
||||||
|
@ -1,31 +1,3 @@
|
|||||||
/*
|
|
||||||
"Wonderland Wars" (carol*) hook
|
|
||||||
|
|
||||||
Devices:
|
|
||||||
|
|
||||||
JVS: 837-14572 "Type 3" I/O Board
|
|
||||||
|
|
||||||
[Satellite]
|
|
||||||
|
|
||||||
USB: "WinTouch" Controller Board
|
|
||||||
^ (DIPSW2 ON, Version 5.xx.xx or above)
|
|
||||||
COM1: 3M Touch Systems 78-0011-2353-4 Touch Controller Board
|
|
||||||
^ (DIPSW2 OFF)
|
|
||||||
COM10: TN32MSEC003S "Gen 1" Aime Reader
|
|
||||||
OR
|
|
||||||
837-15286 "Gen 2" Aime Reader
|
|
||||||
^ (Version 1.6x.xx or above)
|
|
||||||
COM11: 837-15070-02 LED Controller Board
|
|
||||||
COM12: 837-15312 Pen Controller I/O Board
|
|
||||||
|
|
||||||
[Terminal]
|
|
||||||
|
|
||||||
COM10: 837-15286 "Gen 2" Aime Reader
|
|
||||||
|
|
||||||
*: SEGA's abbreviation for Lewis Carroll, author of Alice's Adventures in
|
|
||||||
Wonderland.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -94,7 +94,7 @@ static HRESULT ledbd_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(LOG_CAROL_LED_BD)
|
#if 0
|
||||||
dprintf("LED Board: TX Buffer:\n");
|
dprintf("LED Board: TX Buffer:\n");
|
||||||
dump_iobuf(&ledbd_uart.written);
|
dump_iobuf(&ledbd_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -165,4 +165,4 @@ static HRESULT ledbd_req_unkF0(uint8_t cmd)
|
|||||||
iobuf_write(&ledbd_uart.readable, resp, 16);
|
iobuf_write(&ledbd_uart.readable, resp, 16);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
@ -54,7 +54,7 @@ HRESULT touch_hook_init(const struct touch_config *cfg)
|
|||||||
if (!cfg->enable) {
|
if (!cfg->enable) {
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeCriticalSection(&touch_lock);
|
InitializeCriticalSection(&touch_lock);
|
||||||
|
|
||||||
uart_init(&touch_uart, 1);
|
uart_init(&touch_uart, 1);
|
||||||
@ -112,7 +112,7 @@ static HRESULT touch_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(LOG_CAROL_TOUCH)
|
#if 0
|
||||||
dprintf("Touchscreen: TX Buffer:\n");
|
dprintf("Touchscreen: TX Buffer:\n");
|
||||||
dump_iobuf(&touch_uart.written);
|
dump_iobuf(&touch_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -188,7 +188,7 @@ static void touch_scan_auto(const bool is_pressed, const uint16_t mouse_x, const
|
|||||||
resp.touches[0].touch_id = 1;
|
resp.touches[0].touch_id = 1;
|
||||||
tmp_x = mouse_x & 0x7FFF;
|
tmp_x = mouse_x & 0x7FFF;
|
||||||
tmp_y = mouse_y & 0x7FFF;
|
tmp_y = mouse_y & 0x7FFF;
|
||||||
|
|
||||||
resp.touches[0].x1 = tmp_x & 0x7F;
|
resp.touches[0].x1 = tmp_x & 0x7F;
|
||||||
resp.touches[0].x2 = (tmp_x >> 7) & 0x7F;
|
resp.touches[0].x2 = (tmp_x >> 7) & 0x7F;
|
||||||
resp.touches[0].y1 = tmp_y & 0x7F;
|
resp.touches[0].y1 = tmp_y & 0x7F;
|
||||||
@ -201,7 +201,7 @@ static void touch_scan_auto(const bool is_pressed, const uint16_t mouse_x, const
|
|||||||
dprintf("Touch: Mouse down! x %02X %02X y: %02X %02X\n", resp.touches[0].x1, resp.touches[0].x2, resp.touches[0].y1, resp.touches[0].y2);
|
dprintf("Touch: Mouse down! x %02X %02X y: %02X %02X\n", resp.touches[0].x1, resp.touches[0].x2, resp.touches[0].y1, resp.touches[0].y2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
last_x1 = resp.touches[0].x1;
|
last_x1 = resp.touches[0].x1;
|
||||||
last_x2 = resp.touches[0].x2;
|
last_x2 = resp.touches[0].x2;
|
||||||
last_y1 = resp.touches[0].y1;
|
last_y1 = resp.touches[0].y1;
|
||||||
@ -220,7 +220,7 @@ static void touch_scan_auto(const bool is_pressed, const uint16_t mouse_x, const
|
|||||||
iobuf_write(&touch_uart.readable, &resp, sizeof(resp));
|
iobuf_write(&touch_uart.readable, &resp, sizeof(resp));
|
||||||
LeaveCriticalSection(&touch_lock);
|
LeaveCriticalSection(&touch_lock);
|
||||||
|
|
||||||
#if defined(LOG_CAROL_TOUCH)
|
#if 0
|
||||||
dprintf("Touch: RX Buffer: (pos %08x)\n", (uint32_t)touch_uart.readable.pos);
|
dprintf("Touch: RX Buffer: (pos %08x)\n", (uint32_t)touch_uart.readable.pos);
|
||||||
dump_iobuf(&touch_uart.readable);
|
dump_iobuf(&touch_uart.readable);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,15 +1,3 @@
|
|||||||
/*
|
|
||||||
"CHUNITHM" (chuni) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
JVS: 837-14572 "Type 3" I/O Board
|
|
||||||
COM1: 837-15330 Ground Slider
|
|
||||||
COM10: 837-15093-06 LED Controller Board
|
|
||||||
COM11: 837-15093-06 LED Controller Board
|
|
||||||
COM12: TN32MSEC003S "Gen 1" Aime Reader
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -98,7 +98,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(LOG_CHUNI_SLIDER)
|
#if 0
|
||||||
dprintf("TX Buffer:\n");
|
dprintf("TX Buffer:\n");
|
||||||
dump_iobuf(&slider_uart.written);
|
dump_iobuf(&slider_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -117,7 +117,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(LOG_CHUNI_SLIDER)
|
#if 0
|
||||||
dprintf("Deframe Buffer:\n");
|
dprintf("Deframe Buffer:\n");
|
||||||
dump_iobuf(&req_iobuf);
|
dump_iobuf(&req_iobuf);
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,10 +139,9 @@ void chuni_io_slider_start(chuni_io_slider_callback_t callback);
|
|||||||
void chuni_io_slider_stop(void);
|
void chuni_io_slider_stop(void);
|
||||||
|
|
||||||
/* Update the RGB lighting on the slider. A pointer to an array of 32 * 3 = 96
|
/* Update the RGB lighting on the slider. A pointer to an array of 32 * 3 = 96
|
||||||
bytes is supplied, organized in BRG format.
|
bytes is supplied. The illuminated areas on the touch slider are some
|
||||||
The first set of bytes is the right-most slider key, and from there the bytes
|
combination of rectangular regions and dividing lines between these regions
|
||||||
alternate between the dividers and the keys until the left-most key.
|
but the exact mapping of this lighting control buffer is still TBD.
|
||||||
There are 31 illuminated sections in total.
|
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
Minimum API version: 0x0100 */
|
||||||
|
|
||||||
@ -164,17 +163,9 @@ HRESULT chuni_io_led_init(void);
|
|||||||
Chunithm uses two chains/boards with WS2811 protocol (each logical led corresponds to 3 physical leds).
|
Chunithm uses two chains/boards with WS2811 protocol (each logical led corresponds to 3 physical leds).
|
||||||
board 0 is on the left side and board 1 on the right side of the cab
|
board 0 is on the left side and board 1 on the right side of the cab
|
||||||
|
|
||||||
Board 0 has 53 LEDs:
|
left side has 5*10 rgb values for the billboard, followed by 3 rgb values for the air tower
|
||||||
[0]-[49]: snakes through left half of billboard (first column starts at top)
|
right side has 6*10 rgb values for the billboard, followed by 3 rgb values for the air tower
|
||||||
[50]-[52]: left side partition LEDs
|
|
||||||
|
|
||||||
Board 1 has 63 LEDs:
|
|
||||||
[0]-[59]: right half of billboard (first column starts at bottom)
|
|
||||||
[60]-[62]: right side partition LEDs
|
|
||||||
|
|
||||||
Board 2 is the slider and has 31 LEDs:
|
|
||||||
[0]-[31]: slider LEDs right to left BRG, alternating between keys and dividers
|
|
||||||
|
|
||||||
Each rgb value is comprised of 3 bytes in R,G,B order
|
Each rgb value is comprised of 3 bytes in R,G,B order
|
||||||
|
|
||||||
NOTE: billboard strips have alternating direction (bottom to top, top to bottom, ...)
|
NOTE: billboard strips have alternating direction (bottom to top, top to bottom, ...)
|
||||||
|
@ -57,13 +57,11 @@ void chuni_io_config_load(
|
|||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg->cab_led_output_pipe = GetPrivateProfileIntW(L"led", L"cabLedOutputPipe", 1, filename);
|
cfg->led_output_pipe = GetPrivateProfileIntW(L"led", L"cabLedOutputPipe", 1, filename);
|
||||||
cfg->cab_led_output_serial = GetPrivateProfileIntW(L"led", L"cabLedOutputSerial", 0, filename);
|
cfg->led_output_serial = GetPrivateProfileIntW(L"led", L"cabLedOutputSerial", 0, filename);
|
||||||
|
|
||||||
cfg->controller_led_output_pipe = GetPrivateProfileIntW(L"led", L"controllerLedOutputPipe", 1, filename);
|
cfg->slider_led_output_pipe = GetPrivateProfileIntW(L"led", L"controllerLedOutputPipe", 1, filename);
|
||||||
cfg->controller_led_output_serial = GetPrivateProfileIntW(L"led", L"controllerLedOutputSerial", 0, filename);
|
cfg->slider_led_output_serial = GetPrivateProfileIntW(L"led", L"controllerLedOutputSerial", 0, filename);
|
||||||
|
|
||||||
cfg->controller_led_output_openithm = GetPrivateProfileIntW(L"led", L"controllerLedOutputOpeNITHM", 0, filename);
|
|
||||||
|
|
||||||
cfg->led_serial_baud = GetPrivateProfileIntW(L"led", L"serialBaud", 921600, filename);
|
cfg->led_serial_baud = GetPrivateProfileIntW(L"led", L"serialBaud", 921600, filename);
|
||||||
|
|
||||||
@ -72,7 +70,7 @@ void chuni_io_config_load(
|
|||||||
L"serialPort",
|
L"serialPort",
|
||||||
L"COM5",
|
L"COM5",
|
||||||
port_input,
|
port_input,
|
||||||
_countof(port_input),
|
6,
|
||||||
filename);
|
filename);
|
||||||
|
|
||||||
// Sanitize the output path. If it's a serial COM port, it needs to be prefixed
|
// Sanitize the output path. If it's a serial COM port, it needs to be prefixed
|
||||||
|
@ -12,17 +12,16 @@ struct chuni_io_config {
|
|||||||
uint8_t vk_cell[32];
|
uint8_t vk_cell[32];
|
||||||
|
|
||||||
// Which ways to output LED information are enabled
|
// Which ways to output LED information are enabled
|
||||||
bool cab_led_output_pipe;
|
bool led_output_pipe;
|
||||||
bool cab_led_output_serial;
|
bool led_output_serial;
|
||||||
|
|
||||||
bool controller_led_output_pipe;
|
bool slider_led_output_pipe;
|
||||||
bool controller_led_output_serial;
|
bool slider_led_output_serial;
|
||||||
|
|
||||||
bool controller_led_output_openithm;
|
|
||||||
|
|
||||||
// The name of a COM port to output LED data on, in serial mode
|
// The name of a COM port to output LED data on, in serial mode
|
||||||
wchar_t led_serial_port[12];
|
wchar_t led_serial_port[12];
|
||||||
int32_t led_serial_baud;
|
int32_t led_serial_baud;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void chuni_io_config_load(
|
void chuni_io_config_load(
|
||||||
|
@ -48,15 +48,15 @@ HRESULT led_output_init(struct chuni_io_config* const cfg)
|
|||||||
led_escaped_buf[i].data_len = chuni_led_board_data_lens[i];
|
led_escaped_buf[i].data_len = chuni_led_board_data_lens[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
any_outputs_enabled = config->cab_led_output_pipe || config->controller_led_output_pipe
|
any_outputs_enabled = config->led_output_pipe || config->slider_led_output_pipe
|
||||||
|| config->cab_led_output_serial || config->controller_led_output_serial;
|
|| config->led_output_serial || config->slider_led_output_serial;
|
||||||
|
|
||||||
if (config->cab_led_output_pipe || config->controller_led_output_pipe)
|
if (config->led_output_pipe || config->slider_led_output_pipe)
|
||||||
{
|
{
|
||||||
led_pipe_init(); // don't really care about errors here tbh
|
led_pipe_init(); // don't really care about errors here tbh
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->cab_led_output_serial || config->controller_led_output_serial)
|
if (config->led_output_serial || config->slider_led_output_serial)
|
||||||
{
|
{
|
||||||
led_serial_init(config->led_serial_port, config->led_serial_baud);
|
led_serial_init(config->led_serial_port, config->led_serial_baud);
|
||||||
}
|
}
|
||||||
@ -106,13 +106,13 @@ void led_output_update(uint8_t board, const byte* rgb)
|
|||||||
|
|
||||||
if (board < 2)
|
if (board < 2)
|
||||||
{
|
{
|
||||||
// billboard (cab)
|
// billboard
|
||||||
if (config->cab_led_output_pipe)
|
if (config->led_output_pipe)
|
||||||
{
|
{
|
||||||
led_pipe_update(escaped_data);
|
led_pipe_update(escaped_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->cab_led_output_serial)
|
if (config->led_output_serial)
|
||||||
{
|
{
|
||||||
led_serial_update(escaped_data);
|
led_serial_update(escaped_data);
|
||||||
}
|
}
|
||||||
@ -120,18 +120,14 @@ void led_output_update(uint8_t board, const byte* rgb)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// slider
|
// slider
|
||||||
if (config->controller_led_output_pipe)
|
if (config->slider_led_output_pipe)
|
||||||
{
|
{
|
||||||
led_pipe_update(escaped_data);
|
led_pipe_update(escaped_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->controller_led_output_serial)
|
if (config->slider_led_output_serial)
|
||||||
{
|
{
|
||||||
if (config->controller_led_output_openithm){
|
led_serial_update(escaped_data);
|
||||||
led_serial_update_openithm(rgb);
|
|
||||||
} else {
|
|
||||||
led_serial_update(escaped_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ chuniio_lib = static_library(
|
|||||||
include_directories : inc,
|
include_directories : inc,
|
||||||
implicit_include_directories : false,
|
implicit_include_directories : false,
|
||||||
c_pch : '../precompiled.h',
|
c_pch : '../precompiled.h',
|
||||||
|
|
||||||
sources : [
|
sources : [
|
||||||
'chu2to3.c',
|
'chu2to3.c',
|
||||||
'chu2to3.h',
|
'chu2to3.h',
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
Credits:
|
Credits:
|
||||||
somewhatlurker, skogaby
|
somewhatlurker, skogaby
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -97,27 +97,3 @@ void led_serial_update(struct _chuni_led_data_buf_t* data)
|
|||||||
|
|
||||||
ReleaseMutex(serial_write_mutex);
|
ReleaseMutex(serial_write_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_serial_update_openithm(const byte* rgb)
|
|
||||||
{
|
|
||||||
if (serial_port != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
char led_buffer[100];
|
|
||||||
DWORD bytes_to_write; // No of bytes to write into the port
|
|
||||||
DWORD bytes_written = 0; // No of bytes written to the port
|
|
||||||
bytes_to_write = sizeof(led_buffer);
|
|
||||||
BOOL status;
|
|
||||||
|
|
||||||
led_buffer[0] = 0xAA;
|
|
||||||
led_buffer[1] = 0xAA;
|
|
||||||
memcpy(led_buffer+2, rgb, sizeof(uint8_t) * 96);
|
|
||||||
led_buffer[98] = 0xDD;
|
|
||||||
led_buffer[99] = 0xDD;
|
|
||||||
|
|
||||||
status = WriteFile(serial_port, // Handle to the Serial port
|
|
||||||
led_buffer, // Data to be written to the port
|
|
||||||
bytes_to_write, // No of bytes to write
|
|
||||||
&bytes_written, // Bytes written
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -13,4 +13,3 @@
|
|||||||
|
|
||||||
HRESULT led_serial_init(wchar_t led_com[12], DWORD baud);
|
HRESULT led_serial_init(wchar_t led_com[12], DWORD baud);
|
||||||
void led_serial_update(struct _chuni_led_data_buf_t* data);
|
void led_serial_update(struct _chuni_led_data_buf_t* data);
|
||||||
void led_serial_update_openithm(const byte* rgb);
|
|
@ -170,7 +170,7 @@ HRESULT chuni_dll_init(const struct chuni_dll_config *cfg, HINSTANCE self)
|
|||||||
"\"%s\". Please contact your IO DLL's developer for "
|
"\"%s\". Please contact your IO DLL's developer for "
|
||||||
"further assistance.\n",
|
"further assistance.\n",
|
||||||
sym->sym);
|
sym->sym);
|
||||||
dprintf("imported %d symbols\n", bind_count);
|
dprintf("imported %d symbols\n",bind_count);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,27 +1,3 @@
|
|||||||
/*
|
|
||||||
"CHUNITHM NEW" (chusan) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
USB: 837-15257-02 "Type 4" I/O Board
|
|
||||||
COM1: 837-15330 Ground Slider
|
|
||||||
|
|
||||||
[CVT mode (DIPSW2 ON)]
|
|
||||||
|
|
||||||
COM2: 837-15093-06 LED Controller Board
|
|
||||||
COM3: 837-15093-06 LED Controller Board
|
|
||||||
COM4: 837-15286 "Gen 2" Aime Reader
|
|
||||||
|
|
||||||
[SP mode (DIPSW2 OFF)]
|
|
||||||
|
|
||||||
USB: 837-15067-02 USB Serial I/F Board
|
|
||||||
connected to
|
|
||||||
837-15093-06 LED Controller Board (COM20)
|
|
||||||
837-15093-06 LED Controller Board (COM21)
|
|
||||||
COM2: 200-6275 VFD GP1232A02A FUTABA Board
|
|
||||||
COM4: 837-15396 "Gen 3" Aime Reader
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -123,7 +99,7 @@ static DWORD CALLBACK chusan_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool *dipsw = &chusan_hook_cfg.platform.system.dipsw[0];
|
bool *dipsw = &chusan_hook_cfg.platform.dipsw.dipsw[0];
|
||||||
bool is_cvt = dipsw[2];
|
bool is_cvt = dipsw[2];
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
|
@ -98,7 +98,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(LOG_CHUSAN_SLIDER)
|
#if 0
|
||||||
dprintf("TX Buffer:\n");
|
dprintf("TX Buffer:\n");
|
||||||
dump_iobuf(&slider_uart.written);
|
dump_iobuf(&slider_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -117,7 +117,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(LOG_CHUSAN_SLIDER)
|
#if 0
|
||||||
dprintf("Deframe Buffer:\n");
|
dprintf("Deframe Buffer:\n");
|
||||||
dump_iobuf(&req_iobuf);
|
dump_iobuf(&req_iobuf);
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,59 +15,3 @@ EXPORTS
|
|||||||
cm_io_get_opbtns
|
cm_io_get_opbtns
|
||||||
cm_io_init
|
cm_io_init
|
||||||
cm_io_poll
|
cm_io_poll
|
||||||
CFW_init
|
|
||||||
CFW_term
|
|
||||||
CFW_open
|
|
||||||
CFW_close
|
|
||||||
CFW_listupPrinter
|
|
||||||
CFW_listupPrinterSN
|
|
||||||
CFW_selectPrinter
|
|
||||||
CFW_selectPrinterSN
|
|
||||||
CFW_getPrinterInfo
|
|
||||||
CFW_status
|
|
||||||
CFW_statusAll
|
|
||||||
CFW_resetPrinter
|
|
||||||
CFW_updateFirmware
|
|
||||||
CFW_getFirmwareInfo
|
|
||||||
CHCUSB_init
|
|
||||||
CHCUSB_term
|
|
||||||
CHCUSB_MakeThread
|
|
||||||
CHCUSB_open
|
|
||||||
CHCUSB_close
|
|
||||||
CHCUSB_ReleaseThread
|
|
||||||
CHCUSB_listupPrinter
|
|
||||||
CHCUSB_listupPrinterSN
|
|
||||||
CHCUSB_selectPrinter
|
|
||||||
CHCUSB_selectPrinterSN
|
|
||||||
CHCUSB_getPrinterInfo
|
|
||||||
CHCUSB_imageformat
|
|
||||||
CHCUSB_setmtf
|
|
||||||
CHCUSB_makeGamma
|
|
||||||
CHCUSB_setIcctableProfile
|
|
||||||
CHCUSB_setIcctable
|
|
||||||
CHCUSB_copies
|
|
||||||
CHCUSB_status
|
|
||||||
CHCUSB_statusAll
|
|
||||||
CHCUSB_startpage
|
|
||||||
CHCUSB_endpage
|
|
||||||
CHCUSB_write
|
|
||||||
CHCUSB_writeLaminate
|
|
||||||
CHCUSB_writeHolo
|
|
||||||
CHCUSB_setPrinterInfo
|
|
||||||
CHCUSB_setPrinterToneCurve
|
|
||||||
CHCUSB_getGamma
|
|
||||||
CHCUSB_getMtf
|
|
||||||
CHCUSB_cancelCopies
|
|
||||||
CHCUSB_getPrinterToneCurve
|
|
||||||
CHCUSB_blinkLED
|
|
||||||
CHCUSB_resetPrinter
|
|
||||||
CHCUSB_AttachThreadCount
|
|
||||||
CHCUSB_getPrintIDStatus
|
|
||||||
CHCUSB_setPrintStandby
|
|
||||||
CHCUSB_testCardFeed
|
|
||||||
CHCUSB_exitCard
|
|
||||||
CHCUSB_getCardRfidTID
|
|
||||||
CHCUSB_commCardRfidReader
|
|
||||||
CHCUSB_updateCardRfidReader
|
|
||||||
CHCUSB_getErrorLog
|
|
||||||
CHCUSB_getErrorStatus
|
|
||||||
|
@ -39,7 +39,5 @@ void cm_hook_config_load(
|
|||||||
io4_config_load(&cfg->io4, filename);
|
io4_config_load(&cfg->io4, filename);
|
||||||
vfd_config_load(&cfg->vfd, filename);
|
vfd_config_load(&cfg->vfd, filename);
|
||||||
touch_screen_config_load(&cfg->touch, filename);
|
touch_screen_config_load(&cfg->touch, filename);
|
||||||
printer_config_load(&cfg->printer, filename);
|
|
||||||
cm_dll_config_load(&cfg->dll, filename);
|
cm_dll_config_load(&cfg->dll, filename);
|
||||||
unity_config_load(&cfg->unity, filename);
|
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,11 @@
|
|||||||
|
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
#include "hooklib/touch.h"
|
#include "hooklib/touch.h"
|
||||||
#include "hooklib/printer.h"
|
|
||||||
|
|
||||||
#include "cmhook/cm-dll.h"
|
#include "cmhook/cm-dll.h"
|
||||||
|
|
||||||
#include "platform/config.h"
|
#include "platform/config.h"
|
||||||
|
|
||||||
#include "unityhook/config.h"
|
|
||||||
|
|
||||||
struct cm_hook_config {
|
struct cm_hook_config {
|
||||||
struct platform_config platform;
|
struct platform_config platform;
|
||||||
struct aime_config aime;
|
struct aime_config aime;
|
||||||
@ -22,8 +19,6 @@ struct cm_hook_config {
|
|||||||
struct vfd_config vfd;
|
struct vfd_config vfd;
|
||||||
struct cm_dll_config dll;
|
struct cm_dll_config dll;
|
||||||
struct touch_screen_config touch;
|
struct touch_screen_config touch;
|
||||||
struct printer_config printer;
|
|
||||||
struct unity_config unity;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void cm_dll_config_load(
|
void cm_dll_config_load(
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
/*
|
|
||||||
"Card Maker" (cm) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
USB: 837-15257-01 "Type 4" I/O Board
|
|
||||||
USB: 838-20006 "WinTouch" Controller Board
|
|
||||||
USB: 630-00009 Sinfonia CHC-C310 Printer
|
|
||||||
COM1: 837-15396 "Gen 3" Aime Reader
|
|
||||||
COM2: 200-6275 VFD GP1232A02A FUTABA Board
|
|
||||||
COM3: 220-5872 AS-6DB Coin Selector
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -29,11 +16,10 @@
|
|||||||
#include "cmhook/config.h"
|
#include "cmhook/config.h"
|
||||||
#include "cmhook/io4.h"
|
#include "cmhook/io4.h"
|
||||||
#include "cmhook/cm-dll.h"
|
#include "cmhook/cm-dll.h"
|
||||||
|
#include "cmhook/unity.h"
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
#include "unityhook/hook.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
static HMODULE cm_hook_mod;
|
static HMODULE cm_hook_mod;
|
||||||
@ -56,10 +42,6 @@ static DWORD CALLBACK cm_pre_startup(void)
|
|||||||
touch_screen_hook_init(&cm_hook_cfg.touch, cm_hook_mod);
|
touch_screen_hook_init(&cm_hook_cfg.touch, cm_hook_mod);
|
||||||
serial_hook_init();
|
serial_hook_init();
|
||||||
|
|
||||||
/* Hook external DLL APIs */
|
|
||||||
|
|
||||||
printer_hook_init(&cm_hook_cfg.printer, 0, cm_hook_mod);
|
|
||||||
|
|
||||||
/* Initialize emulation hooks */
|
/* Initialize emulation hooks */
|
||||||
|
|
||||||
hr = platform_hook_init(
|
hr = platform_hook_init(
|
||||||
@ -72,12 +54,6 @@ static DWORD CALLBACK cm_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = cm_dll_init(&cm_hook_cfg.dll, cm_hook_mod);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = sg_reader_hook_init(&cm_hook_cfg.aime, 1, 1, cm_hook_mod);
|
hr = sg_reader_hook_init(&cm_hook_cfg.aime, 1, 1, cm_hook_mod);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@ -90,6 +66,12 @@ static DWORD CALLBACK cm_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr = cm_dll_init(&cm_hook_cfg.dll, cm_hook_mod);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
hr = cm_io4_hook_init(&cm_hook_cfg.io4);
|
hr = cm_io4_hook_init(&cm_hook_cfg.io4);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
@ -101,7 +83,7 @@ static DWORD CALLBACK cm_pre_startup(void)
|
|||||||
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
|
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
|
||||||
hooked earlier in the `cmhook` initialization. */
|
hooked earlier in the `cmhook` initialization. */
|
||||||
|
|
||||||
unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod);
|
unity_hook_init();
|
||||||
|
|
||||||
/* Initialize debug helpers */
|
/* Initialize debug helpers */
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ shared_library(
|
|||||||
hooklib_lib,
|
hooklib_lib,
|
||||||
cmio_lib,
|
cmio_lib,
|
||||||
platform_lib,
|
platform_lib,
|
||||||
unityhook_lib,
|
|
||||||
util_lib,
|
util_lib,
|
||||||
],
|
],
|
||||||
sources : [
|
sources : [
|
||||||
@ -27,5 +26,7 @@ shared_library(
|
|||||||
'io4.h',
|
'io4.h',
|
||||||
'cm-dll.c',
|
'cm-dll.c',
|
||||||
'cm-dll.h',
|
'cm-dll.h',
|
||||||
|
'unity.h',
|
||||||
|
'unity.c',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
95
cmhook/unity.c
Normal file
95
cmhook/unity.c
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "hooklib/dll.h"
|
||||||
|
#include "hooklib/path.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
static void dll_hook_insert_hooks(HMODULE target);
|
||||||
|
|
||||||
|
static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name);
|
||||||
|
static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name);
|
||||||
|
|
||||||
|
static const struct hook_symbol unity_kernel32_syms[] = {
|
||||||
|
{
|
||||||
|
.name = "LoadLibraryW",
|
||||||
|
.patch = my_LoadLibraryW,
|
||||||
|
.link = (void **) &next_LoadLibraryW,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const wchar_t *target_modules[] = {
|
||||||
|
L"mono.dll",
|
||||||
|
L"cri_ware_unity.dll",
|
||||||
|
};
|
||||||
|
static const size_t target_modules_len = _countof(target_modules);
|
||||||
|
|
||||||
|
void unity_hook_init(void)
|
||||||
|
{
|
||||||
|
dll_hook_insert_hooks(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dll_hook_insert_hooks(HMODULE target)
|
||||||
|
{
|
||||||
|
hook_table_apply(
|
||||||
|
target,
|
||||||
|
"kernel32.dll",
|
||||||
|
unity_kernel32_syms,
|
||||||
|
_countof(unity_kernel32_syms));
|
||||||
|
}
|
||||||
|
|
||||||
|
static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name)
|
||||||
|
{
|
||||||
|
const wchar_t *name_end;
|
||||||
|
const wchar_t *target_module;
|
||||||
|
bool already_loaded;
|
||||||
|
HMODULE result;
|
||||||
|
size_t name_len;
|
||||||
|
size_t target_module_len;
|
||||||
|
|
||||||
|
if (name == NULL) {
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the module is already loaded
|
||||||
|
already_loaded = GetModuleHandleW(name) != NULL;
|
||||||
|
|
||||||
|
// Must call the next handler so the DLL reference count is incremented
|
||||||
|
result = next_LoadLibraryW(name);
|
||||||
|
|
||||||
|
if (!already_loaded && result != NULL) {
|
||||||
|
name_len = wcslen(name);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < target_modules_len; i++) {
|
||||||
|
target_module = target_modules[i];
|
||||||
|
target_module_len = wcslen(target_module);
|
||||||
|
|
||||||
|
// Check if the newly loaded library is at least the length of
|
||||||
|
// the name of the target module
|
||||||
|
if (name_len < target_module_len) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
name_end = &name[name_len - target_module_len];
|
||||||
|
|
||||||
|
// Check if the name of the newly loaded library is one of the
|
||||||
|
// modules the path hooks should be injected into
|
||||||
|
if (_wcsicmp(name_end, target_module) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("Unity: Loaded %S\n", target_module);
|
||||||
|
|
||||||
|
dll_hook_insert_hooks(result);
|
||||||
|
path_hook_insert_hooks(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
3
cmhook/unity.h
Normal file
3
cmhook/unity.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void unity_hook_init(void);
|
@ -36,9 +36,9 @@ HRESULT cm_io_init(void);
|
|||||||
HRESULT cm_io_poll(void);
|
HRESULT cm_io_poll(void);
|
||||||
|
|
||||||
/* Get the state of the cabinet's operator buttons as of the last poll. See
|
/* Get the state of the cabinet's operator buttons as of the last poll. See
|
||||||
CM_IO_OPBTN enum above: this contains bit mask definitions for button
|
cm_IO_OPBTN enum above: this contains bit mask definitions for button
|
||||||
states returned in *opbtn. All buttons are active-high.
|
states returned in *opbtn. All buttons are active-high.
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
Minimum API version: 0x0100 */
|
||||||
|
|
||||||
void cm_io_get_opbtns(uint8_t *opbtn);
|
void cm_io_get_opbtns(uint8_t *opbtn);
|
@ -23,32 +23,22 @@ void cxb_dll_config_load(
|
|||||||
struct cxb_dll_config *cfg,
|
struct cxb_dll_config *cfg,
|
||||||
const wchar_t *filename)
|
const wchar_t *filename)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"cxbio",
|
|
||||||
L"path",
|
|
||||||
L"",
|
|
||||||
cfg->path,
|
|
||||||
_countof(cfg->path),
|
|
||||||
filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void revio_config_load(struct revio_config *cfg, const wchar_t *filename)
|
void revio_config_load(struct revio_config *cfg, const wchar_t *filename)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"revio", L"enable", 1, filename);
|
}
|
||||||
|
|
||||||
|
void network_config_load(struct network_config *cfg, const wchar_t *filename)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_config_load(struct led_config *cfg, const wchar_t *filename)
|
void led_config_load(struct led_config *cfg, const wchar_t *filename)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"led", L"enable", 1, filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cxb_hook_config_load(
|
void cxb_hook_config_load(
|
||||||
@ -66,5 +56,6 @@ void cxb_hook_config_load(
|
|||||||
gfx_config_load(&cfg->gfx, filename);
|
gfx_config_load(&cfg->gfx, filename);
|
||||||
cxb_dll_config_load(&cfg->dll, filename);
|
cxb_dll_config_load(&cfg->dll, filename);
|
||||||
revio_config_load(&cfg->revio, filename);
|
revio_config_load(&cfg->revio, filename);
|
||||||
|
network_config_load(&cfg->network, filename);
|
||||||
led_config_load(&cfg->led, filename);
|
led_config_load(&cfg->led, filename);
|
||||||
}
|
}
|
@ -10,6 +10,7 @@
|
|||||||
#include "cxbhook/cxb-dll.h"
|
#include "cxbhook/cxb-dll.h"
|
||||||
#include "cxbhook/revio.h"
|
#include "cxbhook/revio.h"
|
||||||
#include "cxbhook/led.h"
|
#include "cxbhook/led.h"
|
||||||
|
#include "cxbhook/network.h"
|
||||||
|
|
||||||
#include "gfxhook/gfx.h"
|
#include "gfxhook/gfx.h"
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ struct cxb_hook_config {
|
|||||||
struct gfx_config gfx;
|
struct gfx_config gfx;
|
||||||
struct cxb_dll_config dll;
|
struct cxb_dll_config dll;
|
||||||
struct revio_config revio;
|
struct revio_config revio;
|
||||||
|
struct network_config network;
|
||||||
struct led_config led;
|
struct led_config led;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,6 +32,7 @@ void cxb_dll_config_load(
|
|||||||
const wchar_t *filename);
|
const wchar_t *filename);
|
||||||
|
|
||||||
void revio_config_load(struct revio_config *cfg, const wchar_t *filename);
|
void revio_config_load(struct revio_config *cfg, const wchar_t *filename);
|
||||||
|
void network_config_load(struct network_config *cfg, const wchar_t *filename);
|
||||||
void led_config_load(struct led_config *cfg, const wchar_t *filename);
|
void led_config_load(struct led_config *cfg, const wchar_t *filename);
|
||||||
|
|
||||||
void cxb_hook_config_load(
|
void cxb_hook_config_load(
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "cxbhook/config.h"
|
#include "cxbhook/config.h"
|
||||||
#include "cxbhook/revio.h"
|
#include "cxbhook/revio.h"
|
||||||
#include "cxbhook/led.h"
|
#include "cxbhook/led.h"
|
||||||
|
#include "cxbhook/network.h"
|
||||||
|
|
||||||
#include "cxbio/cxbio.h"
|
#include "cxbio/cxbio.h"
|
||||||
|
|
||||||
@ -102,6 +103,12 @@ static DWORD CALLBACK cxb_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr = network_hook_init(&cxb_hook_cfg.network);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
hr = led_hook_init(&cxb_hook_cfg.led);
|
hr = led_hook_init(&cxb_hook_cfg.led);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "cxbhook/led.h"
|
#include "cxbhook/led.h"
|
||||||
#include "cxbhook/cxb-dll.h"
|
#include "cxbhook/cxb-dll.h"
|
||||||
|
|
||||||
#include "hook/procaddr.h"
|
#include "hooklib/procaddr.h"
|
||||||
|
|
||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
@ -49,14 +49,8 @@ static struct hook_symbol lamp_syms[] = {
|
|||||||
|
|
||||||
HRESULT led_hook_init(struct led_config *cfg)
|
HRESULT led_hook_init(struct led_config *cfg)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
dprintf("LED: Init\n");
|
||||||
|
return proc_addr_table_push("CommLamp.dll", lamp_syms, _countof(lamp_syms));
|
||||||
if (!cfg->enable) {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("LED: Hook enabled.\n");
|
|
||||||
return proc_addr_table_push(NULL, "CommLamp.dll", lamp_syms, _countof(lamp_syms));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int my_cCommLamp_Open(char *port)
|
static int my_cCommLamp_Open(char *port)
|
||||||
|
@ -30,5 +30,7 @@ shared_library(
|
|||||||
'revio.h',
|
'revio.h',
|
||||||
'led.c',
|
'led.c',
|
||||||
'led.h',
|
'led.h',
|
||||||
|
'network.c',
|
||||||
|
'network.h',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
13
cxbhook/network.c
Normal file
13
cxbhook/network.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "cxbhook/network.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
HRESULT network_hook_init(struct network_config *cfg)
|
||||||
|
{
|
||||||
|
dprintf("Network: Init\n");
|
||||||
|
return S_OK;
|
||||||
|
}
|
13
cxbhook/network.h
Normal file
13
cxbhook/network.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct network_config {
|
||||||
|
bool enable;
|
||||||
|
bool disable_ssl;
|
||||||
|
char title_server[PATH_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT network_hook_init(struct network_config *cfg);
|
@ -6,7 +6,7 @@
|
|||||||
#include "cxbhook/revio.h"
|
#include "cxbhook/revio.h"
|
||||||
#include "cxbhook/cxb-dll.h"
|
#include "cxbhook/cxb-dll.h"
|
||||||
|
|
||||||
#include "hook/procaddr.h"
|
#include "hooklib/procaddr.h"
|
||||||
|
|
||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
@ -82,14 +82,8 @@ static struct hook_symbol revio_syms[] = {
|
|||||||
|
|
||||||
HRESULT revio_hook_init(struct revio_config *cfg)
|
HRESULT revio_hook_init(struct revio_config *cfg)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
dprintf("Revio: Init\n");
|
||||||
|
return proc_addr_table_push("CommIo.dll", revio_syms, _countof(revio_syms));
|
||||||
if (!cfg->enable) {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("Revio: Hook enabled.\n");
|
|
||||||
return proc_addr_table_push(NULL, "CommIo.dll", revio_syms, _countof(revio_syms));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int my_cCommIo_Open(char *port)
|
static int my_cCommIo_Open(char *port)
|
||||||
@ -160,7 +154,7 @@ static int my_cCommIo_GetTrigger()
|
|||||||
|
|
||||||
out &= ~last_triggers;
|
out &= ~last_triggers;
|
||||||
|
|
||||||
// dprintf("Revio: GetTrigger %X\n", out);
|
dprintf("Revio: GetTrigger %X\n", out);
|
||||||
last_triggers = out;
|
last_triggers = out;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -194,7 +188,7 @@ static int my_cCommIo_GetRelease()
|
|||||||
|
|
||||||
out &= ~btns;
|
out &= ~btns;
|
||||||
|
|
||||||
// dprintf("Revio: GetRelease %X\n", out);
|
dprintf("Revio: GetRelease %X\n", out);
|
||||||
last_triggers = btns;
|
last_triggers = btns;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
32
dist/chuni/segatools.ini
vendored
32
dist/chuni/segatools.ini
vendored
@ -63,6 +63,20 @@ framed=1
|
|||||||
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
||||||
monitor=0
|
monitor=0
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; Custom IO settings
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[aimeio]
|
||||||
|
; To use a custom card reader IO DLL enter its path here.
|
||||||
|
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||||
|
path=
|
||||||
|
|
||||||
|
[chuniio]
|
||||||
|
; To use a custom Chunithm IO DLL enter its path here.
|
||||||
|
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||||
|
path=
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; LED settings
|
; LED settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
@ -82,12 +96,10 @@ cabLedOutputSerial=0
|
|||||||
controllerLedOutputPipe=1
|
controllerLedOutputPipe=1
|
||||||
; Output slider LED data to the serial port
|
; Output slider LED data to the serial port
|
||||||
controllerLedOutputSerial=0
|
controllerLedOutputSerial=0
|
||||||
; Use the OpeNITHM protocol for serial LED output
|
|
||||||
controllerLedOutputOpeNITHM=0
|
|
||||||
|
|
||||||
; Serial port to send data to if using serial output. Default is COM5.
|
; Serial port to send data to if using serial output. Default is COM5.
|
||||||
;serialPort=COM5
|
;serialPort=COM5
|
||||||
; Baud rate for serial data (set to 115200 if using OpeNITHM)
|
; Baud rate for serial data
|
||||||
;serialBaud=921600
|
;serialBaud=921600
|
||||||
|
|
||||||
; Data output a sequence of bytes, with JVS-like framing.
|
; Data output a sequence of bytes, with JVS-like framing.
|
||||||
@ -110,20 +122,6 @@ controllerLedOutputOpeNITHM=0
|
|||||||
; [0]-[31]: slider LEDs right to left BRG, alternating between keys and dividers
|
; [0]-[31]: slider LEDs right to left BRG, alternating between keys and dividers
|
||||||
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Custom IO settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aimeio]
|
|
||||||
; To use a custom card reader IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[chuniio]
|
|
||||||
; To use a custom Chunithm IO DLL enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Input settings
|
; Input settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
51
dist/chusan/segatools.ini
vendored
51
dist/chusan/segatools.ini
vendored
@ -43,7 +43,6 @@ default=127.0.0.1
|
|||||||
; Chunithm is extremely picky about its LAN environment, so leaving this
|
; Chunithm is extremely picky about its LAN environment, so leaving this
|
||||||
; setting enabled is strongly recommended.
|
; setting enabled is strongly recommended.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; The final octet of the local host's IP address on the virtualized subnet (so,
|
; The final octet of the local host's IP address on the virtualized subnet (so,
|
||||||
; if the keychip subnet is `192.168.32.0` and this value is set to `11`, then the
|
; if the keychip subnet is `192.168.32.0` and this value is set to `11`, then the
|
||||||
; local host's virtualized LAN IP is `192.168.32.11`).
|
; local host's virtualized LAN IP is `192.168.32.11`).
|
||||||
@ -59,8 +58,8 @@ addrSuffix=11
|
|||||||
; that subnet must start with 192.168.
|
; that subnet must start with 192.168.
|
||||||
subnet=192.168.139.0
|
subnet=192.168.139.0
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||||
@ -89,6 +88,25 @@ framed=0
|
|||||||
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
||||||
monitor=0
|
monitor=0
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
; Custom IO settings
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[aimeio]
|
||||||
|
; To use a custom card reader IO DLL (x64) enter its path here.
|
||||||
|
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||||
|
path=
|
||||||
|
|
||||||
|
[chuniio]
|
||||||
|
; Uncomment this if you have custom chuniio implementation comprised of a single 32bit DLL.
|
||||||
|
; (will use chu2to3 engine internally)
|
||||||
|
;path=
|
||||||
|
|
||||||
|
; Uncomment both of these if you have custom chuniio implementation comprised of two DLLs.
|
||||||
|
; x86 chuniio to path32, x64 to path64. Both are necessary.
|
||||||
|
;path32=
|
||||||
|
;path64=
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; LED settings
|
; LED settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
@ -108,12 +126,10 @@ cabLedOutputSerial=0
|
|||||||
controllerLedOutputPipe=1
|
controllerLedOutputPipe=1
|
||||||
; Output slider LED data to the serial port
|
; Output slider LED data to the serial port
|
||||||
controllerLedOutputSerial=0
|
controllerLedOutputSerial=0
|
||||||
; Use the OpeNITHM protocol for serial LED output
|
|
||||||
controllerLedOutputOpeNITHM=0
|
|
||||||
|
|
||||||
; Serial port to send data to if using serial output. Default is COM5.
|
; Serial port to send data to if using serial output. Default is COM5.
|
||||||
;serialPort=COM5
|
;serialPort=COM5
|
||||||
; Baud rate for serial data (set to 115200 if using OpeNITHM)
|
; Baud rate for serial data
|
||||||
;serialBaud=921600
|
;serialBaud=921600
|
||||||
|
|
||||||
; Data output a sequence of bytes, with JVS-like framing.
|
; Data output a sequence of bytes, with JVS-like framing.
|
||||||
@ -136,25 +152,6 @@ controllerLedOutputOpeNITHM=0
|
|||||||
; [0]-[31]: slider LEDs right to left BRG, alternating between keys and dividers
|
; [0]-[31]: slider LEDs right to left BRG, alternating between keys and dividers
|
||||||
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Custom IO settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[aimeio]
|
|
||||||
; To use a custom card reader IO DLL (x64) enter its path here.
|
|
||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
[chuniio]
|
|
||||||
; Uncomment this if you have custom chuniio implementation comprised of a single 32bit DLL.
|
|
||||||
; (will use chu2to3 engine internally)
|
|
||||||
;path=
|
|
||||||
|
|
||||||
; Uncomment both of these if you have custom chuniio implementation comprised of two DLLs.
|
|
||||||
; x86 chuniio to path32, x64 to path64. Both are necessary.
|
|
||||||
;path32=
|
|
||||||
;path64=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Input settings
|
; Input settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
@ -204,3 +201,7 @@ ir=0x20
|
|||||||
; ... etc ...
|
; ... etc ...
|
||||||
;cell31=0x53
|
;cell31=0x53
|
||||||
;cell32=0x53
|
;cell32=0x53
|
||||||
|
|
||||||
|
; Enable slider LED serial output. This follows OpeNITHM Serial LED Protocol.
|
||||||
|
; eg. COM5
|
||||||
|
;ledport=
|
||||||
|
19
dist/cm/segatools.ini
vendored
19
dist/cm/segatools.ini
vendored
@ -50,10 +50,10 @@ enable=1
|
|||||||
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
|
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
|
||||||
; If you disable netenv then you must set this to your LAN's IP subnet, and
|
; If you disable netenv then you must set this to your LAN's IP subnet, and
|
||||||
; that subnet must start with 192.168.
|
; that subnet must start with 192.168.
|
||||||
subnet=192.168.165.0
|
subnet=192.168.100.0
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; LAN Install: If multiple machines are present on the same LAN then set
|
; LAN Install: If multiple machines are present on the same LAN then set
|
||||||
@ -68,19 +68,6 @@ dipsw1=0
|
|||||||
; Enable/Disable WinTouch emulation
|
; Enable/Disable WinTouch emulation
|
||||||
enable=0
|
enable=0
|
||||||
|
|
||||||
[unity]
|
|
||||||
; Path to a .NET DLL that should run before the game. Useful for loading
|
|
||||||
; modding frameworks such as BepInEx.
|
|
||||||
targetAssembly=
|
|
||||||
|
|
||||||
[printer]
|
|
||||||
; Sinfonia CHC-C330 printer emulation setting.
|
|
||||||
enable=1
|
|
||||||
; Change the printer serial number here.
|
|
||||||
serial_no="5A-A123"
|
|
||||||
; Insert the path to the image output directory here.
|
|
||||||
printerOutPath="DEVICE\print"
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Custom IO settings
|
; Custom IO settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
11
dist/cxb/segatools.ini
vendored
11
dist/cxb/segatools.ini
vendored
@ -19,10 +19,10 @@ appdata=
|
|||||||
|
|
||||||
[aime]
|
[aime]
|
||||||
; Aime reader emulation
|
; Aime reader emulation
|
||||||
|
; CXB is stupid, so we have to make the paths go back one
|
||||||
enable=1
|
enable=1
|
||||||
; CXB is stupid, so we have to make the paths go back two directories. This
|
|
||||||
; will load the file from "resource\DEVICE\aime.txt".
|
|
||||||
aimePath=../DEVICE/aime.txt
|
aimePath=../DEVICE/aime.txt
|
||||||
|
felicaPath=../DEVICE/felica.txt
|
||||||
|
|
||||||
[led]
|
[led]
|
||||||
; Emulation for the LED board. Currently it's just dummy responses,
|
; Emulation for the LED board. Currently it's just dummy responses,
|
||||||
@ -39,10 +39,6 @@ enable=1
|
|||||||
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
||||||
default=127.0.0.1
|
default=127.0.0.1
|
||||||
|
|
||||||
; Set the title server hostname or IP address here, as the title server
|
|
||||||
; is hardcoded in the game.
|
|
||||||
title=https://127.0.0.1:9002
|
|
||||||
|
|
||||||
[netenv]
|
[netenv]
|
||||||
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
||||||
; Crossbeats is extremely picky about its LAN environment, so leaving this
|
; Crossbeats is extremely picky about its LAN environment, so leaving this
|
||||||
@ -110,14 +106,13 @@ path=
|
|||||||
|
|
||||||
[revio]
|
[revio]
|
||||||
; Enable emulation of the rev IO board
|
; Enable emulation of the rev IO board
|
||||||
enable=1
|
enabe=1
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
; Test button virtual-key code. Default is the F1 key.
|
||||||
test=0x70
|
test=0x70
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
; Service button virtual-key code. Default is the F2 key.
|
||||||
service=0x71
|
service=0x71
|
||||||
; Keyboard button to increment coin counter. Default is the F3 key.
|
; Keyboard button to increment coin counter. Default is the F3 key.
|
||||||
coin=0x72
|
coin=0x72
|
||||||
|
|
||||||
; Menu up key. Default is up arrow.
|
; Menu up key. Default is up arrow.
|
||||||
up=0x26
|
up=0x26
|
||||||
; Menu down key. Default is down arrow.
|
; Menu down key. Default is down arrow.
|
||||||
|
21
dist/fgo/segatools.ini
vendored
21
dist/fgo/segatools.ini
vendored
@ -72,8 +72,8 @@ addrSuffix=11
|
|||||||
; that subnet must start with 192.168.
|
; that subnet must start with 192.168.
|
||||||
subnet=192.168.167.0
|
subnet=192.168.167.0
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||||
@ -128,12 +128,13 @@ path=
|
|||||||
; world. An improved solution will be provided later.
|
; world. An improved solution will be provided later.
|
||||||
|
|
||||||
[io4]
|
[io4]
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
; Input API selection for JVS input emulator.
|
||||||
test=0x70
|
; Test button virtual-key code. Default is the 1 key.
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
test=0x31
|
||||||
service=0x71
|
; Service button virtual-key code. Default is the 2 key.
|
||||||
; Keyboard button to increment coin counter. Default is the F3 key.
|
service=0x32
|
||||||
coin=0x72
|
; Keyboard button to increment coin counter. Default is the 3 key.
|
||||||
|
coin=0x33
|
||||||
|
|
||||||
; .·:'''''''''''''''''''''''''''''''''''''''''''''':·.
|
; .·:'''''''''''''''''''''''''''''''''''''''''''''':·.
|
||||||
; : : ______ / \ [] : :
|
; : : ______ / \ [] : :
|
||||||
@ -150,8 +151,8 @@ coin=0x72
|
|||||||
;
|
;
|
||||||
; Only XInput is currently supported.
|
; Only XInput is currently supported.
|
||||||
|
|
||||||
; XInput bindings
|
; Controller Button
|
||||||
;
|
; -------------------------------------------------------
|
||||||
; Left Stick Joystick
|
; Left Stick Joystick
|
||||||
; Left Stick Click Reset Camera
|
; Left Stick Click Reset Camera
|
||||||
; Left Trigger Dash
|
; Left Trigger Dash
|
||||||
|
23
dist/idac/segatools.ini
vendored
23
dist/idac/segatools.ini
vendored
@ -54,8 +54,8 @@ subnet=192.168.158.0
|
|||||||
; 1: JPN: Japan, 4: EXP: Export (for Asian markets)
|
; 1: JPN: Japan, 4: EXP: Export (for Asian markets)
|
||||||
region=4
|
region=4
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||||
@ -75,25 +75,6 @@ dipsw3=0
|
|||||||
dipsw4=0
|
dipsw4=0
|
||||||
dipsw5=0
|
dipsw5=0
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; LED settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[led15070]
|
|
||||||
; Enable emulation of the 837-15070-02 controlled lights, which handle the
|
|
||||||
; cabinet and seat LEDs.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Misc. hooks settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[indrun]
|
|
||||||
; Hooks to patch GameProject-Win64-Shipping.exe and IndRun.dll. This is needed
|
|
||||||
; to boot version 1.60.00 and up. The hooks are not needed for version 1.50.00
|
|
||||||
; and below.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Custom IO settings
|
; Custom IO settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
25
dist/idac/start.bat
vendored
25
dist/idac/start.bat
vendored
@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
pushd %~dp0
|
pushd %~dp0
|
||||||
|
|
||||||
|
REM set the APP_DIR to the Y drive
|
||||||
|
set APP_DIR=Y:\SDGT
|
||||||
|
|
||||||
|
REM create the APP_DIR if it doesn't exist and redirect it to the TEMP folder
|
||||||
|
if not exist "%APP_DIR%" (
|
||||||
|
subst Y: %TEMP%
|
||||||
|
REM timeout /t 1
|
||||||
|
if not exist "%APP_DIR%" (
|
||||||
|
mkdir "%APP_DIR%"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
echo Mounted the Y:\ drive to the %TEMP%\SDGT folder
|
||||||
|
|
||||||
set AMDAEMON_CFG=config_common.json ^
|
set AMDAEMON_CFG=config_common.json ^
|
||||||
config_ex.json ^
|
config_ex.json ^
|
||||||
config_jp.json ^
|
config_jp.json ^
|
||||||
@ -26,15 +40,12 @@ config_seat_single_jp.json ^
|
|||||||
config_hook.json
|
config_hook.json
|
||||||
|
|
||||||
start "AM Daemon" /min inject -d -k idachook.dll amdaemon.exe -c %AMDAEMON_CFG%
|
start "AM Daemon" /min inject -d -k idachook.dll amdaemon.exe -c %AMDAEMON_CFG%
|
||||||
|
inject -d -k idachook.dll ..\WindowsNoEditor\GameProject.exe -culture=en launch=Cabinet ABSLOG="..\..\..\..\..\Userdata\GameProject.log" -Master -UserDir="..\..\..\Userdata" -NotInstalled -UNATTENDED
|
||||||
rem JP
|
|
||||||
rem inject -d -k idachook.dll ..\WindowsNoEditor\GameProject\Binaries\Win64\GameProject-Win64-Shipping.exe -culture=ja launch=Cabinet ABSLOG="..\..\..\..\..\Userdata\GameProject.log" -Master -UserDir="..\..\..\Userdata" -NotInstalled -UNATTENDED
|
|
||||||
|
|
||||||
rem EXP
|
|
||||||
inject -d -k idachook.dll ..\WindowsNoEditor\GameProject\Binaries\Win64\GameProject-Win64-Shipping.exe -culture=en launch=Cabinet ABSLOG="..\..\..\..\..\Userdata\GameProject.log" -Master -UserDir="..\..\..\Userdata" -NotInstalled -UNATTENDED
|
|
||||||
|
|
||||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
taskkill /f /im amdaemon.exe > nul 2>&1
|
||||||
|
|
||||||
|
REM unmount the APP_DIR
|
||||||
|
subst Y: /d > nul 2>&1
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Game processes have terminated
|
echo Game processes have terminated
|
||||||
pause
|
pause
|
16
dist/mai2/segatools.ini
vendored
16
dist/mai2/segatools.ini
vendored
@ -56,8 +56,8 @@ addrSuffix=11
|
|||||||
; that subnet must start with 192.168.
|
; that subnet must start with 192.168.
|
||||||
subnet=192.168.172.0
|
subnet=192.168.172.0
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||||
@ -69,18 +69,6 @@ freeplay=0
|
|||||||
; this to 1 on exactly one machine and set this to 0 on all others.
|
; this to 1 on exactly one machine and set this to 0 on all others.
|
||||||
dipsw1=1
|
dipsw1=1
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Misc. hook settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[unity]
|
|
||||||
; Enable Unity hook. This will allow you to run custom .NET code before the game
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; Path to a .NET DLL that should run before the game. Useful for loading
|
|
||||||
; modding frameworks such as BepInEx.
|
|
||||||
targetAssembly=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Custom IO settings
|
; Custom IO settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
3
dist/mai2/start.bat
vendored
3
dist/mai2/start.bat
vendored
@ -3,8 +3,7 @@
|
|||||||
pushd %~dp0
|
pushd %~dp0
|
||||||
|
|
||||||
start "AM Daemon" /min inject -d -k mai2hook.dll amdaemon.exe -f -c config_common.json config_server.json config_client.json
|
start "AM Daemon" /min inject -d -k mai2hook.dll amdaemon.exe -f -c config_common.json config_server.json config_client.json
|
||||||
inject -d -k mai2hook.dll sinmai -screen-fullscreen 0 -popupwindow -screen-width 2160 -screen-height 1920 -silent-crashes
|
inject -d -k mai2hook.dll sinmai -screen-fullscreen 0
|
||||||
|
|
||||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
taskkill /f /im amdaemon.exe > nul 2>&1
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
|
4
dist/mercury/segatools.ini
vendored
4
dist/mercury/segatools.ini
vendored
@ -56,8 +56,8 @@ addrSuffix=11
|
|||||||
; that subnet must start with 192.168.
|
; that subnet must start with 192.168.
|
||||||
subnet=192.168.174.0
|
subnet=192.168.174.0
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||||
|
62
dist/mu3/segatools.ini
vendored
62
dist/mu3/segatools.ini
vendored
@ -52,8 +52,8 @@ enable=1
|
|||||||
; that subnet must start with 192.168.
|
; that subnet must start with 192.168.
|
||||||
subnet=192.168.162.0
|
subnet=192.168.162.0
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||||
@ -72,62 +72,6 @@ dipsw1=1
|
|||||||
[gfx]
|
[gfx]
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
[unity]
|
|
||||||
; Enable Unity hook. This will allow you to run custom .NET code before the game
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; Path to a .NET DLL that should run before the game. Useful for loading
|
|
||||||
; modding frameworks such as BepInEx.
|
|
||||||
targetAssembly=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; LED settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[led15093]
|
|
||||||
; Enable emulation of the 15093-06 controlled lights, which handle the air tower
|
|
||||||
; RGBs and the rear LED panel (billboard) on the cabinet.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
[led]
|
|
||||||
; Output billboard LED strip data to a named pipe called "\\.\pipe\ongeki_led"
|
|
||||||
cabLedOutputPipe=1
|
|
||||||
; Output billboard LED strip data to serial
|
|
||||||
cabLedOutputSerial=0
|
|
||||||
|
|
||||||
; Output slider LED data to the named pipe
|
|
||||||
controllerLedOutputPipe=1
|
|
||||||
; Output slider LED data to the serial port
|
|
||||||
controllerLedOutputSerial=0
|
|
||||||
|
|
||||||
; Serial port to send data to if using serial output. Default is COM5.
|
|
||||||
;serialPort=COM5
|
|
||||||
; Baud rate for serial data
|
|
||||||
;serialBaud=921600
|
|
||||||
|
|
||||||
; Data output a sequence of bytes, with JVS-like framing.
|
|
||||||
; Each "packet" starts with 0xE0 as a sync. To avoid E0 appearing elsewhere,
|
|
||||||
; 0xD0 is used as an escape character -- if you receive D0 in the output, ignore
|
|
||||||
; it and use the next sent byte plus one instead.
|
|
||||||
;
|
|
||||||
; After the sync is one byte for the board number that was updated, followed by
|
|
||||||
; the red, green and blue values for each LED.
|
|
||||||
;
|
|
||||||
; Board 0 has 61 LEDs:
|
|
||||||
; [0]-[1]: left side button
|
|
||||||
; [2]-[8]: left pillar lower LEDs
|
|
||||||
; [9]-[17]: left pillar center LEDs
|
|
||||||
; [18]-[24]: left pillar upper LEDs
|
|
||||||
; [25]-[35]: billboard LEDs
|
|
||||||
; [36]-[42]: right pillar upper LEDs
|
|
||||||
; [43]-[51]: right pillar center LEDs
|
|
||||||
; [52]-[58]: right pillar lower LEDs
|
|
||||||
; [59]-[60]: right side button
|
|
||||||
;
|
|
||||||
; Board 1 has 6 LEDs:
|
|
||||||
; [0]-[5]: 3 left and 3 right controller buttons
|
|
||||||
;
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Custom IO settings
|
; Custom IO settings
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
@ -137,7 +81,7 @@ controllerLedOutputSerial=0
|
|||||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||||
path=
|
path=
|
||||||
|
|
||||||
[mu3io]
|
[fgoio]
|
||||||
; To use a custom O.N.G.E.K.I. IO DLL enter its path here.
|
; To use a custom O.N.G.E.K.I. IO DLL enter its path here.
|
||||||
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
|
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
|
||||||
path=
|
path=
|
||||||
|
6
dist/swdc/segatools.ini
vendored
6
dist/swdc/segatools.ini
vendored
@ -56,14 +56,14 @@ addrSuffix=11
|
|||||||
; in order to find the MAIN cabinet.
|
; in order to find the MAIN cabinet.
|
||||||
subnet=192.168.160.0
|
subnet=192.168.160.0
|
||||||
|
|
||||||
[system]
|
[gpio]
|
||||||
; Enable ALLS system settings.
|
; ALLS DIP switches.
|
||||||
enable=1
|
enable=1
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||||
; freeplay. Keep in mind that some game modes (e.g. Freedom/Time Modes) will not
|
; freeplay. Keep in mind that some game modes (e.g. Freedom/Time Modes) will not
|
||||||
; allow you to start a game in freeplay mode.
|
; allow you to start a game in freeplay mode.
|
||||||
freeplay=0
|
freeplay=0´
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; Custom IO settings
|
; Custom IO settings
|
||||||
|
9
dist/tokyo/config_hook.json
vendored
9
dist/tokyo/config_hook.json
vendored
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"network" :
|
|
||||||
{
|
|
||||||
"property" :
|
|
||||||
{
|
|
||||||
"dhcp" : true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
199
dist/tokyo/segatools.ini
vendored
199
dist/tokyo/segatools.ini
vendored
@ -1,199 +0,0 @@
|
|||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Path settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[vfs]
|
|
||||||
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
|
|
||||||
amfs=
|
|
||||||
; Insert the path to the game Option directory here (contains OPxx directories)
|
|
||||||
option=
|
|
||||||
; Create an empty directory somewhere and insert the path here.
|
|
||||||
; This directory may be shared between multiple SEGA games.
|
|
||||||
; NOTE: This has nothing to do with Windows %APPDATA%.
|
|
||||||
appdata=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Network settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[dns]
|
|
||||||
; Insert the hostname or IP address of the server you wish to use here.
|
|
||||||
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
|
||||||
default=127.0.0.1
|
|
||||||
|
|
||||||
[netenv]
|
|
||||||
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
|
||||||
; SEGA games are somewhat picky about their LAN environment, so leaving this
|
|
||||||
; setting enabled is recommended.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; The final octet of the local host's IP address on the virtualized subnet (so,
|
|
||||||
; if the keychip subnet is `192.168.149.0` and this value is set to `205`, then the
|
|
||||||
; local host's virtualized LAN IP is `192.168.149.205`).
|
|
||||||
addrSuffix=205
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Board settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[keychip]
|
|
||||||
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
|
|
||||||
; If you disable netenv then you must set this to your LAN's IP subnet, and
|
|
||||||
; that subnet must start with 192.168.
|
|
||||||
subnet=192.168.149.0
|
|
||||||
|
|
||||||
; Override the keychip's region code.
|
|
||||||
; 1: JAPAN (ALL.Net, Japanese language, Option support enabled)
|
|
||||||
; 4: EXPORT (Local networking only, English language, No option support)
|
|
||||||
; 8: CHINA
|
|
||||||
;
|
|
||||||
; NOTE: Changing this setting causes a factory reset. The language can be
|
|
||||||
; changed in the game settings, so it's possible to run the JAPAN region
|
|
||||||
; with English language.
|
|
||||||
region=1
|
|
||||||
|
|
||||||
[system]
|
|
||||||
; Enable ALLS system settings.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
|
||||||
; freeplay. Keep in mind that some game modes (e.g. Freedom/Time Modes) will not
|
|
||||||
; allow you to start a game in freeplay mode.
|
|
||||||
freeplay=0
|
|
||||||
|
|
||||||
; For Mario & Sonic at the Tokyo 2020 Olympics Arcade, DipSw 1/2/3 must be set
|
|
||||||
; as the following:
|
|
||||||
; Cabinet ID 1 (Server): 1 0 0
|
|
||||||
; Cabinet ID 2 (Client): 0 1 0
|
|
||||||
; Cabinet ID 3 (Client): 0 0 1
|
|
||||||
; Cabinet ID 4 (Client): 0 1 1
|
|
||||||
dipsw1=1
|
|
||||||
dipsw2=0
|
|
||||||
dipsw3=0
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; LED settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[led15093]
|
|
||||||
; Enable emulation of the 15093-04 controlled lights, which handle the cabinet
|
|
||||||
; LEDs.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Misc. hook settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[zinput]
|
|
||||||
; Disables the built-in DirectInput support, which is used to support a
|
|
||||||
; controller out of the box.
|
|
||||||
enable=1
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Custom IO settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
[tokyoio]
|
|
||||||
; To use a custom Mario & Sonic at the Tokyo 2020 Olympics Arcade IO DLL enter
|
|
||||||
; its path here. Leave empty if you want to use Segatools built-in keyboard/
|
|
||||||
; gamepad input.
|
|
||||||
path=
|
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
; Input settings
|
|
||||||
; -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
; Keyboard bindings are specified as hexadecimal (prefixed with 0x) or decimal
|
|
||||||
; (not prefixed with 0x) virtual-key codes, a list of which can be found here:
|
|
||||||
;
|
|
||||||
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
|
||||||
;
|
|
||||||
; This is, admittedly, not the most user-friendly configuration method in the
|
|
||||||
; world. An improved solution will be provided later.
|
|
||||||
|
|
||||||
[io4]
|
|
||||||
; Test button virtual-key code. Default is the F1 key.
|
|
||||||
test=0x70
|
|
||||||
; Service button virtual-key code. Default is the F2 key.
|
|
||||||
service=0x71
|
|
||||||
; Keyboard button to increment coin counter. Default is the F3 key.
|
|
||||||
coin=0x72
|
|
||||||
|
|
||||||
; Input API selection for IO4 input emulator.
|
|
||||||
; Set "xinput" to use a gamepad and "keyboard" to use a keyboard.
|
|
||||||
mode=xinput
|
|
||||||
|
|
||||||
; Mario & Sonic at the Tokyo 2020 Olympics Arcade Control Panel
|
|
||||||
;
|
|
||||||
; |--|------------------ Main-Assy ------------------|--|
|
|
||||||
; | | YELLOW | |
|
|
||||||
; | | --- | |
|
|
||||||
; | | ( O ) | |
|
|
||||||
; |--| BLUE --- RED |--|
|
|
||||||
; | | --- PUSH CENTER --- | |
|
|
||||||
; | | ( O ) /---------------\ ( O ) | |
|
|
||||||
; | | --- / \ --- | |
|
|
||||||
; | | PUSH LEFT / \ PUSH RIGHT| |
|
|
||||||
; |--|---------/ Floor Assy \---------|--|
|
|
||||||
; | | |JUMP SENSE JUMP SENSE| | |
|
|
||||||
; | | |1|---------------|-|-------------->|1| | |
|
|
||||||
; | | | | Foot Panel | | Foot Panel | | | |
|
|
||||||
; | | |2|<- - - - - - - |-| - - - - - - - |2| | |
|
|
||||||
; | | | | | | | | | |
|
|
||||||
; | | |3| -FOOT SENSE - |-| - FOOT SENSE->|3| | |
|
|
||||||
; | | | | L | | R | | | |
|
|
||||||
; | | |4|<- - - - - - - |-| - - - - - - - |4| | |
|
|
||||||
; | | | | | | | | | |
|
|
||||||
; | | |5| - - - - - - - |-| - - - - - - ->|5| | |
|
|
||||||
; | | | | | | | | | |
|
|
||||||
; | | |6|<--------------|-|---------------|6| | |
|
|
||||||
; | | | | | |
|
|
||||||
; | | | | | |
|
|
||||||
; |--|----|-------------------------------------|----|--|
|
|
||||||
;
|
|
||||||
|
|
||||||
; XInput bindings
|
|
||||||
;
|
|
||||||
; X Push Left Blue
|
|
||||||
; Y Push Center Yellow
|
|
||||||
; B Push Right Red
|
|
||||||
; D-Pad Left Push Left Blue
|
|
||||||
; D-Pad Right Push Right Red
|
|
||||||
; Left Trigger Foot Sense L/Jump Sense
|
|
||||||
; Right Trigger Foot Sense R/Jump Sense
|
|
||||||
|
|
||||||
[keyboard]
|
|
||||||
; Keyboard bindings
|
|
||||||
|
|
||||||
; Keyoard: Push button settings
|
|
||||||
|
|
||||||
; PUSH LEFT (BLUE) button virtual-key code. Default is the A key.
|
|
||||||
leftBlue=0x41
|
|
||||||
; PUSH CENTER (YELLOW) button virtual-key code. Default is the S key.
|
|
||||||
centerYellow=0x53
|
|
||||||
; PUSH RIGHT (RED) button virtual-key code. Default is the D key.
|
|
||||||
rightRed=0x44
|
|
||||||
|
|
||||||
; Keyboard: Sensor settings
|
|
||||||
; FOOT SENSE L (LEFT) button virtual-key code. Default is the Left Arrow key.
|
|
||||||
footLeft=0x25
|
|
||||||
; FOOT SENSE R (RIGHT) button virtual-key code. Default is the Right Arrow key.
|
|
||||||
footRight=0x27
|
|
||||||
|
|
||||||
; Keyboard: Jump sensor settings
|
|
||||||
; All jump sensors will also trigger the FOOT SENSE L and FOOT SENSE R buttons.
|
|
||||||
; JUMP SENSOR 1 button virtual-key code. Default is the Z key.
|
|
||||||
jump1=0x5A
|
|
||||||
; JUMP SENSOR 2 button virtual-key code. Default is the X key.
|
|
||||||
jump2=0x58
|
|
||||||
; JUMP SENSOR 3 button virtual-key code. Default is the C key.
|
|
||||||
jump3=0x43
|
|
||||||
; JUMP SENSOR 4 button virtual-key code. Default is the B key.
|
|
||||||
jump4=0x42
|
|
||||||
; JUMP SENSOR 5 button virtual-key code. Default is the N key.
|
|
||||||
jump5=0x4E
|
|
||||||
; JUMP SENSOR 6 button virtual-key code. Default is the M key.
|
|
||||||
jump6=0x4D
|
|
||||||
|
|
||||||
; Virtual-key code for all jump sensors. Default is the Space key.
|
|
||||||
jumpAll=0x20
|
|
57
dist/tokyo/start.bat
vendored
57
dist/tokyo/start.bat
vendored
@ -1,57 +0,0 @@
|
|||||||
@echo off
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
set DAEMON_WAIT_SECONDS=5
|
|
||||||
|
|
||||||
set AMDAEMON_CFG=config_common.json ^
|
|
||||||
config_ch.json ^
|
|
||||||
config_ex.json ^
|
|
||||||
config_jp.json ^
|
|
||||||
config_st1_ch.json ^
|
|
||||||
config_st1_ex.json ^
|
|
||||||
config_st1_jp.json ^
|
|
||||||
config_st2_ch.json ^
|
|
||||||
config_st2_ex.json ^
|
|
||||||
config_st2_jp.json ^
|
|
||||||
config_st3_ch.json ^
|
|
||||||
config_st3_ex.json ^
|
|
||||||
config_st3_jp.json ^
|
|
||||||
config_st4_ch.json ^
|
|
||||||
config_st4_ex.json ^
|
|
||||||
config_st4_jp.json ^
|
|
||||||
config_laninstall_server_ch.json ^
|
|
||||||
config_laninstall_client1_ch.json ^
|
|
||||||
config_laninstall_client2_ch.json ^
|
|
||||||
config_laninstall_client3_ch.json ^
|
|
||||||
config_laninstall_server_ex.json ^
|
|
||||||
config_laninstall_client1_ex.json ^
|
|
||||||
config_laninstall_client2_ex.json ^
|
|
||||||
config_laninstall_client3_ex.json ^
|
|
||||||
config_laninstall_server_jp.json ^
|
|
||||||
config_laninstall_client1_jp.json ^
|
|
||||||
config_laninstall_client2_jp.json ^
|
|
||||||
config_laninstall_client3_jp.json ^
|
|
||||||
config_hook.json
|
|
||||||
|
|
||||||
start /min "AM Daemon" inject -d -k tokyohook.dll amdaemon.exe -c %AMDAEMON_CFG%
|
|
||||||
timeout %DAEMON_WAIT_SECONDS% > nul 2>&1
|
|
||||||
|
|
||||||
REM ---------------------------------------------------------------------------
|
|
||||||
REM Set configuration
|
|
||||||
REM ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
REM Configuration values to be passed to the game executable.
|
|
||||||
REM All known values:
|
|
||||||
REM -forceapi:11
|
|
||||||
REM -forcehal
|
|
||||||
REM -forcevsync:0/1
|
|
||||||
REM -fullscreen
|
|
||||||
REM -windowed
|
|
||||||
REM Note: -windowed is recommended as the game looks sharper in windowed mode.
|
|
||||||
inject -d -k tokyohook.dll app.exe -windowed
|
|
||||||
|
|
||||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Game processes have terminated
|
|
||||||
pause
|
|
@ -1,14 +1,3 @@
|
|||||||
/*
|
|
||||||
"Hatsune Miku Project DIVA Arcade " (diva) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
JVS: 837-14572 "Type 3" I/O Board
|
|
||||||
COM1: 3M Touch Systems 78-0011-2353-4 Touch Controller Board
|
|
||||||
COM10: TN32MSEC003S "Gen 1" Aime Reader
|
|
||||||
COM11: 837-15275 Touch Slider
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -99,7 +99,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if defined(LOG_DIVA_SLIDER)
|
#if 0
|
||||||
dprintf("TX Buffer:\n");
|
dprintf("TX Buffer:\n");
|
||||||
dump_iobuf(&slider_uart.written);
|
dump_iobuf(&slider_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -118,7 +118,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(LOG_DIVA_SLIDER)
|
#if 0
|
||||||
dprintf("Deframe Buffer:\n");
|
dprintf("Deframe Buffer:\n");
|
||||||
dump_iobuf(&req_iobuf);
|
dump_iobuf(&req_iobuf);
|
||||||
#endif
|
#endif
|
||||||
|
@ -153,13 +153,6 @@ setting. Also, loopback addresses are specifically checked for and rejected by
|
|||||||
the games themselves; this needs to be a LAN or WAN IP (or a hostname that
|
the games themselves; this needs to be a LAN or WAN IP (or a hostname that
|
||||||
resolves to one).
|
resolves to one).
|
||||||
|
|
||||||
### `title`
|
|
||||||
|
|
||||||
Default: `title`
|
|
||||||
|
|
||||||
Leave it as `title` to use the title server returned by ALL.Net. Rewrites
|
|
||||||
the title server hostname for certain games, such as crossbeats REV.
|
|
||||||
|
|
||||||
### `router`
|
### `router`
|
||||||
|
|
||||||
Default: Empty string (i.e. use value from `default` setting)
|
Default: Empty string (i.e. use value from `default` setting)
|
||||||
@ -352,7 +345,7 @@ Enable keychip emulation. Disable to use a real keychip.
|
|||||||
Default: `A69E-01A88888888`
|
Default: `A69E-01A88888888`
|
||||||
|
|
||||||
Keychip serial number. Keychip serials observed in the wild follow this
|
Keychip serial number. Keychip serials observed in the wild follow this
|
||||||
pattern: `A\d{2}(E|X)-(01|20)[ABCDU]\d{8}`.
|
pattern: `A6xE-01Ayyyyyyyy`.
|
||||||
|
|
||||||
### `gameId`
|
### `gameId`
|
||||||
|
|
||||||
@ -395,29 +388,13 @@ Bit values are:
|
|||||||
- 3: EXP: Export (for Asian markets)
|
- 3: EXP: Export (for Asian markets)
|
||||||
- 4: CHS: China (Simplified Chinese?)
|
- 4: CHS: China (Simplified Chinese?)
|
||||||
|
|
||||||
### `billingCa`
|
|
||||||
|
|
||||||
Default: `DEVICE\\ca.crt`
|
|
||||||
|
|
||||||
Set the billing certificate path. This has to match the one used for the
|
|
||||||
SSL billing server. The DER certificate must fit in 1024 bytes so it must be
|
|
||||||
small.
|
|
||||||
|
|
||||||
### `billingPub`
|
|
||||||
|
|
||||||
Default: `DEVICE\\billing.pub`
|
|
||||||
|
|
||||||
Set the actual keychip RSA public key path. This public key has to match the
|
|
||||||
private key `billing.key` of the billing server in order to decrypt/encrypt
|
|
||||||
the billing transactions.
|
|
||||||
|
|
||||||
### `billingType`
|
### `billingType`
|
||||||
|
|
||||||
Default: `1`
|
Default: `1`
|
||||||
|
|
||||||
Set the billing "type" for the keychip. The type determins what kind of revenue share,
|
Set the billing "type" for the keychip. The type determins what kind of revenue share,
|
||||||
if any, the game maker has with SEGA. Some games may be picky and require types other
|
if any, the game maker has with SEGA. Some games may be picky and require types other
|
||||||
then 1 (ex. crossbeats REV. requires billing type 2), so this option is provided if this
|
then 1 (ex. Crossbeats requires billing type 2), so this option is provided if this
|
||||||
is an issue. Billing types are:
|
is an issue. Billing types are:
|
||||||
|
|
||||||
- 0: No billing?
|
- 0: No billing?
|
||||||
|
@ -1,20 +1,3 @@
|
|||||||
/*
|
|
||||||
"Fate Grand/Order Arcade" (fgo) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
USB: 837-15257 "Type 4" I/O Board
|
|
||||||
USB: 838-15405 "WinTouch" Controller Board
|
|
||||||
USB: 630-00008 Sinfonia CHC-C330 Printer
|
|
||||||
USB: 837-14509-02 USB-SER I/F BD Mini-B FTDI Board
|
|
||||||
connected to
|
|
||||||
837-15093-06 LED Controller Board
|
|
||||||
COM1: 200-6275 VFD GP1232A02A FUTABA Board
|
|
||||||
COM2: 837-15345 RFID Deck Reader Noard
|
|
||||||
COM3: 837-15396 "Gen 3" Aime Reader
|
|
||||||
COM4: 837-15347 RFID Reader/Writer Board (inside the printer)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -28,7 +28,7 @@ const struct dll_bind_sym fgo_dll_syms[] = {
|
|||||||
.sym = "fgo_io_led_init",
|
.sym = "fgo_io_led_init",
|
||||||
.off = offsetof(struct fgo_dll, led_init),
|
.off = offsetof(struct fgo_dll, led_init),
|
||||||
}, {
|
}, {
|
||||||
.sym = "fgo_io_led_set_colors",
|
.sym = "fgo_io_led_set_leds",
|
||||||
.off = offsetof(struct fgo_dll, led_set_leds),
|
.off = offsetof(struct fgo_dll, led_set_leds),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@ EXPORTS
|
|||||||
fgo_io_init
|
fgo_io_init
|
||||||
fgo_io_poll
|
fgo_io_poll
|
||||||
fgo_io_led_init
|
fgo_io_led_init
|
||||||
fgo_io_led_set_colors
|
fgo_io_led_set_leds
|
||||||
fwdlusb_open
|
fwdlusb_open
|
||||||
fwdlusb_close
|
fwdlusb_close
|
||||||
fwdlusb_listupPrinter
|
fwdlusb_listupPrinter
|
||||||
|
@ -145,7 +145,7 @@ HRESULT fgo_io_led_init(void)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fgo_io_led_set_colors(uint8_t board, uint8_t *rgb)
|
void fgo_io_led_set_leds(uint8_t board, uint8_t *rgb)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
@ -52,12 +52,16 @@ HRESULT fgo_io_poll(void);
|
|||||||
void fgo_io_get_opbtns(uint8_t *opbtn);
|
void fgo_io_get_opbtns(uint8_t *opbtn);
|
||||||
|
|
||||||
/* Get the state of the cabinet's gameplay buttons as of the last poll. See
|
/* Get the state of the cabinet's gameplay buttons as of the last poll. See
|
||||||
FGO_IO_GAMEBTN enum above: this contains bit mask definitions for button
|
FGO_IO_GAMEBTN enum above for bit mask definitions. Inputs are split into
|
||||||
states returned in *gamebtn. All buttons are active-high.
|
a left hand side set of inputs and a right hand side set of inputs: the bit
|
||||||
|
mappings are the same in both cases.
|
||||||
|
|
||||||
|
All buttons are active-high, even though some buttons' electrical signals
|
||||||
|
on a real cabinet are active-low.
|
||||||
|
|
||||||
Minimum API version: 0x0100 */
|
Minimum API version: 0x0100 */
|
||||||
|
|
||||||
void fgo_io_get_gamebtns(uint8_t *gamebtn);
|
void fgo_io_get_gamebtns(uint8_t *btn);
|
||||||
|
|
||||||
/* Get the position of the cabinet stick as of the last poll. The center
|
/* Get the position of the cabinet stick as of the last poll. The center
|
||||||
position should be equal to or close to 32767.
|
position should be equal to or close to 32767.
|
||||||
@ -79,4 +83,4 @@ HRESULT fgo_io_led_init(void);
|
|||||||
|
|
||||||
Exact layout is TBD. */
|
Exact layout is TBD. */
|
||||||
|
|
||||||
void fgo_io_led_set_colors(uint8_t board, uint8_t *rgb);
|
void fgo_io_led_set_leds(uint8_t board, uint8_t *rgb);
|
||||||
|
@ -224,19 +224,9 @@ static HRESULT STDMETHODCALLTYPE my_IDirect3D9_CreateDevice(
|
|||||||
gfx_util_frame_window(hwnd);
|
gfx_util_frame_window(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT max_adapter = IDirect3D9_GetAdapterCount(real);
|
dprintf("Gfx: Using adapter %d\n", gfx_config.monitor);
|
||||||
adapter = gfx_config.monitor;
|
|
||||||
if (adapter >= max_adapter) {
|
|
||||||
dprintf(
|
|
||||||
"Gfx: Requested adapter %d but maximum is %d. Using primary monitor\n",
|
|
||||||
gfx_config.monitor, max_adapter - 1
|
|
||||||
);
|
|
||||||
adapter = D3DADAPTER_DEFAULT;
|
|
||||||
} else {
|
|
||||||
dprintf("Gfx: Using adapter %d\n", gfx_config.monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return IDirect3D9_CreateDevice(real, adapter, type, hwnd, flags, pp, pdev);
|
return IDirect3D9_CreateDevice(real, gfx_config.monitor, type, hwnd, flags, pp, pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE my_IDirect3D9Ex_CreateDevice(
|
static HRESULT STDMETHODCALLTYPE my_IDirect3D9Ex_CreateDevice(
|
||||||
|
166
hooklib/dns.c
166
hooklib/dns.c
@ -3,7 +3,6 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <windns.h>
|
#include <windns.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <winhttp.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -13,8 +12,6 @@
|
|||||||
#include "hook/hr.h"
|
#include "hook/hr.h"
|
||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
#include "hooklib/dns.h"
|
#include "hooklib/dns.h"
|
||||||
|
|
||||||
/* Latest w32headers does not include DnsQueryEx, so we'll have to "polyfill"
|
/* Latest w32headers does not include DnsQueryEx, so we'll have to "polyfill"
|
||||||
@ -69,18 +66,6 @@ static int WSAAPI hook_getaddrinfo(
|
|||||||
const ADDRINFOA *pHints,
|
const ADDRINFOA *pHints,
|
||||||
ADDRINFOA **ppResult);
|
ADDRINFOA **ppResult);
|
||||||
|
|
||||||
static HINTERNET WINAPI hook_WinHttpConnect(
|
|
||||||
HINTERNET hSession,
|
|
||||||
const wchar_t *pwszServerName,
|
|
||||||
INTERNET_PORT nServerPort,
|
|
||||||
DWORD dwReserved);
|
|
||||||
|
|
||||||
static bool WINAPI hook_WinHttpCrackUrl(
|
|
||||||
const wchar_t *pwszUrl,
|
|
||||||
DWORD dwUrlLength,
|
|
||||||
DWORD dwFlags,
|
|
||||||
LPURL_COMPONENTS lpUrlComponents);
|
|
||||||
|
|
||||||
/* Link pointers */
|
/* Link pointers */
|
||||||
|
|
||||||
static DNS_STATUS (WINAPI *next_DnsQuery_A)(
|
static DNS_STATUS (WINAPI *next_DnsQuery_A)(
|
||||||
@ -110,18 +95,6 @@ static int (WSAAPI *next_getaddrinfo)(
|
|||||||
const ADDRINFOA *pHints,
|
const ADDRINFOA *pHints,
|
||||||
ADDRINFOA **ppResult);
|
ADDRINFOA **ppResult);
|
||||||
|
|
||||||
static HINTERNET (WINAPI *next_WinHttpConnect)(
|
|
||||||
HINTERNET hSession,
|
|
||||||
const wchar_t *pwszServerName,
|
|
||||||
INTERNET_PORT nServerPort,
|
|
||||||
DWORD dwReserved);
|
|
||||||
|
|
||||||
static bool (WINAPI *next_WinHttpCrackUrl)(
|
|
||||||
const wchar_t *pwszUrl,
|
|
||||||
DWORD dwUrlLength,
|
|
||||||
DWORD dwFlags,
|
|
||||||
LPURL_COMPONENTS lpUrlComponents);
|
|
||||||
|
|
||||||
static const struct hook_symbol dns_hook_syms_dnsapi[] = {
|
static const struct hook_symbol dns_hook_syms_dnsapi[] = {
|
||||||
{
|
{
|
||||||
.name = "DnsQuery_A",
|
.name = "DnsQuery_A",
|
||||||
@ -147,24 +120,10 @@ static const struct hook_symbol dns_hook_syms_ws2[] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hook_symbol dns_hook_syms_winhttp[] = {
|
|
||||||
{
|
|
||||||
.name = "WinHttpConnect",
|
|
||||||
.patch = hook_WinHttpConnect,
|
|
||||||
.link = (void **) &next_WinHttpConnect,
|
|
||||||
}, {
|
|
||||||
.name = "WinHttpCrackUrl",
|
|
||||||
.patch = hook_WinHttpCrackUrl,
|
|
||||||
.link = (void **) &next_WinHttpCrackUrl,
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool dns_hook_initted;
|
static bool dns_hook_initted;
|
||||||
static CRITICAL_SECTION dns_hook_lock;
|
static CRITICAL_SECTION dns_hook_lock;
|
||||||
static struct dns_hook_entry *dns_hook_entries;
|
static struct dns_hook_entry *dns_hook_entries;
|
||||||
static size_t dns_hook_nentries;
|
static size_t dns_hook_nentries;
|
||||||
static char received_title_url[255];
|
|
||||||
|
|
||||||
static void dns_hook_init(void)
|
static void dns_hook_init(void)
|
||||||
{
|
{
|
||||||
@ -186,43 +145,6 @@ static void dns_hook_init(void)
|
|||||||
"ws2_32.dll",
|
"ws2_32.dll",
|
||||||
dns_hook_syms_ws2,
|
dns_hook_syms_ws2,
|
||||||
_countof(dns_hook_syms_ws2));
|
_countof(dns_hook_syms_ws2));
|
||||||
|
|
||||||
hook_table_apply(
|
|
||||||
NULL,
|
|
||||||
"winhttp.dll",
|
|
||||||
dns_hook_syms_winhttp,
|
|
||||||
_countof(dns_hook_syms_winhttp));
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function match domain and subdomains like *.naominet.jp.
|
|
||||||
bool match_domain(const wchar_t* target, const wchar_t* pattern) {
|
|
||||||
if (_wcsicmp(pattern, target) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pattern_ptr_index = 0;
|
|
||||||
int target_ptr_index = 0;
|
|
||||||
|
|
||||||
while (pattern[pattern_ptr_index] != '\0' && target[target_ptr_index] != '\0') {
|
|
||||||
if (pattern[pattern_ptr_index] == '*') {
|
|
||||||
pattern_ptr_index++; // Check next character for wildcard match.
|
|
||||||
|
|
||||||
while (pattern[pattern_ptr_index] != target[target_ptr_index]) {
|
|
||||||
target_ptr_index++;
|
|
||||||
|
|
||||||
if (target[target_ptr_index] == '\0') return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pattern[pattern_ptr_index] != target[target_ptr_index]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pattern_ptr_index++;
|
|
||||||
target_ptr_index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pattern[pattern_ptr_index] == '\0' && target[target_ptr_index] == '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT dns_hook_push(const wchar_t *from_src, const wchar_t *to_src)
|
HRESULT dns_hook_push(const wchar_t *from_src, const wchar_t *to_src)
|
||||||
@ -328,7 +250,7 @@ static DNS_STATUS WINAPI hook_DnsQuery_A(
|
|||||||
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
||||||
pos = &dns_hook_entries[i];
|
pos = &dns_hook_entries[i];
|
||||||
|
|
||||||
if (match_domain(wstr, pos->from)) {
|
if (_wcsicmp(wstr, pos->from) == 0) {
|
||||||
if(pos->to == NULL) {
|
if(pos->to == NULL) {
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
LeaveCriticalSection(&dns_hook_lock);
|
||||||
hr = HRESULT_FROM_WIN32(DNS_ERROR_RCODE_NAME_ERROR);
|
hr = HRESULT_FROM_WIN32(DNS_ERROR_RCODE_NAME_ERROR);
|
||||||
@ -392,7 +314,7 @@ static DNS_STATUS WINAPI hook_DnsQuery_W(
|
|||||||
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
||||||
pos = &dns_hook_entries[i];
|
pos = &dns_hook_entries[i];
|
||||||
|
|
||||||
if (match_domain(pszName, pos->from)) {
|
if (_wcsicmp(pszName, pos->from) == 0) {
|
||||||
if(pos->to == NULL) {
|
if(pos->to == NULL) {
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
LeaveCriticalSection(&dns_hook_lock);
|
||||||
return HRESULT_FROM_WIN32(DNS_ERROR_RCODE_NAME_ERROR);
|
return HRESULT_FROM_WIN32(DNS_ERROR_RCODE_NAME_ERROR);
|
||||||
@ -436,7 +358,7 @@ static DNS_STATUS WINAPI hook_DnsQueryEx(
|
|||||||
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
||||||
pos = &dns_hook_entries[i];
|
pos = &dns_hook_entries[i];
|
||||||
|
|
||||||
if (match_domain(pRequest->QueryName, pos->from)) {
|
if (_wcsicmp(pRequest->QueryName, pos->from) == 0) {
|
||||||
if(pos->to == NULL) {
|
if(pos->to == NULL) {
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
LeaveCriticalSection(&dns_hook_lock);
|
||||||
return HRESULT_FROM_WIN32(DNS_ERROR_RCODE_NAME_ERROR);
|
return HRESULT_FROM_WIN32(DNS_ERROR_RCODE_NAME_ERROR);
|
||||||
@ -503,7 +425,7 @@ static int WSAAPI hook_getaddrinfo(
|
|||||||
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
||||||
pos = &dns_hook_entries[i];
|
pos = &dns_hook_entries[i];
|
||||||
|
|
||||||
if (match_domain(wstr, pos->from)) {
|
if (_wcsicmp(wstr, pos->from) == 0) {
|
||||||
if(pos->to == NULL) {
|
if(pos->to == NULL) {
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
LeaveCriticalSection(&dns_hook_lock);
|
||||||
result = EAI_NONAME;
|
result = EAI_NONAME;
|
||||||
@ -538,83 +460,3 @@ end:
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HINTERNET WINAPI hook_WinHttpConnect(
|
|
||||||
HINTERNET hSession,
|
|
||||||
const wchar_t *pwszServerName,
|
|
||||||
INTERNET_PORT nServerPort,
|
|
||||||
DWORD dwReserved)
|
|
||||||
{
|
|
||||||
const struct dns_hook_entry *pos;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (pwszServerName == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
EnterCriticalSection(&dns_hook_lock);
|
|
||||||
|
|
||||||
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
|
||||||
pos = &dns_hook_entries[i];
|
|
||||||
|
|
||||||
if (match_domain(pwszServerName, pos->from)) {
|
|
||||||
if(pos->to == NULL) {
|
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pwszServerName = pos->to;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
|
||||||
|
|
||||||
return next_WinHttpConnect(hSession, pwszServerName, nServerPort, dwReserved);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hook to replace CXB title url
|
|
||||||
static bool WINAPI hook_WinHttpCrackUrl(
|
|
||||||
const wchar_t *pwszUrl,
|
|
||||||
DWORD dwUrlLength,
|
|
||||||
DWORD dwFlags,
|
|
||||||
LPURL_COMPONENTS lpUrlComponents)
|
|
||||||
{
|
|
||||||
const struct dns_hook_entry *pos;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
EnterCriticalSection(&dns_hook_lock);
|
|
||||||
|
|
||||||
for (i = 0 ; i < dns_hook_nentries ; i++) {
|
|
||||||
pos = &dns_hook_entries[i];
|
|
||||||
|
|
||||||
if (match_domain(pwszUrl, pos->from)) {
|
|
||||||
wchar_t* toAddr = pos->to;
|
|
||||||
wchar_t titleBuffer[255];
|
|
||||||
|
|
||||||
if(wcscmp(toAddr, L"title") == 0) {
|
|
||||||
size_t wstr_c;
|
|
||||||
mbstowcs_s(&wstr_c, titleBuffer, 255, received_title_url, strlen(received_title_url));
|
|
||||||
toAddr = titleBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool result = next_WinHttpCrackUrl(
|
|
||||||
toAddr,
|
|
||||||
wcslen(toAddr),
|
|
||||||
dwFlags,
|
|
||||||
lpUrlComponents
|
|
||||||
);
|
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&dns_hook_lock);
|
|
||||||
return next_WinHttpCrackUrl(
|
|
||||||
pwszUrl,
|
|
||||||
dwUrlLength,
|
|
||||||
dwFlags,
|
|
||||||
lpUrlComponents
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -23,6 +23,8 @@ hooklib_lib = static_library(
|
|||||||
'fdshark.h',
|
'fdshark.h',
|
||||||
'path.c',
|
'path.c',
|
||||||
'path.h',
|
'path.h',
|
||||||
|
'procaddr.c',
|
||||||
|
'procaddr.h',
|
||||||
'reg.c',
|
'reg.c',
|
||||||
'reg.h',
|
'reg.h',
|
||||||
'setupapi.c',
|
'setupapi.c',
|
||||||
|
305
hooklib/path.c
305
hooklib/path.c
@ -101,40 +101,6 @@ static BOOL WINAPI hook_PathFileExistsA(LPCSTR pszPath);
|
|||||||
|
|
||||||
static BOOL WINAPI hook_PathFileExistsW(LPCWSTR pszPath);
|
static BOOL WINAPI hook_PathFileExistsW(LPCWSTR pszPath);
|
||||||
|
|
||||||
static BOOL WINAPI hook_MoveFileA(
|
|
||||||
const char *lpExistingFileName,
|
|
||||||
const char *lpNewFileName);
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_MoveFileW(
|
|
||||||
const wchar_t *lpExistingFileName,
|
|
||||||
const wchar_t *lpNewFileName);
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_MoveFileExA(
|
|
||||||
const char *lpExistingFileName,
|
|
||||||
const char *lpNewFileName,
|
|
||||||
uint32_t dwFlags);
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_ReplaceFileA(
|
|
||||||
const char *lpReplacedFileName,
|
|
||||||
const char *lpReplacementFileName,
|
|
||||||
const char *lpBackupFileName,
|
|
||||||
uint32_t dwReplaceFlags,
|
|
||||||
void *lpExclude,
|
|
||||||
void *lpReserved);
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_ReplaceFileW(
|
|
||||||
const wchar_t *lpReplacedFileName,
|
|
||||||
const wchar_t *lpReplacementFileName,
|
|
||||||
const wchar_t *lpBackupFileName,
|
|
||||||
uint32_t dwReplaceFlags,
|
|
||||||
void *lpExclude,
|
|
||||||
void *lpReserved);
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_DeleteFileA(const char *lpFileName);
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_DeleteFileW(const wchar_t *lpFileName);
|
|
||||||
|
|
||||||
/* Link pointers */
|
/* Link pointers */
|
||||||
|
|
||||||
static BOOL (WINAPI *next_CreateDirectoryA)(
|
static BOOL (WINAPI *next_CreateDirectoryA)(
|
||||||
@ -219,39 +185,6 @@ static BOOL (WINAPI *next_PathFileExistsA)(LPCSTR pszPath);
|
|||||||
|
|
||||||
static BOOL (WINAPI *next_PathFileExistsW)(LPCWSTR pszPath);
|
static BOOL (WINAPI *next_PathFileExistsW)(LPCWSTR pszPath);
|
||||||
|
|
||||||
static BOOL (WINAPI *next_MoveFileA)(
|
|
||||||
const char *lpExistingFileName,
|
|
||||||
const char *lpNewFileName);
|
|
||||||
|
|
||||||
static BOOL (WINAPI *next_MoveFileW)(
|
|
||||||
const wchar_t *lpExistingFileName,
|
|
||||||
const wchar_t *lpNewFileName);
|
|
||||||
|
|
||||||
static BOOL (WINAPI *next_MoveFileExA)(
|
|
||||||
const char *lpExistingFileName,
|
|
||||||
const char *lpNewFileName,
|
|
||||||
uint32_t dwFlags);
|
|
||||||
|
|
||||||
static BOOL (WINAPI *next_ReplaceFileA)(
|
|
||||||
const char *lpReplacedFileName,
|
|
||||||
const char *lpReplacementFileName,
|
|
||||||
const char *lpBackupFileName,
|
|
||||||
uint32_t dwReplaceFlags,
|
|
||||||
void *lpExclude,
|
|
||||||
void *lpReserved);
|
|
||||||
|
|
||||||
static BOOL (WINAPI *next_ReplaceFileW)(
|
|
||||||
const wchar_t *lpReplacedFileName,
|
|
||||||
const wchar_t *lpReplacementFileName,
|
|
||||||
const wchar_t *lpBackupFileName,
|
|
||||||
uint32_t dwReplaceFlags,
|
|
||||||
void *lpExclude,
|
|
||||||
void *lpReserved);
|
|
||||||
|
|
||||||
static BOOL (WINAPI *next_DeleteFileA)(const char *lpFileName);
|
|
||||||
|
|
||||||
static BOOL (WINAPI *next_DeleteFileW)(const wchar_t *lpFileName);
|
|
||||||
|
|
||||||
/* Hook table */
|
/* Hook table */
|
||||||
|
|
||||||
static const struct hook_symbol path_hook_syms[] = {
|
static const struct hook_symbol path_hook_syms[] = {
|
||||||
@ -327,34 +260,6 @@ static const struct hook_symbol path_hook_syms[] = {
|
|||||||
.name = "PathFileExistsW",
|
.name = "PathFileExistsW",
|
||||||
.patch = hook_PathFileExistsW,
|
.patch = hook_PathFileExistsW,
|
||||||
.link = (void **) &next_PathFileExistsW,
|
.link = (void **) &next_PathFileExistsW,
|
||||||
}, {
|
|
||||||
.name = "MoveFileA",
|
|
||||||
.patch = hook_MoveFileA,
|
|
||||||
.link = (void **) &next_MoveFileA,
|
|
||||||
}, {
|
|
||||||
.name = "MoveFileW",
|
|
||||||
.patch = hook_MoveFileW,
|
|
||||||
.link = (void **) &next_MoveFileW,
|
|
||||||
}, {
|
|
||||||
.name = "MoveFileExA",
|
|
||||||
.patch = hook_MoveFileExA,
|
|
||||||
.link = (void **) &next_MoveFileExA,
|
|
||||||
}, {
|
|
||||||
.name = "ReplaceFileA",
|
|
||||||
.patch = hook_ReplaceFileA,
|
|
||||||
.link = (void **) &next_ReplaceFileA,
|
|
||||||
}, {
|
|
||||||
.name = "ReplaceFileW",
|
|
||||||
.patch = hook_ReplaceFileW,
|
|
||||||
.link = (void **) &next_ReplaceFileW,
|
|
||||||
}, {
|
|
||||||
.name = "DeleteFileA",
|
|
||||||
.patch = hook_DeleteFileA,
|
|
||||||
.link = (void **) &next_DeleteFileA,
|
|
||||||
}, {
|
|
||||||
.name = "DeleteFileW",
|
|
||||||
.patch = hook_DeleteFileW,
|
|
||||||
.link = (void **) &next_DeleteFileW,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1001,213 +906,3 @@ static BOOL WINAPI hook_PathFileExistsW(LPCWSTR pszPath)
|
|||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI hook_MoveFileA(
|
|
||||||
const char *lpExistingFileName,
|
|
||||||
const char *lpNewFileName)
|
|
||||||
{
|
|
||||||
char *oldTrans;
|
|
||||||
char *newTrans;
|
|
||||||
BOOL ok;
|
|
||||||
|
|
||||||
ok = path_transform_a(&oldTrans, lpExistingFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = path_transform_a(&newTrans, lpNewFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
free(oldTrans);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = next_MoveFileA(
|
|
||||||
oldTrans ? oldTrans : lpExistingFileName,
|
|
||||||
newTrans ? newTrans : lpNewFileName);
|
|
||||||
|
|
||||||
free(oldTrans);
|
|
||||||
free(newTrans);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_MoveFileW(
|
|
||||||
const wchar_t *lpExistingFileName,
|
|
||||||
const wchar_t *lpNewFileName)
|
|
||||||
{
|
|
||||||
wchar_t *oldTrans;
|
|
||||||
wchar_t *newTrans;
|
|
||||||
BOOL ok;
|
|
||||||
|
|
||||||
ok = path_transform_w(&oldTrans, lpExistingFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = path_transform_w(&newTrans, lpNewFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
free(oldTrans);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = next_MoveFileW(
|
|
||||||
oldTrans ? oldTrans : lpExistingFileName,
|
|
||||||
newTrans ? newTrans : lpNewFileName);
|
|
||||||
|
|
||||||
free(oldTrans);
|
|
||||||
free(newTrans);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_MoveFileExA(
|
|
||||||
const char *lpExistingFileName,
|
|
||||||
const char *lpNewFileName,
|
|
||||||
uint32_t dwFlags)
|
|
||||||
{
|
|
||||||
char *oldTrans;
|
|
||||||
char *newTrans;
|
|
||||||
BOOL ok;
|
|
||||||
|
|
||||||
ok = path_transform_a(&oldTrans, lpExistingFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = path_transform_a(&newTrans, lpNewFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
free(oldTrans);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = next_MoveFileExA(
|
|
||||||
oldTrans ? oldTrans : lpExistingFileName,
|
|
||||||
newTrans ? newTrans : lpNewFileName,
|
|
||||||
dwFlags);
|
|
||||||
|
|
||||||
free(oldTrans);
|
|
||||||
free(newTrans);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_ReplaceFileA(
|
|
||||||
const char *lpReplacedFileName,
|
|
||||||
const char *lpReplacementFileName,
|
|
||||||
const char *lpBackupFileName,
|
|
||||||
uint32_t dwReplaceFlags,
|
|
||||||
void *lpExclude,
|
|
||||||
void *lpReserved)
|
|
||||||
{
|
|
||||||
char *oldTrans;
|
|
||||||
char *newTrans;
|
|
||||||
BOOL ok;
|
|
||||||
|
|
||||||
ok = path_transform_a(&oldTrans, lpReplacedFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = path_transform_a(&newTrans, lpReplacementFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
free(oldTrans);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = next_ReplaceFileA(
|
|
||||||
oldTrans ? oldTrans : lpReplacedFileName,
|
|
||||||
newTrans ? newTrans : lpReplacementFileName,
|
|
||||||
lpBackupFileName,
|
|
||||||
dwReplaceFlags,
|
|
||||||
lpExclude,
|
|
||||||
lpReserved);
|
|
||||||
|
|
||||||
free(oldTrans);
|
|
||||||
free(newTrans);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_ReplaceFileW(
|
|
||||||
const wchar_t *lpReplacedFileName,
|
|
||||||
const wchar_t *lpReplacementFileName,
|
|
||||||
const wchar_t *lpBackupFileName,
|
|
||||||
uint32_t dwReplaceFlags,
|
|
||||||
void *lpExclude,
|
|
||||||
void *lpReserved)
|
|
||||||
{
|
|
||||||
wchar_t *oldTrans;
|
|
||||||
wchar_t *newTrans;
|
|
||||||
BOOL ok;
|
|
||||||
|
|
||||||
ok = path_transform_w(&oldTrans, lpReplacedFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = path_transform_w(&newTrans, lpReplacementFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
free(oldTrans);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = next_ReplaceFileW(
|
|
||||||
oldTrans ? oldTrans : lpReplacedFileName,
|
|
||||||
newTrans ? newTrans : lpReplacementFileName,
|
|
||||||
lpBackupFileName,
|
|
||||||
dwReplaceFlags,
|
|
||||||
lpExclude,
|
|
||||||
lpReserved);
|
|
||||||
|
|
||||||
free(oldTrans);
|
|
||||||
free(newTrans);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_DeleteFileA(const char *lpFileName)
|
|
||||||
{
|
|
||||||
char *trans;
|
|
||||||
BOOL ok;
|
|
||||||
|
|
||||||
ok = path_transform_a(&trans, lpFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = next_DeleteFileA(trans ? trans: lpFileName);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_DeleteFileW(const wchar_t *lpFileName)
|
|
||||||
{
|
|
||||||
wchar_t *trans;
|
|
||||||
BOOL ok;
|
|
||||||
|
|
||||||
ok = path_transform_w(&trans, lpFileName);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = next_DeleteFileW(trans ? trans: lpFileName);
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
1602
hooklib/printer.c
1602
hooklib/printer.c
File diff suppressed because it is too large
Load Diff
@ -14,4 +14,3 @@ struct printer_config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self);
|
void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self);
|
||||||
void printer_hook_insert_hooks(HMODULE target);
|
|
||||||
|
125
hooklib/procaddr.c
Normal file
125
hooklib/procaddr.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
|
#include "hooklib/procaddr.h"
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
static struct proc_addr_table *proc_addr_hook_list;
|
||||||
|
static size_t proc_addr_hook_count;
|
||||||
|
static CRITICAL_SECTION proc_addr_hook_lock;
|
||||||
|
static bool proc_addr_hook_initted;
|
||||||
|
|
||||||
|
static FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name);
|
||||||
|
static FARPROC (WINAPI *next_GetProcAddress)(HMODULE hModule, const char *name);
|
||||||
|
static void proc_addr_hook_init(void);
|
||||||
|
|
||||||
|
static const struct hook_symbol win32_hooks[] = {
|
||||||
|
{
|
||||||
|
.name = "GetProcAddress",
|
||||||
|
.patch = my_GetProcAddress,
|
||||||
|
.link = (void **) &next_GetProcAddress
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT proc_addr_table_push(
|
||||||
|
const char *target,
|
||||||
|
struct hook_symbol *syms,
|
||||||
|
size_t nsyms
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
struct proc_addr_table *new_item;
|
||||||
|
struct proc_addr_table *new_mem;
|
||||||
|
|
||||||
|
proc_addr_hook_init();
|
||||||
|
|
||||||
|
EnterCriticalSection(&proc_addr_hook_lock);
|
||||||
|
|
||||||
|
new_mem = realloc(
|
||||||
|
proc_addr_hook_list,
|
||||||
|
(proc_addr_hook_count + 1) * sizeof(struct proc_addr_table));
|
||||||
|
|
||||||
|
if (new_mem == NULL) {
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&proc_addr_hook_lock);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_item = &new_mem[proc_addr_hook_count];
|
||||||
|
new_item->name = target;
|
||||||
|
new_item->nsyms = nsyms;
|
||||||
|
new_item->syms = syms;
|
||||||
|
|
||||||
|
proc_addr_hook_list = new_mem;
|
||||||
|
proc_addr_hook_count++;
|
||||||
|
hr = S_OK;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&proc_addr_hook_lock);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void proc_addr_hook_init(void)
|
||||||
|
{
|
||||||
|
if (proc_addr_hook_initted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("ProcAddr: Hook init\n");
|
||||||
|
proc_addr_hook_initted = true;
|
||||||
|
|
||||||
|
InitializeCriticalSection(&proc_addr_hook_lock);
|
||||||
|
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"kernel32.dll",
|
||||||
|
win32_hooks,
|
||||||
|
_countof(win32_hooks));
|
||||||
|
}
|
||||||
|
|
||||||
|
FARPROC WINAPI my_GetProcAddress(HMODULE hModule, const char *name)
|
||||||
|
{
|
||||||
|
uintptr_t ordinal = (uintptr_t) name;
|
||||||
|
char mod_path[PATH_MAX];
|
||||||
|
char *mod_name;
|
||||||
|
const struct hook_symbol *sym;
|
||||||
|
FARPROC result = next_GetProcAddress(hModule, name);
|
||||||
|
|
||||||
|
GetModuleFileNameA(hModule, mod_path, PATH_MAX);
|
||||||
|
mod_name = basename(mod_path);
|
||||||
|
|
||||||
|
for (int i = 0; i < proc_addr_hook_count; i++) {
|
||||||
|
|
||||||
|
if (strcmp(proc_addr_hook_list[i].name, mod_name) == 0) {
|
||||||
|
|
||||||
|
for (int j = 0; j < proc_addr_hook_list[i].nsyms; j++) {
|
||||||
|
sym = &proc_addr_hook_list[i].syms[j];
|
||||||
|
|
||||||
|
if (ordinal > 0xFFFF) {
|
||||||
|
|
||||||
|
if (strcmp(sym->name, name) == 0) {
|
||||||
|
|
||||||
|
dprintf("ProcAddr: Hooking %s from %s\n", name, mod_name);
|
||||||
|
result = (FARPROC) sym->patch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (sym->ordinal == ordinal) {
|
||||||
|
|
||||||
|
dprintf("ProcAddr: Hooking Ord %p from %s\n", (void *)ordinal, mod_name);
|
||||||
|
result = (FARPROC) sym->patch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
18
hooklib/procaddr.h
Normal file
18
hooklib/procaddr.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
struct proc_addr_table {
|
||||||
|
const char *name;
|
||||||
|
size_t nsyms;
|
||||||
|
struct hook_symbol *syms;
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT proc_addr_table_push(
|
||||||
|
const char *target,
|
||||||
|
struct hook_symbol *syms,
|
||||||
|
size_t nsyms
|
||||||
|
);
|
165
hooklib/reg.c
165
hooklib/reg.c
@ -7,7 +7,6 @@
|
|||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
#include "hooklib/reg.h"
|
#include "hooklib/reg.h"
|
||||||
#include "hook/procaddr.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
#include "util/str.h"
|
#include "util/str.h"
|
||||||
@ -100,29 +99,6 @@ static LSTATUS WINAPI hook_RegGetValueW(
|
|||||||
uint32_t *numData
|
uint32_t *numData
|
||||||
);
|
);
|
||||||
|
|
||||||
static LSTATUS WINAPI hook_RegQueryInfoKeyW(
|
|
||||||
HKEY hKey,
|
|
||||||
LPWSTR lpClass,
|
|
||||||
LPDWORD lpcchClass,
|
|
||||||
LPDWORD lpReserved,
|
|
||||||
LPDWORD lpcSubKeys,
|
|
||||||
LPDWORD lpcbMaxSubKeyLen,
|
|
||||||
LPDWORD lpcbMaxClassLen,
|
|
||||||
LPDWORD lpcValues,
|
|
||||||
LPDWORD lpcbMaxValueNameLen,
|
|
||||||
LPDWORD lpcbMaxValueLen,
|
|
||||||
LPDWORD lpcbSecurityDescriptor,
|
|
||||||
PFILETIME lpftLastWriteTime);
|
|
||||||
|
|
||||||
static LSTATUS WINAPI hook_RegEnumValueW(
|
|
||||||
HKEY hkey,
|
|
||||||
DWORD dwIndex,
|
|
||||||
LPWSTR lpValueName,
|
|
||||||
LPDWORD lpcchValueName,
|
|
||||||
LPDWORD lpReserved,
|
|
||||||
LPDWORD lpType,
|
|
||||||
LPBYTE lpData,
|
|
||||||
LPDWORD lpcbData);
|
|
||||||
/* Link pointers */
|
/* Link pointers */
|
||||||
|
|
||||||
static LSTATUS (WINAPI *next_RegOpenKeyExW)(
|
static LSTATUS (WINAPI *next_RegOpenKeyExW)(
|
||||||
@ -179,30 +155,6 @@ static LSTATUS (WINAPI *next_RegGetValueW)(
|
|||||||
uint32_t *numData
|
uint32_t *numData
|
||||||
);
|
);
|
||||||
|
|
||||||
static LSTATUS (WINAPI *next_RegQueryInfoKeyW)(
|
|
||||||
HKEY hKey,
|
|
||||||
LPWSTR lpClass,
|
|
||||||
LPDWORD lpcchClass,
|
|
||||||
LPDWORD lpReserved,
|
|
||||||
LPDWORD lpcSubKeys,
|
|
||||||
LPDWORD lpcbMaxSubKeyLen,
|
|
||||||
LPDWORD lpcbMaxClassLen,
|
|
||||||
LPDWORD lpcValues,
|
|
||||||
LPDWORD lpcbMaxValueNameLen,
|
|
||||||
LPDWORD lpcbMaxValueLen,
|
|
||||||
LPDWORD lpcbSecurityDescriptor,
|
|
||||||
PFILETIME lpftLastWriteTime);
|
|
||||||
|
|
||||||
static LSTATUS (WINAPI *next_RegEnumValueW)(
|
|
||||||
HKEY hkey,
|
|
||||||
DWORD dwIndex,
|
|
||||||
LPWSTR lpValueName,
|
|
||||||
LPDWORD lpcchValueName,
|
|
||||||
LPDWORD lpReserved,
|
|
||||||
LPDWORD lpType,
|
|
||||||
LPBYTE lpData,
|
|
||||||
LPDWORD lpcbData);
|
|
||||||
|
|
||||||
static const struct hook_symbol reg_hook_syms[] = {
|
static const struct hook_symbol reg_hook_syms[] = {
|
||||||
{
|
{
|
||||||
.name = "RegOpenKeyExW",
|
.name = "RegOpenKeyExW",
|
||||||
@ -232,14 +184,6 @@ static const struct hook_symbol reg_hook_syms[] = {
|
|||||||
.name = "RegGetValueW",
|
.name = "RegGetValueW",
|
||||||
.patch = hook_RegGetValueW,
|
.patch = hook_RegGetValueW,
|
||||||
.link = (void **) &next_RegGetValueW,
|
.link = (void **) &next_RegGetValueW,
|
||||||
}, {
|
|
||||||
.name = "RegQueryInfoKeyW",
|
|
||||||
.patch = hook_RegQueryInfoKeyW,
|
|
||||||
.link = (void **) &next_RegQueryInfoKeyW,
|
|
||||||
}, {
|
|
||||||
.name = "RegEnumValueW",
|
|
||||||
.patch = hook_RegEnumValueW,
|
|
||||||
.link = (void **) &next_RegEnumValueW,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -310,24 +254,11 @@ static void reg_hook_init(void)
|
|||||||
InitializeCriticalSection(®_hook_lock);
|
InitializeCriticalSection(®_hook_lock);
|
||||||
dprintf("Reg hook init\n");
|
dprintf("Reg hook init\n");
|
||||||
|
|
||||||
reg_hook_insert_hooks(NULL);
|
|
||||||
|
|
||||||
proc_addr_table_push(
|
|
||||||
NULL,
|
|
||||||
"ADVAPI32.dll",
|
|
||||||
(struct hook_symbol *) reg_hook_syms,
|
|
||||||
_countof(reg_hook_syms));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void reg_hook_insert_hooks(HMODULE target)
|
|
||||||
{
|
|
||||||
hook_table_apply(
|
hook_table_apply(
|
||||||
target,
|
NULL,
|
||||||
"advapi32.dll",
|
"advapi32.dll",
|
||||||
reg_hook_syms,
|
reg_hook_syms,
|
||||||
_countof(reg_hook_syms));
|
_countof(reg_hook_syms));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LRESULT reg_hook_propagate_hr(HRESULT hr)
|
static LRESULT reg_hook_propagate_hr(HRESULT hr)
|
||||||
@ -400,7 +331,6 @@ static LSTATUS reg_hook_open_locked(
|
|||||||
/* Assume reg keys are referenced from a root key and not from some
|
/* Assume reg keys are referenced from a root key and not from some
|
||||||
intermediary key */
|
intermediary key */
|
||||||
key = ®_hook_keys[i];
|
key = ®_hook_keys[i];
|
||||||
//dprintf("Reg: %ls vs %ls\n", name, key->name);
|
|
||||||
|
|
||||||
if (key->root == parent && wstr_ieq(key->name, name)) {
|
if (key->root == parent && wstr_ieq(key->name, name)) {
|
||||||
break;
|
break;
|
||||||
@ -891,99 +821,6 @@ static LSTATUS WINAPI hook_RegGetValueW(
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LSTATUS WINAPI hook_RegQueryInfoKeyW(
|
|
||||||
HKEY hKey,
|
|
||||||
LPWSTR lpClass,
|
|
||||||
LPDWORD lpcchClass,
|
|
||||||
LPDWORD lpReserved,
|
|
||||||
LPDWORD lpcSubKeys,
|
|
||||||
LPDWORD lpcbMaxSubKeyLen,
|
|
||||||
LPDWORD lpcbMaxClassLen,
|
|
||||||
LPDWORD lpcValues,
|
|
||||||
LPDWORD lpcbMaxValueNameLen,
|
|
||||||
LPDWORD lpcbMaxValueLen,
|
|
||||||
LPDWORD lpcbSecurityDescriptor,
|
|
||||||
PFILETIME lpftLastWriteTime)
|
|
||||||
{
|
|
||||||
struct reg_hook_key *key;
|
|
||||||
LSTATUS err;
|
|
||||||
|
|
||||||
EnterCriticalSection(®_hook_lock);
|
|
||||||
|
|
||||||
key = reg_hook_match_key_locked(hKey);
|
|
||||||
|
|
||||||
/* Check if this is a virtualized registry key */
|
|
||||||
|
|
||||||
if (key == NULL) {
|
|
||||||
LeaveCriticalSection(®_hook_lock);
|
|
||||||
|
|
||||||
return next_RegQueryInfoKeyW(
|
|
||||||
hKey,
|
|
||||||
lpClass,
|
|
||||||
lpcchClass,
|
|
||||||
lpReserved,
|
|
||||||
lpcSubKeys,
|
|
||||||
lpcbMaxSubKeyLen,
|
|
||||||
lpcbMaxClassLen,
|
|
||||||
lpcValues,
|
|
||||||
lpcbMaxValueNameLen,
|
|
||||||
lpcbMaxValueLen,
|
|
||||||
lpcbSecurityDescriptor,
|
|
||||||
lpftLastWriteTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the only one I've seen even be changed, so it's all I'm doing
|
|
||||||
// until I see otherwise.
|
|
||||||
*lpcValues = key->nvals;
|
|
||||||
LeaveCriticalSection(®_hook_lock);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LSTATUS WINAPI hook_RegEnumValueW(
|
|
||||||
HKEY hkey,
|
|
||||||
DWORD dwIndex,
|
|
||||||
LPWSTR lpValueName,
|
|
||||||
LPDWORD lpcchValueName,
|
|
||||||
LPDWORD lpReserved,
|
|
||||||
LPDWORD lpType,
|
|
||||||
LPBYTE lpData,
|
|
||||||
LPDWORD lpcbData)
|
|
||||||
{
|
|
||||||
struct reg_hook_key *key;
|
|
||||||
HRESULT hr;
|
|
||||||
LSTATUS err;
|
|
||||||
|
|
||||||
EnterCriticalSection(®_hook_lock);
|
|
||||||
|
|
||||||
key = reg_hook_match_key_locked(hkey);
|
|
||||||
|
|
||||||
/* Check if this is a virtualized registry key */
|
|
||||||
|
|
||||||
if (key == NULL) {
|
|
||||||
LeaveCriticalSection(®_hook_lock);
|
|
||||||
|
|
||||||
return next_RegEnumValueW(
|
|
||||||
hkey,
|
|
||||||
dwIndex,
|
|
||||||
lpValueName,
|
|
||||||
lpcchValueName,
|
|
||||||
lpReserved,
|
|
||||||
lpType,
|
|
||||||
lpData,
|
|
||||||
lpcbData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwIndex >= key->nvals) {
|
|
||||||
LeaveCriticalSection(®_hook_lock);
|
|
||||||
return ERROR_NO_MORE_ITEMS; // Pretty sure this is what it actually returns here?
|
|
||||||
}
|
|
||||||
|
|
||||||
wcscpy_s(lpValueName, *lpcchValueName, key->vals[dwIndex].name);
|
|
||||||
*lpcchValueName = wcslen(key->vals[dwIndex].name);
|
|
||||||
LeaveCriticalSection(®_hook_lock);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT reg_hook_read_bin(
|
HRESULT reg_hook_read_bin(
|
||||||
void *bytes,
|
void *bytes,
|
||||||
uint32_t *nbytes,
|
uint32_t *nbytes,
|
||||||
|
@ -12,8 +12,6 @@ struct reg_hook_val {
|
|||||||
uint32_t type;
|
uint32_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
void reg_hook_insert_hooks(HMODULE target);
|
|
||||||
|
|
||||||
HRESULT reg_hook_push_key(
|
HRESULT reg_hook_push_key(
|
||||||
HKEY root,
|
HKEY root,
|
||||||
const wchar_t *name,
|
const wchar_t *name,
|
||||||
|
@ -119,19 +119,10 @@ void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE sel
|
|||||||
defaultCursor = LoadCursorA(NULL, IDC_CROSS);
|
defaultCursor = LoadCursorA(NULL, IDC_CROSS);
|
||||||
|
|
||||||
memcpy(&touch_config, cfg, sizeof(*cfg));
|
memcpy(&touch_config, cfg, sizeof(*cfg));
|
||||||
touch_hook_insert_hooks(NULL);
|
hook_table_apply(NULL, "user32.dll", touch_hooks, _countof(touch_hooks));
|
||||||
dprintf("TOUCH: hook enabled.\n");
|
dprintf("TOUCH: hook enabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void touch_hook_insert_hooks(HMODULE target)
|
|
||||||
{
|
|
||||||
hook_table_apply(
|
|
||||||
target,
|
|
||||||
"user32.dll",
|
|
||||||
touch_hooks,
|
|
||||||
_countof(touch_hooks));
|
|
||||||
}
|
|
||||||
|
|
||||||
static HCURSOR WINAPI hook_SetCursor(HCURSOR cursor) {
|
static HCURSOR WINAPI hook_SetCursor(HCURSOR cursor) {
|
||||||
if (cursor == 0 && touch_config.cursor)
|
if (cursor == 0 && touch_config.cursor)
|
||||||
return next_SetCursor(defaultCursor);
|
return next_SetCursor(defaultCursor);
|
||||||
|
@ -14,4 +14,3 @@ struct touch_screen_config {
|
|||||||
blah blah you know the drill by now. */
|
blah blah you know the drill by now. */
|
||||||
|
|
||||||
void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE self);
|
void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE self);
|
||||||
void touch_hook_insert_hooks(HMODULE target);
|
|
||||||
|
@ -13,43 +13,6 @@
|
|||||||
#include "platform/config.h"
|
#include "platform/config.h"
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
|
|
||||||
void led15070_config_load(struct led15070_config *cfg, const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
wchar_t tmpstr[16];
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"led15070", L"enable", 1, filename);
|
|
||||||
cfg->port_no = GetPrivateProfileIntW(L"led15070", L"portNo", 0, filename);
|
|
||||||
cfg->fw_ver = GetPrivateProfileIntW(L"led15070", L"fwVer", 0x90, filename);
|
|
||||||
/* TODO: Unknown, no firmware file available */
|
|
||||||
cfg->fw_sum = GetPrivateProfileIntW(L"led15070", L"fwSum", 0x0000, filename);
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15070",
|
|
||||||
L"boardNumber",
|
|
||||||
L"15070-02",
|
|
||||||
tmpstr,
|
|
||||||
_countof(tmpstr),
|
|
||||||
filename);
|
|
||||||
|
|
||||||
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
|
|
||||||
for (int i = n; i < sizeof(cfg->board_number); i++)
|
|
||||||
{
|
|
||||||
cfg->board_number[i] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
GetPrivateProfileStringW(
|
|
||||||
L"led15070",
|
|
||||||
L"eepromPath",
|
|
||||||
L"DEVICE",
|
|
||||||
cfg->eeprom_path,
|
|
||||||
_countof(cfg->eeprom_path),
|
|
||||||
filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void idac_dll_config_load(
|
void idac_dll_config_load(
|
||||||
struct idac_dll_config *cfg,
|
struct idac_dll_config *cfg,
|
||||||
const wchar_t *filename)
|
const wchar_t *filename)
|
||||||
@ -66,16 +29,6 @@ void idac_dll_config_load(
|
|||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void indrun_config_load(
|
|
||||||
struct indrun_config *cfg,
|
|
||||||
const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"indrun", L"enable", 1, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
void idac_hook_config_load(
|
void idac_hook_config_load(
|
||||||
struct idac_hook_config *cfg,
|
struct idac_hook_config *cfg,
|
||||||
const wchar_t *filename)
|
const wchar_t *filename)
|
||||||
@ -89,8 +42,6 @@ void idac_hook_config_load(
|
|||||||
zinput_config_load(&cfg->zinput, filename);
|
zinput_config_load(&cfg->zinput, filename);
|
||||||
dvd_config_load(&cfg->dvd, filename);
|
dvd_config_load(&cfg->dvd, filename);
|
||||||
io4_config_load(&cfg->io4, filename);
|
io4_config_load(&cfg->io4, filename);
|
||||||
led15070_config_load(&cfg->led15070, filename);
|
|
||||||
indrun_config_load(&cfg->indrun, filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void zinput_config_load(struct zinput_config *cfg, const wchar_t *filename)
|
void zinput_config_load(struct zinput_config *cfg, const wchar_t *filename)
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "board/config.h"
|
#include "board/config.h"
|
||||||
#include "board/led15070.h"
|
|
||||||
|
|
||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
|
|
||||||
#include "idachook/idac-dll.h"
|
#include "idachook/idac-dll.h"
|
||||||
#include "idachook/zinput.h"
|
#include "idachook/zinput.h"
|
||||||
#include "idachook/indrun.h"
|
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
@ -21,8 +19,6 @@ struct idac_hook_config {
|
|||||||
struct io4_config io4;
|
struct io4_config io4;
|
||||||
struct idac_dll_config dll;
|
struct idac_dll_config dll;
|
||||||
struct zinput_config zinput;
|
struct zinput_config zinput;
|
||||||
struct led15070_config led15070;
|
|
||||||
struct indrun_config indrun;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void idac_dll_config_load(
|
void idac_dll_config_load(
|
||||||
@ -33,10 +29,4 @@ void idac_hook_config_load(
|
|||||||
struct idac_hook_config *cfg,
|
struct idac_hook_config *cfg,
|
||||||
const wchar_t *filename);
|
const wchar_t *filename);
|
||||||
|
|
||||||
void zinput_config_load(
|
void zinput_config_load(struct zinput_config *cfg, const wchar_t *filename);
|
||||||
struct zinput_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
||||||
|
|
||||||
void indrun_config_load(
|
|
||||||
struct indrun_config *cfg,
|
|
||||||
const wchar_t *filename);
|
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
/*
|
|
||||||
"Initial D THE ARCADE" (idac) hook
|
|
||||||
|
|
||||||
Devices
|
|
||||||
|
|
||||||
USB: 837-15257 "Type 4" I/O Board
|
|
||||||
COM1: 838-15069 MOTOR DRIVE BD RS232/422 Board
|
|
||||||
COM2: 837-15070-02 IC BD LED Controller Board
|
|
||||||
COM3: 837-15286 "Gen 2" Aime Reader (DIPSW2 OFF)
|
|
||||||
OR
|
|
||||||
837-15396 "Gen 3" Aime Reader (DIPSW2 ON)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
|
||||||
@ -66,13 +53,13 @@ static DWORD CALLBACK idac_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = idac_dll_init(&idac_hook_cfg.dll, idac_hook_mod);
|
hr = sg_reader_hook_init(&idac_hook_cfg.aime, 3, 3, idac_hook_mod);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = sg_reader_hook_init(&idac_hook_cfg.aime, 3, 3, idac_hook_mod);
|
hr = idac_dll_init(&idac_hook_cfg.dll, idac_hook_mod);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -84,20 +71,6 @@ static DWORD CALLBACK idac_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = led15070_hook_init(&idac_hook_cfg.led15070, idac_dll.led_init,
|
|
||||||
idac_dll.led_set_fet_output, NULL, idac_dll.led_gs_update, 2, 1);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize native plugin DLL hooks
|
|
||||||
|
|
||||||
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
|
|
||||||
hooked earlier in the initialization. */
|
|
||||||
|
|
||||||
indrun_hook_init(&idac_hook_cfg.indrun);
|
|
||||||
|
|
||||||
/* Initialize debug helpers */
|
/* Initialize debug helpers */
|
||||||
|
|
||||||
spike_hook_init(L".\\segatools.ini");
|
spike_hook_init(L".\\segatools.ini");
|
||||||
|
@ -24,18 +24,6 @@ const struct dll_bind_sym idac_dll_syms[] = {
|
|||||||
}, {
|
}, {
|
||||||
.sym = "idac_io_get_analogs",
|
.sym = "idac_io_get_analogs",
|
||||||
.off = offsetof(struct idac_dll, get_analogs),
|
.off = offsetof(struct idac_dll, get_analogs),
|
||||||
}, {
|
|
||||||
.sym = "idac_io_led_init",
|
|
||||||
.off = offsetof(struct idac_dll, led_init),
|
|
||||||
}, {
|
|
||||||
.sym = "idac_io_led_set_fet_output",
|
|
||||||
.off = offsetof(struct idac_dll, led_set_fet_output),
|
|
||||||
}, {
|
|
||||||
.sym = "idac_io_led_gs_update",
|
|
||||||
.off = offsetof(struct idac_dll, led_gs_update),
|
|
||||||
}, {
|
|
||||||
.sym = "idac_io_led_set_leds",
|
|
||||||
.off = offsetof(struct idac_dll, led_set_leds),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,10 +11,6 @@ struct idac_dll {
|
|||||||
void (*get_gamebtns)(uint8_t *gamebtn);
|
void (*get_gamebtns)(uint8_t *gamebtn);
|
||||||
void (*get_shifter)(uint8_t *gear);
|
void (*get_shifter)(uint8_t *gear);
|
||||||
void (*get_analogs)(struct idac_io_analog_state *out);
|
void (*get_analogs)(struct idac_io_analog_state *out);
|
||||||
HRESULT (*led_init)(void);
|
|
||||||
void (*led_set_fet_output)(const uint8_t *rgb);
|
|
||||||
void (*led_gs_update)(const uint8_t *rgb);
|
|
||||||
void (*led_set_leds)(const uint8_t *rgb);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct idac_dll_config {
|
struct idac_dll_config {
|
||||||
|
@ -13,11 +13,8 @@ EXPORTS
|
|||||||
amDllVideoSetResolution @3
|
amDllVideoSetResolution @3
|
||||||
idac_io_get_api_version
|
idac_io_get_api_version
|
||||||
idac_io_init
|
idac_io_init
|
||||||
|
idac_io_poll
|
||||||
idac_io_get_opbtns
|
idac_io_get_opbtns
|
||||||
idac_io_get_gamebtns
|
idac_io_get_gamebtns
|
||||||
idac_io_get_shifter
|
idac_io_get_shifter
|
||||||
idac_io_get_analogs
|
idac_io_get_analogs
|
||||||
idac_io_led_init
|
|
||||||
idac_io_led_set_fet_output
|
|
||||||
idac_io_led_gs_update
|
|
||||||
idac_io_led_set_leds
|
|
||||||
|
@ -1,260 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "hook/table.h"
|
|
||||||
|
|
||||||
#include "hooklib/dll.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
#include "indrun.h"
|
|
||||||
|
|
||||||
static const wchar_t *target_modules[] = {
|
|
||||||
L"IndRun.dll",
|
|
||||||
};
|
|
||||||
|
|
||||||
static const size_t target_modules_len = _countof(target_modules);
|
|
||||||
|
|
||||||
static void dll_hook_insert_hooks(HMODULE target);
|
|
||||||
static void app_hook_insert_hooks(HMODULE target);
|
|
||||||
|
|
||||||
static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name);
|
|
||||||
static HMODULE (WINAPI *next_LoadLibraryW)(const wchar_t *name);
|
|
||||||
|
|
||||||
static int WINAPI hook_GetSystemMetrics(int nIndex);
|
|
||||||
static int (WINAPI *next_GetSystemMetrics)(int nIndex);
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize);
|
|
||||||
static DWORD WINAPI hook_GetCurrentDirectoryW( DWORD nBufferLength, LPWSTR lpBuffer);
|
|
||||||
static BOOL WINAPI hook_GetVersionExW(LPOSVERSIONINFOW lpVersionInformation);
|
|
||||||
static int (WINAPI *next_GetVersionExW)(LPOSVERSIONINFOW lpVersionInformation);
|
|
||||||
static BOOL WINAPI hook_VerifyVersionInfoW(LPOSVERSIONINFOEXW lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask);
|
|
||||||
static BOOL (WINAPI *next_VerifyVersionInfoW)(LPOSVERSIONINFOEXW lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask);
|
|
||||||
static BOOL WINAPI hook_K32EnumProcesses(DWORD *lpidProcess, DWORD cb, LPDWORD lpcbNeeded);
|
|
||||||
static BOOL (WINAPI *next_K32EnumProcesses)(DWORD *lpidProcess, DWORD cb, LPDWORD lpcbNeeded);
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer);
|
|
||||||
|
|
||||||
static const struct hook_symbol idac_app_user32_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "GetSystemMetrics",
|
|
||||||
.patch = hook_GetSystemMetrics,
|
|
||||||
.link = (void **) &next_GetSystemMetrics,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hook_symbol idac_app_kernel32_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "GetComputerNameW",
|
|
||||||
.patch = hook_GetComputerNameW,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "GetCurrentDirectoryW",
|
|
||||||
.patch = hook_GetCurrentDirectoryW,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "GetVersionExW",
|
|
||||||
.patch = hook_GetVersionExW,
|
|
||||||
.link = (void **) &next_GetVersionExW,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "VerifyVersionInfoW",
|
|
||||||
.patch = hook_VerifyVersionInfoW,
|
|
||||||
.link = (void **) &next_VerifyVersionInfoW,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.name = "K32EnumProcesses",
|
|
||||||
.patch = hook_K32EnumProcesses,
|
|
||||||
.link = (void **) &next_K32EnumProcesses,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hook_symbol idac_app_advapi32_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "GetUserNameW",
|
|
||||||
.patch = hook_GetUserNameW,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hook_symbol indrun_kernel32_syms[] = {
|
|
||||||
{
|
|
||||||
.name = "LoadLibraryW",
|
|
||||||
.patch = hook_LoadLibraryW,
|
|
||||||
.link = (void **) &next_LoadLibraryW,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void indrun_hook_init(struct indrun_config *cfg)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
|
|
||||||
if (!cfg->enable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("IDAC: Hooks enabled.\n");
|
|
||||||
|
|
||||||
// GameProject-Win64-Shipping.exe hooks
|
|
||||||
app_hook_insert_hooks(NULL);
|
|
||||||
|
|
||||||
// IndRun.dll hooks
|
|
||||||
dll_hook_insert_hooks(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dll_hook_insert_hooks(HMODULE target) {
|
|
||||||
hook_table_apply(
|
|
||||||
target,
|
|
||||||
"kernel32.dll",
|
|
||||||
indrun_kernel32_syms,
|
|
||||||
_countof(indrun_kernel32_syms));
|
|
||||||
}
|
|
||||||
|
|
||||||
void app_hook_insert_hooks(HMODULE target) {
|
|
||||||
hook_table_apply(
|
|
||||||
target,
|
|
||||||
"user32.dll",
|
|
||||||
idac_app_user32_syms,
|
|
||||||
_countof(idac_app_user32_syms));
|
|
||||||
|
|
||||||
hook_table_apply(
|
|
||||||
target,
|
|
||||||
"kernel32.dll",
|
|
||||||
idac_app_kernel32_syms,
|
|
||||||
_countof(idac_app_kernel32_syms));
|
|
||||||
|
|
||||||
hook_table_apply(
|
|
||||||
target,
|
|
||||||
"advapi32.dll",
|
|
||||||
idac_app_advapi32_syms,
|
|
||||||
_countof(idac_app_advapi32_syms));
|
|
||||||
}
|
|
||||||
|
|
||||||
static HMODULE WINAPI hook_LoadLibraryW(const wchar_t *name)
|
|
||||||
{
|
|
||||||
const wchar_t *name_end;
|
|
||||||
const wchar_t *target_module;
|
|
||||||
bool already_loaded;
|
|
||||||
HMODULE result;
|
|
||||||
size_t name_len;
|
|
||||||
size_t target_module_len;
|
|
||||||
|
|
||||||
if (name == NULL) {
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the module is already loaded
|
|
||||||
already_loaded = GetModuleHandleW(name) != NULL;
|
|
||||||
|
|
||||||
// Must call the next handler so the DLL reference count is incremented
|
|
||||||
result = next_LoadLibraryW(name);
|
|
||||||
|
|
||||||
if (!already_loaded && result != NULL) {
|
|
||||||
name_len = wcslen(name);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < target_modules_len; i++) {
|
|
||||||
target_module = target_modules[i];
|
|
||||||
target_module_len = wcslen(target_module);
|
|
||||||
|
|
||||||
// Check if the newly loaded library is at least the length of
|
|
||||||
// the name of the target module
|
|
||||||
if (name_len < target_module_len) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
name_end = &name[name_len - target_module_len];
|
|
||||||
|
|
||||||
// Check if the name of the newly loaded library is one of the
|
|
||||||
// modules the path hooks should be injected into
|
|
||||||
if (_wcsicmp(name_end, target_module) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("IDAC: Hooked %S\n", target_module);
|
|
||||||
|
|
||||||
dll_hook_insert_hooks(result);
|
|
||||||
app_hook_insert_hooks(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int WINAPI hook_GetSystemMetrics(int nIndex) {
|
|
||||||
int ret = next_GetSystemMetrics(nIndex);
|
|
||||||
|
|
||||||
// Disable mouse buttons detection
|
|
||||||
if (nIndex == SM_CMOUSEBUTTONS) {
|
|
||||||
dprintf("IDAC: GetSystemMetrics(%d) -> 0\n", nIndex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize) {
|
|
||||||
dprintf("IDAC: GetComputerNameW -> ACAE01A99999999\n");
|
|
||||||
|
|
||||||
// Fake the computer name as ACAE01A999999999
|
|
||||||
wcscpy(lpBuffer, L"ACAE01A999999999");
|
|
||||||
*nSize = _countof(L"ACAE01A99999999");
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD WINAPI hook_GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer) {
|
|
||||||
dprintf("IDAC: GetCurrentDirectoryW -> X:\\\n");
|
|
||||||
|
|
||||||
// Fake the current diretory as X:
|
|
||||||
wcscpy(lpBuffer, L"X");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_GetVersionExW(LPOSVERSIONINFOW lpVersionInformation) {
|
|
||||||
int result = next_GetVersionExW(lpVersionInformation);
|
|
||||||
|
|
||||||
// Fake the version as Windows 10 1809
|
|
||||||
if (result) {
|
|
||||||
dprintf("IDAC: GetVersionExW -> Windows 10 1809\n");
|
|
||||||
lpVersionInformation->dwMajorVersion = 10;
|
|
||||||
lpVersionInformation->dwMinorVersion = 0;
|
|
||||||
lpVersionInformation->dwBuildNumber = 17763;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer) {
|
|
||||||
dprintf("IDAC: GetUserNameW -> AppUser\n");
|
|
||||||
|
|
||||||
// Fake the user name as AppUser
|
|
||||||
wcscpy(lpBuffer, L"AppUser");
|
|
||||||
*pcbBuffer = _countof(L"AppUser");
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_VerifyVersionInfoW(LPOSVERSIONINFOEXW lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask) {
|
|
||||||
BOOL result = next_VerifyVersionInfoW(lpVersionInformation, dwTypeMask, dwlConditionMask);
|
|
||||||
|
|
||||||
// Fake the version as Windows 10 1809
|
|
||||||
if (lpVersionInformation->dwBuildNumber == 17763) {
|
|
||||||
dprintf("IDAC: VerifyVersionInfoW -> Windows 10 1809\n");
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL WINAPI hook_K32EnumProcesses(DWORD *lpidProcess, DWORD cb, LPDWORD lpcbNeeded) {
|
|
||||||
BOOL result = next_K32EnumProcesses(lpidProcess, cb, lpcbNeeded);
|
|
||||||
|
|
||||||
// Rteurn an empy process list
|
|
||||||
dprintf("IDAC: K32EnumProcesses -> NULL\n");
|
|
||||||
lpidProcess = NULL;
|
|
||||||
*lpcbNeeded = 0;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
struct indrun_config {
|
|
||||||
bool enable;
|
|
||||||
};
|
|
||||||
|
|
||||||
void indrun_hook_init(struct indrun_config *cfg);
|
|
@ -11,12 +11,10 @@
|
|||||||
#include "util/dprintf.h"
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
static HRESULT idac_io4_poll(void *ctx, struct io4_state *state);
|
static HRESULT idac_io4_poll(void *ctx, struct io4_state *state);
|
||||||
static HRESULT idac_io4_write_gpio(uint8_t* payload, size_t len);
|
|
||||||
static uint16_t coins;
|
static uint16_t coins;
|
||||||
|
|
||||||
static const struct io4_ops idac_io4_ops = {
|
static const struct io4_ops idac_io4_ops = {
|
||||||
.poll = idac_io4_poll,
|
.poll = idac_io4_poll,
|
||||||
.write_gpio = idac_io4_write_gpio
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t idac_gear_signals[] = {
|
static const uint16_t idac_gear_signals[] = {
|
||||||
@ -130,34 +128,3 @@ static HRESULT idac_io4_poll(void *ctx, struct io4_state *state)
|
|||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT idac_io4_write_gpio(uint8_t* payload, size_t len)
|
|
||||||
{
|
|
||||||
// Just fast fail if there aren't enough bytes in the payload
|
|
||||||
if (len < 3)
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
// This command is used for lights in IDAC, but it only contains button lights,
|
|
||||||
// and only in the first 3 bytes of the payload; everything else is padding to
|
|
||||||
// make the payload 62 bytes. The rest of the cabinet lights and the side button
|
|
||||||
// lights are handled separately, by the 15070 lights controller.
|
|
||||||
uint32_t lights_data = (uint32_t) ((uint8_t)(payload[0]) << 24 |
|
|
||||||
(uint8_t)(payload[1]) << 16 |
|
|
||||||
(uint8_t)(payload[2]) << 8);
|
|
||||||
|
|
||||||
// Since Sega uses an odd ordering for the first part of the bitfield,
|
|
||||||
// let's normalize the data and just send over bytes for the receiver
|
|
||||||
// to interpret as ON/OFF values.
|
|
||||||
uint8_t rgb_out[6] = {
|
|
||||||
lights_data & IDAC_IO_LED_START ? 0xFF : 0x00,
|
|
||||||
lights_data & IDAC_IO_LED_VIEW_CHANGE ? 0xFF : 0x00,
|
|
||||||
lights_data & IDAC_IO_LED_UP ? 0xFF : 0x00,
|
|
||||||
lights_data & IDAC_IO_LED_DOWN ? 0xFF : 0x00,
|
|
||||||
lights_data & IDAC_IO_LED_RIGHT ? 0xFF : 0x00,
|
|
||||||
lights_data & IDAC_IO_LED_LEFT ? 0xFF : 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
idac_dll.led_set_leds(rgb_out);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
@ -28,7 +28,5 @@ shared_library(
|
|||||||
'io4.h',
|
'io4.h',
|
||||||
'zinput.c',
|
'zinput.c',
|
||||||
'zinput.h',
|
'zinput.h',
|
||||||
'indrun.c',
|
|
||||||
'indrun.h',
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user