forked from Hay1tsme/segatools
Compare commits
No commits in common. "develop" and "develop" have entirely different histories.
3
.gitignore
vendored
3
.gitignore
vendored
@ -18,6 +18,3 @@ build/
|
||||
|
||||
# External dependencies
|
||||
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
|
||||
|
||||
# Add "-D[option]=[value]" here as necessary
|
||||
MESON_OPTIONS :=
|
||||
# For options that shouldn't be committed
|
||||
-include MesonLocalOptions.mk
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Targets
|
||||
# -----------------------------------------------------------------------------
|
||||
@ -24,9 +19,9 @@ include Package.mk
|
||||
|
||||
.PHONY: build # Build the project
|
||||
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)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)
|
||||
|
||||
.PHONY: dist # Build and create a zip distribution package
|
||||
|
39
Package.mk
39
Package.mk
@ -203,43 +203,6 @@ $(BUILD_DIR_ZIP)/cm.zip:
|
||||
$(V)strip $(BUILD_DIR_ZIP)/cm/*.{exe,dll}
|
||||
$(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)/kemono.zip:
|
||||
$(V)echo ... $@
|
||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/kemono
|
||||
$(V)mkdir -p $(BUILD_DIR_ZIP)/kemono/DEVICE
|
||||
$(V)cp $(DIST_DIR)/kemono/segatools.ini \
|
||||
$(DIST_DIR)/kemono/start.bat \
|
||||
$(BUILD_DIR_ZIP)/kemono
|
||||
$(V)cp $(BUILD_DIR_32)/kemonohook/kemonohook.dll \
|
||||
$(BUILD_DIR_ZIP)/kemono/kemonohook_x86.dll
|
||||
$(V)cp $(BUILD_DIR_64)/kemonohook/kemonohook.dll \
|
||||
$(BUILD_DIR_ZIP)/kemono/kemonohook_x64.dll
|
||||
$(V)cp $(BUILD_DIR_32)/subprojects/capnhook/inject/inject.exe \
|
||||
$(BUILD_DIR_ZIP)/kemono/inject_x86.exe
|
||||
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
|
||||
$(BUILD_DIR_ZIP)/kemono/inject_x64.exe
|
||||
$(V)cp pki/billing.pub \
|
||||
pki/ca.crt \
|
||||
$(BUILD_DIR_ZIP)/kemono/DEVICE
|
||||
for x in exe dll; do strip $(BUILD_DIR_ZIP)/kemono/*.$$x; done
|
||||
$(V)cd $(BUILD_DIR_ZIP)/kemono ; zip -r ../kemono.zip *
|
||||
|
||||
$(BUILD_DIR_ZIP)/doc.zip: \
|
||||
$(DOC_DIR)/config \
|
||||
$(DOC_DIR)/chunihook.md \
|
||||
@ -262,9 +225,7 @@ $(BUILD_DIR_ZIP)/segatools.zip: \
|
||||
$(BUILD_DIR_ZIP)/mu3.zip \
|
||||
$(BUILD_DIR_ZIP)/mai2.zip \
|
||||
$(BUILD_DIR_ZIP)/cm.zip \
|
||||
$(BUILD_DIR_ZIP)/tokyo.zip \
|
||||
$(BUILD_DIR_ZIP)/fgo.zip \
|
||||
$(BUILD_DIR_ZIP)/kemono.zip \
|
||||
CHANGELOG.md \
|
||||
README.md \
|
||||
|
||||
|
26
README.md
26
README.md
@ -1,37 +1,33 @@
|
||||
# Segatools
|
||||
|
||||
Version: `2024-09-30`
|
||||
Version: `2024-03-13`
|
||||
|
||||
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
|
||||
|
||||
## List of supported games
|
||||
|
||||
* Card Maker
|
||||
* starting from Card Maker
|
||||
* CHUNITHM
|
||||
* up to [CHUNITHM PARADISE LOST](doc/chunihook.md)
|
||||
* 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 Arcade Stage Zero](doc/idzhook.md)
|
||||
* Initial D THE ARCADE
|
||||
* maimai DX
|
||||
* starting from maimai DX
|
||||
* Mario & Sonic
|
||||
* Mario & Sonic at the Tokyo 2020 Olympics Arcade
|
||||
* O.N.G.E.K.I.
|
||||
* starting from O.N.G.E.K.I.
|
||||
* Hatsune Miku: Project DIVA Arcade
|
||||
* up to Future Tone
|
||||
* SEGA World Drivers Championship
|
||||
* 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
|
||||
* starting from WACCA
|
||||
* Kemono Friends
|
||||
* Kemono Friends 3: Planet Tours
|
||||
|
||||
## End-users
|
||||
|
||||
|
@ -185,14 +185,14 @@ static HRESULT jvs_ioctl_sense(struct irp *irp)
|
||||
|
||||
static HRESULT jvs_ioctl_transact(struct irp *irp)
|
||||
{
|
||||
#if defined(LOG_JVS)
|
||||
#if 0
|
||||
dprintf("\nJVS Port: Outbound frame:\n");
|
||||
dump_const_iobuf(&irp->write);
|
||||
#endif
|
||||
|
||||
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");
|
||||
dump_iobuf(&irp->read);
|
||||
dprintf("\n");
|
||||
|
@ -90,14 +90,4 @@ void vfd_config_load(struct vfd_config *cfg, const wchar_t *filename)
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"vfd", L"enable", 1, filename);
|
||||
cfg->port = GetPrivateProfileIntW(L"vfd", L"portNo", 0, filename);
|
||||
cfg->utf_conversion = GetPrivateProfileIntW(L"vfd", L"utfConversion", 0, filename);
|
||||
}
|
||||
|
||||
void ffb_config_load(struct ffb_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"ffb", L"enable", 1, filename);
|
||||
}
|
||||
|
@ -6,9 +6,7 @@
|
||||
#include "board/io4.h"
|
||||
#include "board/sg-reader.h"
|
||||
#include "board/vfd.h"
|
||||
#include "board/ffb.h"
|
||||
|
||||
void aime_config_load(struct aime_config *cfg, const wchar_t *filename);
|
||||
void io4_config_load(struct io4_config *cfg, const wchar_t *filename);
|
||||
void vfd_config_load(struct vfd_config *cfg, const wchar_t *filename);
|
||||
void ffb_config_load(struct ffb_config *cfg, const wchar_t *filename);
|
||||
|
235
board/ffb.c
235
board/ffb.c
@ -1,235 +0,0 @@
|
||||
/*
|
||||
Force Feedback Board (FFB)
|
||||
|
||||
This board is used by many SEGA games to provide force feedback to the player.
|
||||
It is driven by the game software over a serial connection and is used by many
|
||||
games such as SEGA World Drivers Championship, Initial D Arcade, ...
|
||||
|
||||
Part number in schematics is "838-15069 MOTOR DRIVE BD RS232/422 Board".
|
||||
|
||||
Some observations:
|
||||
The maximal strength for any effect is 127, except Damper which maxes out at 40.
|
||||
The period for rumble effects is in the range 0-40.
|
||||
*/
|
||||
|
||||
#include "board/ffb.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "hook/iohook.h"
|
||||
#include "hooklib/uart.h"
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
|
||||
// request format:
|
||||
// 0x?? - sync + command
|
||||
// 0x?? - direction/additional command
|
||||
// 0x?? - strength
|
||||
// 0x?? - checksum (sum of everything except the sync byte)
|
||||
|
||||
enum {
|
||||
FFB_CMD_TOGGLE = 0x80,
|
||||
FFB_CMD_CONSTANT_FORCE = 0x84,
|
||||
FFB_CMD_RUMBLE = 0x85,
|
||||
FFB_CMD_DAMPER = 0x86,
|
||||
};
|
||||
|
||||
struct ffb_hdr {
|
||||
uint8_t cmd;
|
||||
};
|
||||
|
||||
union ffb_req_any {
|
||||
struct ffb_hdr hdr;
|
||||
uint8_t bytes[3];
|
||||
};
|
||||
|
||||
static HRESULT ffb_handle_irp(struct irp *irp);
|
||||
|
||||
static HRESULT ffb_req_dispatch(const union ffb_req_any *req);
|
||||
static HRESULT ffb_req_toggle(const uint8_t *bytes);
|
||||
static HRESULT ffb_req_constant_force(const uint8_t *bytes);
|
||||
static HRESULT ffb_req_rumble(const uint8_t *bytes);
|
||||
static HRESULT ffb_req_damper(const uint8_t *bytes);
|
||||
|
||||
static const struct ffb_ops *ffb_ops;
|
||||
static struct uart ffb_uart;
|
||||
|
||||
static bool ffb_started;
|
||||
static HRESULT ffb_start_hr;
|
||||
static uint8_t ffb_written[4];
|
||||
static uint8_t ffb_readable[4];
|
||||
|
||||
/* Static variables to store maximum strength values */
|
||||
static uint8_t max_constant_force = 0;
|
||||
static uint8_t max_rumble = 0;
|
||||
static uint8_t max_period = 0;
|
||||
static uint8_t max_damper = 0;
|
||||
|
||||
HRESULT ffb_hook_init(
|
||||
const struct ffb_config *cfg,
|
||||
const struct ffb_ops *ops,
|
||||
unsigned int port_no)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(ops != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
ffb_ops = ops;
|
||||
|
||||
uart_init(&ffb_uart, port_no);
|
||||
ffb_uart.written.bytes = ffb_written;
|
||||
ffb_uart.written.nbytes = sizeof(ffb_written);
|
||||
ffb_uart.readable.bytes = ffb_readable;
|
||||
ffb_uart.readable.nbytes = sizeof(ffb_readable);
|
||||
|
||||
dprintf("FFB: hook enabled.\n");
|
||||
|
||||
return iohook_push_handler(ffb_handle_irp);
|
||||
}
|
||||
|
||||
static HRESULT ffb_handle_irp(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(irp != NULL);
|
||||
|
||||
if (!uart_match_irp(&ffb_uart, irp)) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
hr = uart_handle_irp(&ffb_uart, irp);
|
||||
|
||||
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
assert(&ffb_uart.written != NULL);
|
||||
assert(ffb_uart.written.bytes != NULL || ffb_uart.written.nbytes == 0);
|
||||
assert(ffb_uart.written.pos <= ffb_uart.written.nbytes);
|
||||
|
||||
// dprintf("FFB TX:\n");
|
||||
|
||||
hr = ffb_req_dispatch((const union ffb_req_any *) ffb_uart.written.bytes);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("FFB: Processing error: %x\n", (int)hr);
|
||||
}
|
||||
|
||||
// dump_iobuf(&ffb_uart.written);
|
||||
ffb_uart.written.pos = 0;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT ffb_req_dispatch(const union ffb_req_any *req)
|
||||
{
|
||||
switch (req->hdr.cmd) {
|
||||
case FFB_CMD_TOGGLE:
|
||||
return ffb_req_toggle(req->bytes);
|
||||
case FFB_CMD_CONSTANT_FORCE:
|
||||
return ffb_req_constant_force(req->bytes);
|
||||
case FFB_CMD_RUMBLE:
|
||||
return ffb_req_rumble(req->bytes);
|
||||
case FFB_CMD_DAMPER:
|
||||
return ffb_req_damper(req->bytes);
|
||||
|
||||
/* There are some test mode specfic commands which doesn't seem to be used in
|
||||
game at all. The same is true for the initialization phase. */
|
||||
|
||||
default:
|
||||
dprintf("FFB: Unhandled command %02x\n", req->hdr.cmd);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT ffb_req_toggle(const uint8_t *bytes)
|
||||
{
|
||||
uint8_t activate = bytes[2];
|
||||
|
||||
if (activate == 0x01) {
|
||||
dprintf("FFB: Activated\n");
|
||||
} else {
|
||||
dprintf("FFB: Deactivated\n");
|
||||
}
|
||||
|
||||
if (ffb_ops->toggle != NULL) {
|
||||
ffb_ops->toggle(activate == 0x01);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ffb_req_constant_force(const uint8_t *bytes)
|
||||
{
|
||||
// dprintf("FFB: Constant force\n");
|
||||
|
||||
uint8_t direction = bytes[1];
|
||||
uint8_t force = bytes[2];
|
||||
|
||||
if (direction == 0x0) {
|
||||
// Right
|
||||
force = 128 - force;
|
||||
}
|
||||
|
||||
// Update max strength if the current force is greater
|
||||
if (force > max_constant_force) {
|
||||
max_constant_force = force;
|
||||
}
|
||||
|
||||
// dprintf("FFB: Constant Force Strength: %d (Max: %d)\n", force, max_constant_force);
|
||||
if (ffb_ops->constant_force != NULL) {
|
||||
ffb_ops->constant_force(direction, force);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ffb_req_rumble(const uint8_t *bytes)
|
||||
{
|
||||
// dprintf("FFB: Rumble\n");
|
||||
|
||||
uint8_t force = bytes[1];
|
||||
uint8_t period = bytes[2];
|
||||
|
||||
// Update max strength if the current force is greater
|
||||
if (force > max_rumble) {
|
||||
max_rumble = force;
|
||||
}
|
||||
|
||||
if (period > max_period) {
|
||||
max_period = period;
|
||||
}
|
||||
|
||||
// dprintf("FFB: Rumble Period: %d (Max %d), Strength: %d (Max: %d)\n", period, max_period, force, max_rumble);
|
||||
if (ffb_ops->rumble != NULL) {
|
||||
ffb_ops->rumble(force, period);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ffb_req_damper(const uint8_t *bytes)
|
||||
{
|
||||
// dprintf("FFB: Damper\n");
|
||||
|
||||
uint8_t force = bytes[2];
|
||||
|
||||
// Update max strength if the current force is greater
|
||||
if (force > max_damper) {
|
||||
max_damper = force;
|
||||
}
|
||||
|
||||
// dprintf("FFB: Damper Strength: %d (Max: %d)\n", force, max_damper);
|
||||
if (ffb_ops->damper != NULL) {
|
||||
ffb_ops->damper(force);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
20
board/ffb.h
20
board/ffb.h
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct ffb_config {
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct ffb_ops {
|
||||
void (*toggle)(bool active);
|
||||
void (*constant_force)(uint8_t direction, uint8_t force);
|
||||
void (*rumble)(uint8_t force, uint8_t period);
|
||||
void (*damper)(uint8_t force);
|
||||
};
|
||||
|
||||
HRESULT ffb_hook_init(
|
||||
const struct ffb_config *cfg,
|
||||
const struct ffb_ops *ops,
|
||||
unsigned int port_no);
|
71
board/io3.c
71
board/io3.c
@ -79,11 +79,6 @@ static HRESULT io3_cmd_read_analogs(
|
||||
struct const_iobuf *req_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(
|
||||
struct io3 *io3,
|
||||
struct const_iobuf *req_buf,
|
||||
@ -121,13 +116,6 @@ static uint8_t io3_features[] = {
|
||||
|
||||
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
|
||||
Param1 : 3 : Number of ports (8 bits per port)
|
||||
Param2 : 0 : N/A
|
||||
@ -231,9 +219,6 @@ static HRESULT io3_cmd(
|
||||
case JVS_CMD_READ_ANALOGS:
|
||||
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:
|
||||
return io3_cmd_write_gpio(io3, req, resp);
|
||||
|
||||
@ -390,7 +375,7 @@ static HRESULT io3_cmd_read_switches(
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if defined(LOG_IO3)
|
||||
#if 0
|
||||
dprintf("JVS I/O: Read switches, np=%i, bpp=%i\n",
|
||||
req.num_players,
|
||||
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(
|
||||
struct io3 *io3,
|
||||
struct const_iobuf *req_buf,
|
||||
|
@ -18,7 +18,6 @@ struct io3_ops {
|
||||
void (*write_gpio)(void *ctx, uint32_t state);
|
||||
void (*read_switches)(void *ctx, struct io3_switch_state *out);
|
||||
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);
|
||||
};
|
||||
|
||||
|
@ -48,7 +48,7 @@ static_assert(sizeof(struct io4_report_in) == 0x40, "IO4 IN report size");
|
||||
struct io4_report_out {
|
||||
uint8_t report_id;
|
||||
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");
|
||||
@ -223,11 +223,7 @@ static HRESULT io4_handle_write(struct irp *irp)
|
||||
return S_OK;
|
||||
|
||||
case IO4_CMD_SET_GENERAL_OUTPUT:
|
||||
// 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);
|
||||
}
|
||||
dprintf("USB I/O: GPIO Out\n");
|
||||
|
||||
return S_OK;
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define IO4_REPORT_OUT_PAYLOAD_LEN 62
|
||||
|
||||
enum {
|
||||
/* System buttons in button[0] */
|
||||
|
||||
@ -26,7 +24,6 @@ struct io4_state {
|
||||
|
||||
struct io4_ops {
|
||||
HRESULT (*poll)(void *ctx, struct io4_state *state);
|
||||
HRESULT (*write_gpio)(uint8_t* payload, size_t len);
|
||||
};
|
||||
|
||||
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);
|
@ -199,7 +199,7 @@ struct led15093_resp_board_info {
|
||||
char chip_num[5];
|
||||
uint8_t endcode; // Always 0xFF
|
||||
uint8_t fw_ver;
|
||||
uint16_t rx_buf;
|
||||
uint8_t rx_buf;
|
||||
};
|
||||
|
||||
struct led15093_resp_protocol_ver {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
SEGA 837-15093-XX LED Controller Board emulator
|
||||
|
||||
|
||||
Supported variants:
|
||||
|
||||
837-15093
|
||||
@ -106,7 +106,7 @@ static uint8_t led15093_host_adr = 1;
|
||||
static io_led_init_t led_init;
|
||||
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)
|
||||
{
|
||||
|
||||
@ -236,12 +236,12 @@ static HRESULT led15093_handle_irp_locked(int board, struct irp *irp)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if (irp->op == IRP_OP_OPEN) {
|
||||
dprintf("LED 15093: Starting backend DLL\n");
|
||||
// int res = led_init();
|
||||
hr = led_init();
|
||||
|
||||
|
||||
/*
|
||||
if (res != 0) {
|
||||
dprintf("LED 15093: Backend error, LED board disconnected: "
|
||||
@ -267,7 +267,7 @@ static HRESULT led15093_handle_irp_locked(int board, struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if defined(LOG_LED15093)
|
||||
#if 0
|
||||
dprintf("TX Buffer:\n");
|
||||
dump_iobuf(&boarduart->written);
|
||||
#endif
|
||||
@ -294,7 +294,7 @@ static HRESULT led15093_handle_irp_locked(int board, struct irp *irp)
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if defined(LOG_LED15093)
|
||||
#if 0
|
||||
dprintf("Deframe Buffer:\n");
|
||||
dump_iobuf(&req_iobuf);
|
||||
#endif
|
||||
@ -717,7 +717,7 @@ static HRESULT led15093_req_set_imm_led(int board, const struct led15093_req_set
|
||||
resp.status = v->status_code;
|
||||
if (req->cmd == LED_15093_CMD_SET_IMM_LED) {
|
||||
resp.cmd = LED_15093_CMD_SET_IMM_LED;
|
||||
}
|
||||
}
|
||||
// else {
|
||||
// resp.cmd = LED_15093_CMD_SET_IMM_LED_LEGACY;
|
||||
// }
|
||||
|
@ -25,11 +25,6 @@ board_lib = static_library(
|
||||
'led15093-frame.h',
|
||||
'led15093.c',
|
||||
'led15093.h',
|
||||
'led15070-cmd.h',
|
||||
'led15070-frame.c',
|
||||
'led15070-frame.h',
|
||||
'led15070.c',
|
||||
'led15070.h',
|
||||
'sg-cmd.c',
|
||||
'sg-cmd.h',
|
||||
'sg-frame.c',
|
||||
@ -47,10 +42,5 @@ board_lib = static_library(
|
||||
'slider-frame.h',
|
||||
'vfd.c',
|
||||
'vfd.h',
|
||||
'vfd-cmd.h',
|
||||
'vfd-frame.c',
|
||||
'vfd-frame.h',
|
||||
'ffb.c',
|
||||
'ffb.h'
|
||||
],
|
||||
)
|
||||
|
@ -5,21 +5,19 @@
|
||||
#pragma pack(push, 1)
|
||||
|
||||
enum {
|
||||
SG_NFC_CMD_GET_FW_VERSION = 0x30,
|
||||
SG_NFC_CMD_GET_HW_VERSION = 0x32,
|
||||
SG_NFC_CMD_RADIO_ON = 0x40,
|
||||
SG_NFC_CMD_RADIO_OFF = 0x41,
|
||||
SG_NFC_CMD_POLL = 0x42,
|
||||
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x50,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE_A = 0x51,
|
||||
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x54,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE_B = 0x55,
|
||||
SG_NFC_CMD_TO_UPDATE_MODE = 0x60,
|
||||
SG_NFC_CMD_SEND_HEX_DATA = 0x61,
|
||||
SG_NFC_CMD_RESET = 0x62,
|
||||
SG_NFC_CMD_FELICA_ENCAP = 0x71,
|
||||
SG_NFC_CMD_GET_FW_VERSION = 0x30,
|
||||
SG_NFC_CMD_GET_HW_VERSION = 0x32,
|
||||
SG_NFC_CMD_RADIO_ON = 0x40,
|
||||
SG_NFC_CMD_RADIO_OFF = 0x41,
|
||||
SG_NFC_CMD_POLL = 0x42,
|
||||
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x50,
|
||||
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE = 0x55, /* guess based on time sent */
|
||||
SG_NFC_CMD_SEND_HEX_DATA = 0x61,
|
||||
SG_NFC_CMD_RESET = 0x62,
|
||||
SG_NFC_CMD_FELICA_ENCAP = 0x71,
|
||||
};
|
||||
|
||||
struct sg_nfc_res_get_fw_version {
|
||||
@ -34,7 +32,7 @@ struct sg_nfc_res_get_hw_version {
|
||||
|
||||
struct sg_nfc_req_mifare_set_key {
|
||||
struct sg_req_header req;
|
||||
uint8_t key[6];
|
||||
uint8_t key_a[6];
|
||||
};
|
||||
|
||||
struct sg_nfc_req_mifare_50 {
|
||||
|
@ -60,11 +60,6 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
||||
const struct sg_nfc_req_felica_encap *req,
|
||||
struct sg_nfc_res_felica_encap *res);
|
||||
|
||||
static HRESULT sg_nfc_cmd_send_hex_data(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_res_header *res);
|
||||
|
||||
static HRESULT sg_nfc_cmd_dummy(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
@ -189,17 +184,13 @@ static HRESULT sg_nfc_dispatch(
|
||||
&req->felica_encap,
|
||||
&res->felica_encap);
|
||||
|
||||
case SG_NFC_CMD_MIFARE_AUTHENTICATE_A:
|
||||
case SG_NFC_CMD_MIFARE_AUTHENTICATE_B:
|
||||
case SG_NFC_CMD_SEND_HEX_DATA:
|
||||
return sg_nfc_cmd_send_hex_data(nfc, &req->simple, &res->simple);
|
||||
|
||||
case SG_NFC_CMD_MIFARE_AUTHENTICATE:
|
||||
case SG_NFC_CMD_MIFARE_SELECT_TAG:
|
||||
case SG_NFC_CMD_MIFARE_SET_KEY_AIME:
|
||||
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
|
||||
case SG_NFC_CMD_RADIO_ON:
|
||||
case SG_NFC_CMD_RADIO_OFF:
|
||||
case SG_NFC_CMD_TO_UPDATE_MODE:
|
||||
case SG_NFC_CMD_SEND_HEX_DATA: // TODO: implement?
|
||||
return sg_nfc_cmd_dummy(nfc, &req->simple, &res->simple);
|
||||
|
||||
default:
|
||||
@ -429,7 +420,7 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
||||
f_res.nbytes = sizeof(res->payload);
|
||||
f_res.pos = 1;
|
||||
|
||||
#if defined(LOG_NFC)
|
||||
#if 0
|
||||
dprintf("FELICA OUTBOUND:\n");
|
||||
dump_const_iobuf(&f_req);
|
||||
#endif
|
||||
@ -443,7 +434,7 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
||||
sg_res_init(&res->res, &req->req, f_res.pos);
|
||||
res->payload[0] = f_res.pos;
|
||||
|
||||
#if defined(LOG_NFC)
|
||||
#if 0
|
||||
dprintf("FELICA INBOUND:\n");
|
||||
dump_iobuf(&f_res);
|
||||
#endif
|
||||
@ -451,22 +442,6 @@ static HRESULT sg_nfc_cmd_felica_encap(
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_send_hex_data(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
struct sg_res_header *res)
|
||||
{
|
||||
sg_res_init(res, req, 0);
|
||||
|
||||
/* Firmware checksum length? */
|
||||
if (req->payload_len == 0x2b) {
|
||||
/* The firmware is identical flag? */
|
||||
res->status = 0x20;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sg_nfc_cmd_dummy(
|
||||
struct sg_nfc *nfc,
|
||||
const struct sg_req_header *req,
|
||||
|
@ -115,14 +115,14 @@ static HRESULT sg_reader_handle_irp_locked(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
#if defined(LOG_NFC)
|
||||
#if 0
|
||||
if (irp->op == IRP_OP_WRITE) {
|
||||
dprintf("WRITE:\n");
|
||||
dump_const_iobuf(&irp->write);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LOG_NFC)
|
||||
#if 0
|
||||
if (irp->op == IRP_OP_READ) {
|
||||
dprintf("READ:\n");
|
||||
dump_iobuf(&sg_reader_uart.readable);
|
||||
|
123
board/vfd-cmd.h
123
board/vfd-cmd.h
@ -1,123 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/vfd-frame.h"
|
||||
|
||||
enum {
|
||||
VFD_CMD_GET_VERSION = 0x5B,
|
||||
VFD_CMD_RESET = 0x0B,
|
||||
VFD_CMD_CLEAR_SCREEN = 0x0C,
|
||||
VFD_CMD_SET_BRIGHTNESS = 0x20,
|
||||
VFD_CMD_SET_SCREEN_ON = 0x21,
|
||||
VFD_CMD_SET_H_SCROLL = 0x22,
|
||||
VFD_CMD_DRAW_IMAGE = 0x2E,
|
||||
VFD_CMD_SET_CURSOR = 0x30,
|
||||
VFD_CMD_SET_ENCODING = 0x32,
|
||||
VFD_CMD_SET_TEXT_WND = 0x40,
|
||||
VFD_CMD_SET_TEXT_SPEED = 0x41,
|
||||
VFD_CMD_WRITE_TEXT = 0x50,
|
||||
VFD_CMD_ENABLE_SCROLL = 0x51,
|
||||
VFD_CMD_DISABLE_SCROLL = 0x52,
|
||||
VFD_CMD_ROTATE = 0x5D,
|
||||
VFD_CMD_CREATE_CHAR = 0xA3,
|
||||
VFD_CMD_CREATE_CHAR2 = 0xA4,
|
||||
};
|
||||
|
||||
enum {
|
||||
VFD_ENC_GB2312 = 0,
|
||||
VFD_ENC_BIG5 = 1,
|
||||
VFD_ENC_SHIFT_JIS = 2,
|
||||
VFD_ENC_KSC5601 = 3,
|
||||
VFD_ENC_MAX = 3,
|
||||
};
|
||||
|
||||
struct vfd_req_hdr {
|
||||
uint8_t sync;
|
||||
uint8_t cmd;
|
||||
};
|
||||
|
||||
struct vfd_req_any {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t payload[2054];
|
||||
};
|
||||
|
||||
struct vfd_req_board_info {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t unk1;
|
||||
};
|
||||
|
||||
struct vfd_resp_board_info { // \x0201.20\x03
|
||||
uint8_t unk1;
|
||||
char version[5];
|
||||
uint8_t unk2;
|
||||
};
|
||||
|
||||
struct vfd_req_reset {
|
||||
struct vfd_req_hdr hdr;
|
||||
};
|
||||
|
||||
struct vfd_req_cls {
|
||||
struct vfd_req_hdr hdr;
|
||||
};
|
||||
|
||||
struct vfd_req_brightness {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t brightness;
|
||||
};
|
||||
|
||||
struct vfd_req_power {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t power_state;
|
||||
};
|
||||
|
||||
struct vfd_req_hscroll {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t x_pos;
|
||||
};
|
||||
|
||||
struct vfd_req_draw {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint16_t x0;
|
||||
uint8_t y0;
|
||||
uint16_t x1;
|
||||
uint8_t y1;
|
||||
uint8_t image[2048];
|
||||
};
|
||||
|
||||
struct vfd_req_cursor {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint16_t x;
|
||||
uint8_t y;
|
||||
};
|
||||
|
||||
struct vfd_req_encoding {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t encoding;
|
||||
};
|
||||
|
||||
struct vfd_req_wnd {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint16_t x0;
|
||||
uint8_t y0;
|
||||
uint16_t x1;
|
||||
uint8_t y1;
|
||||
};
|
||||
|
||||
struct vfd_req_speed {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t encoding;
|
||||
};
|
||||
|
||||
struct vfd_req_scroll {
|
||||
struct vfd_req_hdr hdr;
|
||||
};
|
||||
|
||||
struct vfd_req_rotate {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t unk1;
|
||||
};
|
||||
|
||||
struct vfd_req_create_char {
|
||||
struct vfd_req_hdr hdr;
|
||||
uint8_t type;
|
||||
uint8_t pixels[32];
|
||||
};
|
@ -1,88 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define SUPER_VERBOSE 1
|
||||
|
||||
#include "board/vfd-frame.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static HRESULT vfd_frame_encode_byte(struct iobuf *dest, uint8_t byte);
|
||||
|
||||
/* Frame structure:
|
||||
|
||||
REQUEST:
|
||||
[0] Sync byte (0x1A or 0x1B)
|
||||
[1] Packet ID
|
||||
[2...n-1] Data/payload
|
||||
|
||||
--- OR ---
|
||||
|
||||
if no sync byte is given, plain static text in the currently configured encoding is expected.
|
||||
|
||||
RESPONSE:
|
||||
This thing never responds, unless it's VFD_CMD_GET_VERSION
|
||||
*/
|
||||
|
||||
bool vfd_frame_sync(struct const_iobuf *src) {
|
||||
return src->bytes[src->pos] == VFD_SYNC_BYTE || src->bytes[src->pos] == VFD_SYNC_BYTE2;
|
||||
}
|
||||
|
||||
HRESULT vfd_frame_encode(
|
||||
struct iobuf *dest,
|
||||
const void *ptr,
|
||||
size_t nbytes) {
|
||||
const uint8_t *src;
|
||||
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;
|
||||
|
||||
if (dest->pos >= dest->nbytes) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("VFD: RX Buffer:\n");
|
||||
#endif
|
||||
|
||||
for (i = 1; i < nbytes; i++) {
|
||||
byte = src[i];
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("%02x ", byte);
|
||||
#endif
|
||||
|
||||
hr = vfd_frame_encode_byte(dest, byte);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("\n");
|
||||
#endif
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT vfd_frame_encode_byte(struct iobuf *dest, uint8_t byte) {
|
||||
if (dest->pos + 1 > dest->nbytes) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
dest->bytes[dest->pos++] = byte;
|
||||
|
||||
return S_OK;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
enum {
|
||||
VFD_SYNC_BYTE = 0x1B,
|
||||
VFD_SYNC_BYTE2 = 0x1A,
|
||||
};
|
||||
|
||||
bool vfd_frame_sync(struct const_iobuf *src);
|
||||
|
||||
HRESULT vfd_frame_encode(
|
||||
struct iobuf *dest,
|
||||
const void *ptr,
|
||||
size_t nbytes);
|
400
board/vfd.c
400
board/vfd.c
@ -2,16 +2,17 @@
|
||||
directly by amdaemon, and it has something to do with displaying the status
|
||||
of electronic payments.
|
||||
|
||||
Part number in schematics is "VFD GP1232A02A FUTABA". */
|
||||
Part number in schematics is "VFD GP1232A02A FUTABA".
|
||||
|
||||
Little else about this board is known. Black-holing the RS232 comms that it
|
||||
receives seems to be sufficient for the time being. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/vfd.h"
|
||||
#include "board/vfd-cmd.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
@ -20,101 +21,33 @@
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
#define SUPER_VERBOSE 0
|
||||
|
||||
static HRESULT vfd_handle_irp(struct irp *irp);
|
||||
|
||||
static struct uart vfd_uart;
|
||||
static uint8_t vfd_written[4096];
|
||||
static uint8_t vfd_readable[4096];
|
||||
static uint8_t vfd_written[512];
|
||||
static uint8_t vfd_readable[512];
|
||||
UINT codepage;
|
||||
|
||||
static int encoding = VFD_ENC_SHIFT_JIS;
|
||||
|
||||
HRESULT vfd_handle_get_version(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_reset(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_clear_screen(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_brightness(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_screen_on(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_h_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_draw_image(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_cursor(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_encoding(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_text_wnd(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_set_text_speed(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_write_text(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_enable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_disable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_rotate(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_create_char(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
HRESULT vfd_handle_create_char2(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
|
||||
|
||||
static bool utf_enabled;
|
||||
|
||||
HRESULT vfd_hook_init(struct vfd_config *cfg, int default_port)
|
||||
HRESULT vfd_hook_init(const struct vfd_config *cfg, unsigned int port_no)
|
||||
{
|
||||
if (!cfg->enable){
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
utf_enabled = cfg->utf_conversion;
|
||||
|
||||
int port = cfg->port;
|
||||
if (port == 0){
|
||||
port = default_port;
|
||||
}
|
||||
|
||||
dprintf("VFD: enabling (port=%d)\n", port);
|
||||
uart_init(&vfd_uart, port);
|
||||
uart_init(&vfd_uart, port_no);
|
||||
vfd_uart.written.bytes = vfd_written;
|
||||
vfd_uart.written.nbytes = sizeof(vfd_written);
|
||||
vfd_uart.readable.bytes = vfd_readable;
|
||||
vfd_uart.readable.nbytes = sizeof(vfd_readable);
|
||||
|
||||
codepage = GetACP();
|
||||
dprintf("VFD: hook enabled.\n");
|
||||
|
||||
return iohook_push_handler(vfd_handle_irp);
|
||||
}
|
||||
|
||||
|
||||
const char* get_encoding_name(int b){
|
||||
switch (b){
|
||||
case 0: return "gb2312";
|
||||
case 1: return "big5";
|
||||
case 2: return "shift-jis";
|
||||
case 3: return "ks_c_5601-1987";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void print_vfd_text(const char* str, int len){
|
||||
|
||||
if (utf_enabled){
|
||||
|
||||
wchar_t encoded[1024];
|
||||
memset(encoded, 0, 1024 * sizeof(wchar_t));
|
||||
|
||||
int codepage = 0;
|
||||
if (encoding == VFD_ENC_GB2312){
|
||||
codepage = 936;
|
||||
} else if (encoding == VFD_ENC_BIG5){
|
||||
codepage = 950;
|
||||
} else if (encoding == VFD_ENC_SHIFT_JIS){
|
||||
codepage = 932;
|
||||
} else if (encoding == VFD_ENC_KSC5601) {
|
||||
codepage = 949;
|
||||
}
|
||||
|
||||
if (!MultiByteToWideChar(codepage, MB_USEGLYPHCHARS, str, len, encoded, 1024)){
|
||||
dprintf("VFD: Text conversion failed: %ld", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
dprintf("VFD: Text: %ls\n", encoded);
|
||||
} else {
|
||||
|
||||
dprintf("VFD: Text: %s\n", str);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT vfd_handle_irp(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
@ -125,274 +58,67 @@ static HRESULT vfd_handle_irp(struct irp *irp)
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
if (irp->op == IRP_OP_OPEN){
|
||||
dprintf("VFD: Open\n");
|
||||
} else if (irp->op == IRP_OP_CLOSE){
|
||||
dprintf("VFD: Close\n");
|
||||
}
|
||||
|
||||
hr = uart_handle_irp(&vfd_uart, irp);
|
||||
|
||||
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if SUPER_VERBOSE
|
||||
dprintf("VFD TX:\n");
|
||||
dump_iobuf(&vfd_uart.written);
|
||||
#endif
|
||||
|
||||
struct const_iobuf reader;
|
||||
iobuf_flip(&reader, &vfd_uart.written);
|
||||
|
||||
struct iobuf* writer = &vfd_uart.readable;
|
||||
for (; reader.pos < reader.nbytes ; ){
|
||||
|
||||
if (vfd_frame_sync(&reader)) {
|
||||
|
||||
reader.pos++; // get the sync byte out of the way
|
||||
|
||||
uint8_t cmd;
|
||||
iobuf_read_8(&reader, &cmd);
|
||||
|
||||
if (cmd == VFD_CMD_GET_VERSION) {
|
||||
hr = vfd_handle_get_version(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_RESET) {
|
||||
hr = vfd_handle_reset(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_CLEAR_SCREEN) {
|
||||
hr = vfd_handle_clear_screen(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_BRIGHTNESS) {
|
||||
hr = vfd_handle_set_brightness(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_SCREEN_ON) {
|
||||
hr = vfd_handle_set_screen_on(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_H_SCROLL) {
|
||||
hr = vfd_handle_set_h_scroll(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_DRAW_IMAGE) {
|
||||
hr = vfd_handle_draw_image(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_CURSOR) {
|
||||
hr = vfd_handle_set_cursor(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_ENCODING) {
|
||||
hr = vfd_handle_set_encoding(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_TEXT_WND) {
|
||||
hr = vfd_handle_set_text_wnd(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_SET_TEXT_SPEED) {
|
||||
hr = vfd_handle_set_text_speed(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_WRITE_TEXT) {
|
||||
hr = vfd_handle_write_text(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_ENABLE_SCROLL) {
|
||||
hr = vfd_handle_enable_scroll(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_DISABLE_SCROLL) {
|
||||
hr = vfd_handle_disable_scroll(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_ROTATE) {
|
||||
hr = vfd_handle_rotate(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_CREATE_CHAR) {
|
||||
hr = vfd_handle_create_char(&reader, writer, &vfd_uart);
|
||||
} else if (cmd == VFD_CMD_CREATE_CHAR2) {
|
||||
hr = vfd_handle_create_char2(&reader, writer, &vfd_uart);
|
||||
} else {
|
||||
dprintf("VFD: Unknown command 0x%x\n", cmd);
|
||||
dump_const_iobuf(&reader);
|
||||
hr = S_FALSE;
|
||||
uint8_t cmd = 0;
|
||||
uint8_t str_1[512];
|
||||
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 no sync byte is sent, we are just getting plain text...
|
||||
|
||||
if (reader.pos < reader.nbytes){
|
||||
int len = 0;
|
||||
|
||||
// read chars until we hit a new sync byte or the data ends
|
||||
while (reader.pos + len + 1 < reader.nbytes && reader.bytes[reader.pos + len] != VFD_SYNC_BYTE && reader.bytes[reader.pos + len] != VFD_SYNC_BYTE2){
|
||||
len++;
|
||||
}
|
||||
|
||||
char* str = malloc(len);
|
||||
memset(str, 0, len);
|
||||
iobuf_read(&reader, str, len);
|
||||
print_vfd_text(str, len);
|
||||
free(str);
|
||||
|
||||
reader.pos += len;
|
||||
else if (cmd == 0x50) {
|
||||
i++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(hr)){
|
||||
return hr;
|
||||
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;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT vfd_handle_get_version(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Get Version\n");
|
||||
|
||||
struct vfd_resp_board_info resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.unk1 = 2;
|
||||
strcpy(resp.version, "01.20");
|
||||
resp.unk2 = 1;
|
||||
|
||||
return vfd_frame_encode(writer, &resp, sizeof(resp));
|
||||
}
|
||||
HRESULT vfd_handle_reset(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Reset\n");
|
||||
|
||||
encoding = VFD_ENC_SHIFT_JIS;
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_clear_screen(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Clear Screen\n");
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_brightness(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
if (b > 4){
|
||||
dprintf("VFD: Brightness, invalid argument\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
dprintf("VFD: Brightness, %d\n", b);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_screen_on(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
if (b > 1){
|
||||
dprintf("VFD: Screen Power, invalid argument\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
dprintf("VFD: Screen Power, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_h_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t x;
|
||||
iobuf_read_8(reader, &x);
|
||||
|
||||
dprintf("VFD: Horizontal Scroll, X=%d\n", x);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_draw_image(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
int w, h;
|
||||
uint16_t x0, x1;
|
||||
uint8_t y0, y1;
|
||||
uint8_t image[2048];
|
||||
|
||||
iobuf_read_be16(reader, &x0);
|
||||
iobuf_read_8(reader, &y0);
|
||||
iobuf_read_be16(reader, &x1);
|
||||
iobuf_read_8(reader, &y1);
|
||||
w = x1 - x0;
|
||||
h = y1 - y0;
|
||||
iobuf_read(reader, image, w*h);
|
||||
|
||||
dprintf("VFD: Draw image, %dx%d\n", w, h);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT vfd_handle_set_cursor(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint16_t x;
|
||||
uint8_t y;
|
||||
|
||||
iobuf_read_be16(reader, &x);
|
||||
iobuf_read_8(reader, &y);
|
||||
|
||||
dprintf("VFD: Set Cursor, x=%d,y=%d\n", x, y);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT vfd_handle_set_encoding(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
dprintf("VFD: Set Encoding, %d (%s)\n", b, get_encoding_name(b));
|
||||
|
||||
if (b < 0 || b > VFD_ENC_MAX){
|
||||
dprintf("Invalid encoding specified\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
encoding = b;
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_text_wnd(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint16_t x0, x1;
|
||||
uint8_t y0, y1;
|
||||
|
||||
iobuf_read_be16(reader, &x0);
|
||||
iobuf_read_8(reader, &y0);
|
||||
iobuf_read_be16(reader, &x1);
|
||||
iobuf_read_8(reader, &y1);
|
||||
|
||||
dprintf("VFD: Set Text Window, p0:%d,%d, p1:%d,%d\n", x0, y0, x1, y1);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_set_text_speed(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
dprintf("VFD: Set Text Speed, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_write_text(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t len;
|
||||
iobuf_read_8(reader, &len);
|
||||
|
||||
char* str = malloc(len);
|
||||
iobuf_read(reader, str, len);
|
||||
|
||||
print_vfd_text(str, len);
|
||||
free(str);
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_enable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Enable Scrolling\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_disable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
dprintf("VFD: Disable Scrolling\n");
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_rotate(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
|
||||
dprintf("VFD: Rotate, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_create_char(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b;
|
||||
iobuf_read_8(reader, &b);
|
||||
char buf[32];
|
||||
|
||||
iobuf_read(reader, buf, 32);
|
||||
|
||||
dprintf("VFD: Create character, %d\n", b);
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT vfd_handle_create_char2(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
|
||||
uint8_t b, b2;
|
||||
iobuf_read_8(reader, &b);
|
||||
iobuf_read_8(reader, &b2);
|
||||
char buf[16];
|
||||
|
||||
iobuf_read(reader, buf, 16);
|
||||
|
||||
dprintf("VFD: Create character, %d, %d\n", b, b2);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
@ -4,10 +4,7 @@
|
||||
|
||||
struct vfd_config {
|
||||
bool enable;
|
||||
int port;
|
||||
bool utf_conversion;
|
||||
};
|
||||
|
||||
|
||||
HRESULT vfd_hook_init(struct vfd_config *cfg, int default_port);
|
||||
|
||||
HRESULT vfd_hook_init(const struct vfd_config *cfg, unsigned int port_no);
|
||||
|
@ -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 calculated_checksum = 0;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
|
||||
if (src->pos < 6) {
|
||||
dprintf("Control Board: Decode Error, request too short (pos is 0x%08X)\n", (int)src->pos);
|
||||
return SEC_E_BUFFER_TOO_SMALL;
|
||||
@ -137,7 +137,7 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp)
|
||||
|
||||
for (;;) {
|
||||
if (controlbd_uart.written.bytes[0] == 0xE0) {
|
||||
#if defined(LOG_CAROL_CONTROL_BD)
|
||||
#if 0
|
||||
dprintf("Control Board: TX Buffer:\n");
|
||||
dump_iobuf(&controlbd_uart.written);
|
||||
#endif
|
||||
@ -147,12 +147,12 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp)
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = controlbd_req_dispatch(&req);
|
||||
hr = controlbd_req_dispatch(&req);
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Control Board: Dispatch Error: 0X%X\n", (int) hr);
|
||||
return hr;
|
||||
}
|
||||
#if defined(LOG_CAROL_CONTROL_BD)
|
||||
#if 0
|
||||
dprintf("Control Board: RX Buffer:\n");
|
||||
dump_iobuf(&controlbd_uart.readable);
|
||||
#endif
|
||||
@ -206,7 +206,7 @@ static HRESULT controlbd_req_dispatch(const struct controlbd_req_any *req)
|
||||
case CONTROLBD_CMD_FIRM_SUM:
|
||||
return controlbd_req_firmware_checksum();
|
||||
|
||||
case CONTROLBD_CMD_TIMEOUT:
|
||||
case CONTROLBD_CMD_TIMEOUT:
|
||||
dprintf("Control Board: Acknowledge Timeout\n");
|
||||
return controlbd_req_ack_any(req->hdr.cmd);
|
||||
|
||||
@ -278,7 +278,7 @@ static HRESULT controlbd_req_get_board_info(void)
|
||||
resp.rev = 0x90;
|
||||
resp.bfr_size = 0x0001;
|
||||
resp.ack = 1;
|
||||
|
||||
|
||||
strcpy_s(resp.bd_no, sizeof(resp.bd_no), "15312 ");
|
||||
strcpy_s(resp.chip_no, sizeof(resp.chip_no), "6699 ");
|
||||
resp.chip_no[5] = 0xFF;
|
||||
@ -317,7 +317,7 @@ static HRESULT controlbd_req_polling(const struct controlbd_req_any *req)
|
||||
resp.unk7 = 3;
|
||||
resp.unk8 = 1;
|
||||
resp.unk9 = 1;
|
||||
|
||||
|
||||
resp.btns_pressed = 0; // bit 1 is pen button, bit 2 is dodge
|
||||
resp.coord_x = 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 <stdlib.h>
|
||||
|
@ -94,7 +94,7 @@ static HRESULT ledbd_handle_irp_locked(struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if defined(LOG_CAROL_LED_BD)
|
||||
#if 0
|
||||
dprintf("LED Board: TX Buffer:\n");
|
||||
dump_iobuf(&ledbd_uart.written);
|
||||
#endif
|
||||
@ -165,4 +165,4 @@ static HRESULT ledbd_req_unkF0(uint8_t cmd)
|
||||
iobuf_write(&ledbd_uart.readable, resp, 16);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
@ -54,7 +54,7 @@ HRESULT touch_hook_init(const struct touch_config *cfg)
|
||||
if (!cfg->enable) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
InitializeCriticalSection(&touch_lock);
|
||||
|
||||
uart_init(&touch_uart, 1);
|
||||
@ -112,7 +112,7 @@ static HRESULT touch_handle_irp_locked(struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if defined(LOG_CAROL_TOUCH)
|
||||
#if 0
|
||||
dprintf("Touchscreen: TX Buffer:\n");
|
||||
dump_iobuf(&touch_uart.written);
|
||||
#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;
|
||||
tmp_x = mouse_x & 0x7FFF;
|
||||
tmp_y = mouse_y & 0x7FFF;
|
||||
|
||||
|
||||
resp.touches[0].x1 = tmp_x & 0x7F;
|
||||
resp.touches[0].x2 = (tmp_x >> 7) & 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);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
last_x1 = resp.touches[0].x1;
|
||||
last_x2 = resp.touches[0].x2;
|
||||
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));
|
||||
LeaveCriticalSection(&touch_lock);
|
||||
|
||||
#if defined(LOG_CAROL_TOUCH)
|
||||
#if 0
|
||||
dprintf("Touch: RX Buffer: (pos %08x)\n", (uint32_t)touch_uart.readable.pos);
|
||||
dump_iobuf(&touch_uart.readable);
|
||||
#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 <stdlib.h>
|
||||
|
@ -98,7 +98,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if defined(LOG_CHUNI_SLIDER)
|
||||
#if 0
|
||||
dprintf("TX Buffer:\n");
|
||||
dump_iobuf(&slider_uart.written);
|
||||
#endif
|
||||
@ -117,7 +117,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if defined(LOG_CHUNI_SLIDER)
|
||||
#if 0
|
||||
dprintf("Deframe Buffer:\n");
|
||||
dump_iobuf(&req_iobuf);
|
||||
#endif
|
||||
|
@ -139,10 +139,9 @@ void chuni_io_slider_start(chuni_io_slider_callback_t callback);
|
||||
void chuni_io_slider_stop(void);
|
||||
|
||||
/* Update the RGB lighting on the slider. A pointer to an array of 32 * 3 = 96
|
||||
bytes is supplied, organized in BRG format.
|
||||
The first set of bytes is the right-most slider key, and from there the bytes
|
||||
alternate between the dividers and the keys until the left-most key.
|
||||
There are 31 illuminated sections in total.
|
||||
bytes is supplied. The illuminated areas on the touch slider are some
|
||||
combination of rectangular regions and dividing lines between these regions
|
||||
but the exact mapping of this lighting control buffer is still TBD.
|
||||
|
||||
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).
|
||||
board 0 is on the left side and board 1 on the right side of the cab
|
||||
|
||||
Board 0 has 53 LEDs:
|
||||
[0]-[49]: snakes through left half of billboard (first column starts at top)
|
||||
[50]-[52]: left side partition LEDs
|
||||
left side has 5*10 rgb values for the billboard, followed by 3 rgb values for the air tower
|
||||
right side has 6*10 rgb values for the billboard, followed by 3 rgb values for the air tower
|
||||
|
||||
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
|
||||
|
||||
NOTE: billboard strips have alternating direction (bottom to top, top to bottom, ...)
|
||||
|
@ -57,13 +57,11 @@ void chuni_io_config_load(
|
||||
filename);
|
||||
}
|
||||
|
||||
cfg->cab_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_pipe = GetPrivateProfileIntW(L"led", L"cabLedOutputPipe", 1, 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->controller_led_output_serial = GetPrivateProfileIntW(L"led", L"controllerLedOutputSerial", 0, filename);
|
||||
|
||||
cfg->controller_led_output_openithm = GetPrivateProfileIntW(L"led", L"controllerLedOutputOpeNITHM", 0, filename);
|
||||
cfg->slider_led_output_pipe = GetPrivateProfileIntW(L"led", L"controllerLedOutputPipe", 1, filename);
|
||||
cfg->slider_led_output_serial = GetPrivateProfileIntW(L"led", L"controllerLedOutputSerial", 0, filename);
|
||||
|
||||
cfg->led_serial_baud = GetPrivateProfileIntW(L"led", L"serialBaud", 921600, filename);
|
||||
|
||||
@ -72,7 +70,7 @@ void chuni_io_config_load(
|
||||
L"serialPort",
|
||||
L"COM5",
|
||||
port_input,
|
||||
_countof(port_input),
|
||||
6,
|
||||
filename);
|
||||
|
||||
// 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];
|
||||
|
||||
// Which ways to output LED information are enabled
|
||||
bool cab_led_output_pipe;
|
||||
bool cab_led_output_serial;
|
||||
bool led_output_pipe;
|
||||
bool led_output_serial;
|
||||
|
||||
bool controller_led_output_pipe;
|
||||
bool controller_led_output_serial;
|
||||
|
||||
bool controller_led_output_openithm;
|
||||
bool slider_led_output_pipe;
|
||||
bool slider_led_output_serial;
|
||||
|
||||
// The name of a COM port to output LED data on, in serial mode
|
||||
wchar_t led_serial_port[12];
|
||||
int32_t led_serial_baud;
|
||||
|
||||
};
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
any_outputs_enabled = config->cab_led_output_pipe || config->controller_led_output_pipe
|
||||
|| config->cab_led_output_serial || config->controller_led_output_serial;
|
||||
any_outputs_enabled = config->led_output_pipe || config->slider_led_output_pipe
|
||||
|| 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
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -106,13 +106,13 @@ void led_output_update(uint8_t board, const byte* rgb)
|
||||
|
||||
if (board < 2)
|
||||
{
|
||||
// billboard (cab)
|
||||
if (config->cab_led_output_pipe)
|
||||
// billboard
|
||||
if (config->led_output_pipe)
|
||||
{
|
||||
led_pipe_update(escaped_data);
|
||||
}
|
||||
|
||||
if (config->cab_led_output_serial)
|
||||
if (config->led_output_serial)
|
||||
{
|
||||
led_serial_update(escaped_data);
|
||||
}
|
||||
@ -120,18 +120,14 @@ void led_output_update(uint8_t board, const byte* rgb)
|
||||
else
|
||||
{
|
||||
// slider
|
||||
if (config->controller_led_output_pipe)
|
||||
if (config->slider_led_output_pipe)
|
||||
{
|
||||
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_openithm(rgb);
|
||||
} else {
|
||||
led_serial_update(escaped_data);
|
||||
}
|
||||
led_serial_update(escaped_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ chuniio_lib = static_library(
|
||||
include_directories : inc,
|
||||
implicit_include_directories : false,
|
||||
c_pch : '../precompiled.h',
|
||||
|
||||
sources : [
|
||||
'chu2to3.c',
|
||||
'chu2to3.h',
|
||||
|
@ -4,7 +4,6 @@
|
||||
Credits:
|
||||
somewhatlurker, skogaby
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
@ -97,27 +97,3 @@ void led_serial_update(struct _chuni_led_data_buf_t* data)
|
||||
|
||||
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);
|
||||
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 "
|
||||
"further assistance.\n",
|
||||
sym->sym);
|
||||
dprintf("imported %d symbols\n", bind_count);
|
||||
dprintf("imported %d symbols\n",bind_count);
|
||||
goto end;
|
||||
}
|
||||
} 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 <stddef.h>
|
||||
@ -123,7 +99,7 @@ static DWORD CALLBACK chusan_pre_startup(void)
|
||||
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];
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
@ -98,7 +98,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if defined(LOG_CHUSAN_SLIDER)
|
||||
#if 0
|
||||
dprintf("TX Buffer:\n");
|
||||
dump_iobuf(&slider_uart.written);
|
||||
#endif
|
||||
@ -117,7 +117,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if defined(LOG_CHUSAN_SLIDER)
|
||||
#if 0
|
||||
dprintf("Deframe Buffer:\n");
|
||||
dump_iobuf(&req_iobuf);
|
||||
#endif
|
||||
|
@ -15,59 +15,3 @@ EXPORTS
|
||||
cm_io_get_opbtns
|
||||
cm_io_init
|
||||
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,6 @@ void cm_hook_config_load(
|
||||
io4_config_load(&cfg->io4, filename);
|
||||
vfd_config_load(&cfg->vfd, filename);
|
||||
touch_screen_config_load(&cfg->touch, filename);
|
||||
printer_config_load(&cfg->printer, filename);
|
||||
cm_dll_config_load(&cfg->dll, filename);
|
||||
unity_config_load(&cfg->unity, filename);
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "hooklib/dvd.h"
|
||||
#include "hooklib/touch.h"
|
||||
#include "hooklib/printer.h"
|
||||
|
||||
#include "cmhook/cm-dll.h"
|
||||
|
||||
@ -22,7 +21,6 @@ struct cm_hook_config {
|
||||
struct vfd_config vfd;
|
||||
struct cm_dll_config dll;
|
||||
struct touch_screen_config touch;
|
||||
struct printer_config printer;
|
||||
struct unity_config unity;
|
||||
};
|
||||
|
||||
|
@ -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 <stdlib.h>
|
||||
@ -56,10 +43,6 @@ static DWORD CALLBACK cm_pre_startup(void)
|
||||
touch_screen_hook_init(&cm_hook_cfg.touch, cm_hook_mod);
|
||||
serial_hook_init();
|
||||
|
||||
/* Hook external DLL APIs */
|
||||
|
||||
printer_hook_init(&cm_hook_cfg.printer, 0, cm_hook_mod);
|
||||
|
||||
/* Initialize emulation hooks */
|
||||
|
||||
hr = platform_hook_init(
|
||||
@ -72,12 +55,6 @@ static DWORD CALLBACK cm_pre_startup(void)
|
||||
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);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
@ -90,6 +67,12 @@ static DWORD CALLBACK cm_pre_startup(void)
|
||||
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);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
@ -101,7 +84,7 @@ static DWORD CALLBACK cm_pre_startup(void)
|
||||
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
|
||||
hooked earlier in the `cmhook` initialization. */
|
||||
|
||||
unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod, NULL);
|
||||
unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod);
|
||||
|
||||
/* Initialize debug helpers */
|
||||
|
||||
|
@ -36,9 +36,9 @@ HRESULT cm_io_init(void);
|
||||
HRESULT cm_io_poll(void);
|
||||
|
||||
/* 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.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
void cm_io_get_opbtns(uint8_t *opbtn);
|
||||
void cm_io_get_opbtns(uint8_t *opbtn);
|
@ -5,7 +5,7 @@
|
||||
#include "cxbhook/led.h"
|
||||
#include "cxbhook/cxb-dll.h"
|
||||
|
||||
#include "hook/procaddr.h"
|
||||
#include "hooklib/procaddr.h"
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
@ -56,7 +56,7 @@ HRESULT led_hook_init(struct led_config *cfg)
|
||||
}
|
||||
|
||||
dprintf("LED: Hook enabled.\n");
|
||||
return proc_addr_table_push(NULL, "CommLamp.dll", lamp_syms, _countof(lamp_syms));
|
||||
return proc_addr_table_push("CommLamp.dll", lamp_syms, _countof(lamp_syms));
|
||||
}
|
||||
|
||||
static int my_cCommLamp_Open(char *port)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "cxbhook/revio.h"
|
||||
#include "cxbhook/cxb-dll.h"
|
||||
|
||||
#include "hook/procaddr.h"
|
||||
#include "hooklib/procaddr.h"
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
@ -89,7 +89,7 @@ HRESULT revio_hook_init(struct revio_config *cfg)
|
||||
}
|
||||
|
||||
dprintf("Revio: Hook enabled.\n");
|
||||
return proc_addr_table_push(NULL, "CommIo.dll", revio_syms, _countof(revio_syms));
|
||||
return proc_addr_table_push("CommIo.dll", revio_syms, _countof(revio_syms));
|
||||
}
|
||||
|
||||
static int my_cCommIo_Open(char *port)
|
||||
|
2
dist/carol/segatools.ini
vendored
2
dist/carol/segatools.ini
vendored
@ -64,8 +64,6 @@ subnet=192.168.126.0
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
enable=1
|
||||
; Force the game to run windowed.
|
||||
windowed=1
|
||||
; Add a frame to the game window if running windowed.
|
||||
|
34
dist/chuni/segatools.ini
vendored
34
dist/chuni/segatools.ini
vendored
@ -56,8 +56,6 @@ subnet=192.168.139.0
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
enable=1
|
||||
; Force the game to run windowed.
|
||||
windowed=1
|
||||
; Add a frame to the game window if running windowed.
|
||||
@ -65,6 +63,20 @@ framed=1
|
||||
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
||||
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
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -84,12 +96,10 @@ cabLedOutputSerial=0
|
||||
controllerLedOutputPipe=1
|
||||
; Output slider LED data to the serial port
|
||||
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.
|
||||
;serialPort=COM5
|
||||
; Baud rate for serial data (set to 115200 if using OpeNITHM)
|
||||
; Baud rate for serial data
|
||||
;serialBaud=921600
|
||||
|
||||
; Data output a sequence of bytes, with JVS-like framing.
|
||||
@ -112,20 +122,6 @@ controllerLedOutputOpeNITHM=0
|
||||
; [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
|
||||
; -----------------------------------------------------------------------------
|
||||
|
55
dist/chusan/segatools.ini
vendored
55
dist/chusan/segatools.ini
vendored
@ -25,7 +25,7 @@ aimePath=DEVICE\aime.txt
|
||||
;highBaud=1
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation. Disable to use a real VFD
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
@ -43,7 +43,6 @@ default=127.0.0.1
|
||||
; Chunithm is extremely picky about its LAN environment, so leaving this
|
||||
; setting enabled is strongly 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.32.0` and this value is set to `11`, then the
|
||||
; local host's virtualized LAN IP is `192.168.32.11`).
|
||||
@ -59,8 +58,8 @@ addrSuffix=11
|
||||
; that subnet must start with 192.168.
|
||||
subnet=192.168.139.0
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||
@ -82,8 +81,6 @@ dipsw3=1
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
enable=1
|
||||
; Force the game to run windowed.
|
||||
windowed=1
|
||||
; Add a frame to the game window if running windowed.
|
||||
@ -91,6 +88,25 @@ framed=0
|
||||
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
||||
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
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -110,12 +126,10 @@ cabLedOutputSerial=0
|
||||
controllerLedOutputPipe=1
|
||||
; Output slider LED data to the serial port
|
||||
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.
|
||||
;serialPort=COM5
|
||||
; Baud rate for serial data (set to 115200 if using OpeNITHM)
|
||||
; Baud rate for serial data
|
||||
;serialBaud=921600
|
||||
|
||||
; Data output a sequence of bytes, with JVS-like framing.
|
||||
@ -138,25 +152,6 @@ controllerLedOutputOpeNITHM=0
|
||||
; [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
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -206,3 +201,7 @@ ir=0x20
|
||||
; ... etc ...
|
||||
;cell31=0x53
|
||||
;cell32=0x53
|
||||
|
||||
; Enable slider LED serial output. This follows OpeNITHM Serial LED Protocol.
|
||||
; eg. COM5
|
||||
;ledport=
|
||||
|
16
dist/cm/segatools.ini
vendored
16
dist/cm/segatools.ini
vendored
@ -23,7 +23,7 @@ enable=1
|
||||
aimePath=DEVICE\aime.txt
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation. Disable to use a real VFD
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
@ -50,10 +50,10 @@ enable=1
|
||||
; 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.165.0
|
||||
subnet=192.168.100.0
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; LAN Install: If multiple machines are present on the same LAN then set
|
||||
@ -73,14 +73,6 @@ enable=0
|
||||
; 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
|
||||
; -----------------------------------------------------------------------------
|
||||
|
2
dist/cxb/segatools.ini
vendored
2
dist/cxb/segatools.ini
vendored
@ -75,8 +75,6 @@ path=../DEVICE/sram.bin
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
enable=1
|
||||
; Force the game to run windowed.
|
||||
windowed=1
|
||||
; Add a frame to the game window if running windowed.
|
||||
|
18
dist/diva/segatools.ini
vendored
18
dist/diva/segatools.ini
vendored
@ -5,7 +5,7 @@
|
||||
[vfs]
|
||||
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
|
||||
amfs=
|
||||
; Insert the path to the game Option (mdata) directory here (contains Mxxx directories)
|
||||
; Insert the path to the game Option directory here (contains Axxx directories)
|
||||
option=
|
||||
; Create an empty directory somewhere and insert the path here.
|
||||
; This directory may be shared between multiple SEGA games.
|
||||
@ -36,10 +36,6 @@ default=127.0.0.1
|
||||
; Chunithm is extremely picky about its LAN environment, so leaving this
|
||||
; setting enabled is strongly 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.32.0` and this value is set to `11`, then the
|
||||
; local host's virtualized LAN IP is `192.168.32.11`).
|
||||
addrSuffix=11
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Board settings
|
||||
@ -58,18 +54,6 @@ dipsw1=1
|
||||
; that subnet must start with 192.168.
|
||||
subnet=192.168.78.0
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Misc. hooks settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
enable=1
|
||||
; Force the game to run windowed.
|
||||
windowed=1
|
||||
; Add a frame to the game window if running windowed.
|
||||
framed=0
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Custom IO settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
15
dist/fgo/segatools.ini
vendored
15
dist/fgo/segatools.ini
vendored
@ -23,7 +23,7 @@ enable=1
|
||||
aimePath=DEVICE\aime.txt
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation. Disable to use a real VFD
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
@ -72,8 +72,8 @@ addrSuffix=11
|
||||
; that subnet must start with 192.168.
|
||||
subnet=192.168.167.0
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||
@ -85,14 +85,6 @@ freeplay=0
|
||||
; Misc. hook settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
enable=1
|
||||
; Force the game to run windowed.
|
||||
windowed=0
|
||||
; Add a frame to the game window if running windowed.
|
||||
framed=0
|
||||
|
||||
[touch]
|
||||
; WinTouch emulation setting.
|
||||
enable=1
|
||||
@ -136,6 +128,7 @@ path=
|
||||
; world. An improved solution will be provided later.
|
||||
|
||||
[io4]
|
||||
; Input API selection for JVS input emulator.
|
||||
; Test button virtual-key code. Default is the F1 key.
|
||||
test=0x70
|
||||
; Service button virtual-key code. Default is the F2 key.
|
||||
|
48
dist/idac/segatools.ini
vendored
48
dist/idac/segatools.ini
vendored
@ -54,8 +54,8 @@ subnet=192.168.158.0
|
||||
; 1: JPN: Japan, 4: EXP: Export (for Asian markets)
|
||||
region=4
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||
@ -75,30 +75,6 @@ dipsw3=0
|
||||
dipsw4=0
|
||||
dipsw5=0
|
||||
|
||||
[ffb]
|
||||
; Enable force feedback (838-15069) board emulation. This is required for
|
||||
; both DirectInput and XInput steering wheel effects.
|
||||
enable=1
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; 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
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -236,20 +212,6 @@ reverseAccelAxis=0
|
||||
reverseBrakeAxis=0
|
||||
|
||||
; Force feedback settings.
|
||||
; Only works when FFB board emulation is enabled!
|
||||
;
|
||||
; It is recommended to change the strength inside the Game Test Mode!
|
||||
;
|
||||
; These settings are only used when using DirectInput for the wheel.
|
||||
; The values are in the range 0%-100%, where 0 disables the effect and
|
||||
; 100 is the maximum.
|
||||
|
||||
; Constant force strength, used for centering spring effect.
|
||||
constantForceStrength=100
|
||||
; Damper strength, used for steering wheel damper effect.
|
||||
damperStrength=100
|
||||
|
||||
; Rumble strength, used for road surface effects.
|
||||
rumbleStrength=100
|
||||
; Rumble duration factor from ms to µs, used to scale the duration of the rumble effect.
|
||||
rumbleDuration=1000
|
||||
; Strength of the force feedback spring effect in percent. Possible values
|
||||
; are 0-100.
|
||||
centerSpringStrength=30
|
||||
|
34
dist/idz/segatools.ini
vendored
34
dist/idz/segatools.ini
vendored
@ -69,20 +69,6 @@ region=4
|
||||
; exactly one machine and set this to 0 on all others.
|
||||
dipsw1=1
|
||||
|
||||
[ffb]
|
||||
; Enable force feedback (838-15069) board emulation. This is required for
|
||||
; both DirectInput and XInput steering wheel effects.
|
||||
enable=1
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; LED settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[led15070]
|
||||
; Enable emulation of the 837-15070-02 controlled lights, which handle the
|
||||
; cabinet and seat LEDs.
|
||||
enable=1
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Misc. hooks settings
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -226,20 +212,6 @@ reverseAccelAxis=0
|
||||
reverseBrakeAxis=0
|
||||
|
||||
; Force feedback settings.
|
||||
; Only works when FFB board emulation is enabled!
|
||||
;
|
||||
; It is recommended to change the strength inside the Game Test Mode!
|
||||
;
|
||||
; These settings are only used when using DirectInput for the wheel.
|
||||
; The values are in the range 0%-100%, where 0 disables the effect and
|
||||
; 100 is the maximum.
|
||||
|
||||
; Constant force strength, used for centering spring effect.
|
||||
constantForceStrength=100
|
||||
; Damper strength, used for steering wheel damper effect.
|
||||
damperStrength=100
|
||||
|
||||
; Rumble strength, used for road surface effects.
|
||||
rumbleStrength=100
|
||||
; Rumble duration factor from ms to µs, used to scale the duration of the rumble effect.
|
||||
rumbleDuration=1000
|
||||
; Strength of the force feedback spring effect in percent. Possible values
|
||||
; are 0-100.
|
||||
centerSpringStrength=30
|
||||
|
5
dist/idz/start.bat
vendored
5
dist/idz/start.bat
vendored
@ -2,11 +2,10 @@
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
start /min "AM Daemon" inject -d -k idzhook.dll amdaemon.exe -c configDHCP_Final_Common.json configDHCP_Final_JP.json configDHCP_Final_JP_ST1.json configDHCP_Final_JP_ST2.json configDHCP_Final_EX.json configDHCP_Final_EX_ST1.json configDHCP_Final_EX_ST2.json
|
||||
|
||||
inject -k idzhook.dll InitialD0_DX11_Nu.exe
|
||||
rem Set dipsw1=0 and uncomment the ServerBox for in store battle?
|
||||
rem inject -k idzhook.dll ServerBoxD8_Nu_x64.exe
|
||||
inject -d -k idzhook.dll InitialD0_DX11_Nu.exe
|
||||
inject -d -k idzhook.dll amdaemon.exe -c configDHCP_Final_Common.json configDHCP_Final_JP.json configDHCP_Final_JP_ST1.json configDHCP_Final_JP_ST2.json configDHCP_Final_EX.json configDHCP_Final_EX_ST1.json configDHCP_Final_EX_ST2.json
|
||||
|
||||
taskkill /im ServerBoxD8_Nu_x64.exe > nul 2>&1
|
||||
|
||||
|
150
dist/kemono/segatools.ini
vendored
150
dist/kemono/segatools.ini
vendored
@ -1,150 +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 Axxx 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=
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Device settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[aime]
|
||||
; Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
|
||||
; reader.
|
||||
enable=1
|
||||
aimePath=DEVICE\aime.txt
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; 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 its 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.32.0` and this value is set to `11`, then the
|
||||
; local host's virtualized LAN IP is `192.168.32.11`).
|
||||
addrSuffix=11
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; 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.179.0
|
||||
|
||||
[gpio]
|
||||
; Emulated Nu DIP switch for Distribution Server setting.
|
||||
;
|
||||
; If multiple machines are present on the same LAN then set this to 1 on
|
||||
; exactly one machine and set this to 0 on all others.
|
||||
dipsw1=1
|
||||
|
||||
; Chassis Test button virtual-key code. Default is the 4 key.
|
||||
test=0x34
|
||||
; Chassis Service button virtual-key code. Default is the 5 key.
|
||||
service=0x35
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; 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.
|
||||
;
|
||||
; NOTE: For Kemono Friends, BepInEx (or similar) should be installed to the main folder, not the "UnityApp" folder.
|
||||
targetAssembly=
|
||||
|
||||
[printer]
|
||||
; Sinfonia CHC-C300 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"
|
||||
; The length in milliseconds the printer should be busy printing.
|
||||
; Set to 0 to instantly finish printing.
|
||||
waitTime=20000
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; LED settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[led15093]
|
||||
; 837-15093-06 LED board emulation setting.
|
||||
enable=1
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; 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=
|
||||
|
||||
[kemonoio]
|
||||
; To use a custom Kemono IO DLL enter its path here.
|
||||
; Leave empty if you want to use Segatools built-in keyboard 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.
|
||||
|
||||
[io3]
|
||||
; Test button virtual-key code. Default is the 1 key.
|
||||
test=0x31
|
||||
; Service button virtual-key code. Default is the 2 key.
|
||||
service=0x32
|
||||
; Keyboard button to increment coin counter. Default is the 3 key.
|
||||
coin=0x33
|
||||
|
||||
; Analog lever (which is actually just four buttons, and not real analog input, default: Arrow keys)
|
||||
left=0x25
|
||||
right=0x27
|
||||
up=0x26
|
||||
down=0x28
|
||||
|
||||
; Controller face buttons (default A, S, D)
|
||||
red=0x41
|
||||
green=0x53
|
||||
blue=0x44
|
||||
|
||||
; Menu confirmation key (default RETURN)
|
||||
start=0x0D
|
12
dist/kemono/start.bat
vendored
12
dist/kemono/start.bat
vendored
@ -1,12 +0,0 @@
|
||||
@echo off
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
start "AM Daemon" /min inject_x64 -d -k kemonohook_x64.dll amdaemon.exe -c config.json
|
||||
inject_x86 -d -k kemonohook_x86.dll UnityApp\Parade -screen-fullscreen 0 -popupwindow -screen-width 720 -screen-height 1280 -silent-crashes
|
||||
|
||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
||||
|
||||
echo.
|
||||
echo Game processes have terminated
|
||||
pause
|
27
dist/mai2/segatools.ini
vendored
27
dist/mai2/segatools.ini
vendored
@ -23,7 +23,7 @@ enable=1
|
||||
aimePath=DEVICE\aime.txt
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation. Disable to use a real VFD
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
@ -56,8 +56,8 @@ addrSuffix=11
|
||||
; that subnet must start with 192.168.
|
||||
subnet=192.168.172.0
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; 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.
|
||||
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
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -95,6 +83,15 @@ path=
|
||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||
path=
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Misc. hook settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[unity]
|
||||
; Path to a .NET DLL that should run before the game. Useful for loading
|
||||
; modding frameworks such as BepInEx.
|
||||
targetAssembly=
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Input settings
|
||||
; -----------------------------------------------------------------------------
|
||||
|
7
dist/mercury/segatools.ini
vendored
7
dist/mercury/segatools.ini
vendored
@ -23,7 +23,7 @@ enable=1
|
||||
aimePath=DEVICE\aime.txt
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation. Disable to use a real VFD
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
@ -56,8 +56,8 @@ addrSuffix=11
|
||||
; that subnet must start with 192.168.
|
||||
subnet=192.168.174.0
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||
@ -74,7 +74,6 @@ dipsw1=1
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
enable=1
|
||||
|
||||
; Hooks related to the touch boards
|
||||
|
60
dist/mu3/segatools.ini
vendored
60
dist/mu3/segatools.ini
vendored
@ -23,7 +23,7 @@ enable=1
|
||||
aimePath=DEVICE\aime.txt
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation. Disable to use a real VFD
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
@ -52,8 +52,8 @@ enable=1
|
||||
; that subnet must start with 192.168.
|
||||
subnet=192.168.162.0
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||
@ -70,65 +70,13 @@ dipsw1=1
|
||||
; -----------------------------------------------------------------------------
|
||||
|
||||
[gfx]
|
||||
; Enables the graphics hook.
|
||||
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
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -191,7 +139,7 @@ leftSide=0x01 ; Mouse Left
|
||||
rightSide=0x02 ; Mouse Right
|
||||
|
||||
right1=0x4A ; J
|
||||
right2=0x4B ; K
|
||||
right1=0x4B ; K
|
||||
right3=0x4C ; L
|
||||
|
||||
leftMenu=0x55 ; U
|
||||
|
31
dist/swdc/segatools.ini
vendored
31
dist/swdc/segatools.ini
vendored
@ -23,7 +23,7 @@ enable=1
|
||||
aimePath=DEVICE\aime.txt
|
||||
|
||||
[vfd]
|
||||
; Enable VFD emulation. Disable to use a real VFD
|
||||
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
; GP1232A02A FUTABA assembly.
|
||||
enable=1
|
||||
|
||||
@ -56,8 +56,8 @@ addrSuffix=11
|
||||
; in order to find the MAIN cabinet.
|
||||
subnet=192.168.160.0
|
||||
|
||||
[system]
|
||||
; Enable ALLS system settings.
|
||||
[gpio]
|
||||
; ALLS DIP switches.
|
||||
enable=1
|
||||
|
||||
; Enable freeplay mode. This will disable the coin slot and set the game to
|
||||
@ -65,11 +65,6 @@ enable=1
|
||||
; allow you to start a game in freeplay mode.
|
||||
freeplay=0
|
||||
|
||||
[ffb]
|
||||
; Enable force feedback (838-15069) board emulation. This is required for
|
||||
; both DirectInput and XInput steering wheel effects.
|
||||
enable=1
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Custom IO settings
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -186,20 +181,6 @@ reverseAccelAxis=0
|
||||
reverseBrakeAxis=0
|
||||
|
||||
; Force feedback settings.
|
||||
; Only works when FFB board emulation is enabled!
|
||||
;
|
||||
; It is recommended to change the strength inside the Game Test Mode!
|
||||
;
|
||||
; These settings are only used when using DirectInput for the wheel.
|
||||
; The values are in the range 0%-100%, where 0 disables the effect and
|
||||
; 100 is the maximum.
|
||||
|
||||
; Constant force strength, used for centering spring effect.
|
||||
constantForceStrength=100
|
||||
; Damper strength, used for steering wheel damper effect.
|
||||
damperStrength=100
|
||||
|
||||
; Rumble strength, used for road surface effects.
|
||||
rumbleStrength=100
|
||||
; Rumble duration factor from ms to µs, used to scale the duration of the rumble effect.
|
||||
rumbleDuration=1000
|
||||
; Strength of the force feedback spring effect in percent. Possible values
|
||||
; are 0-100.
|
||||
centerSpringStrength=30
|
||||
|
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
|
@ -8,9 +8,6 @@
|
||||
#include "board/config.h"
|
||||
#include "board/sg-reader.h"
|
||||
|
||||
#include "hooklib/config.h"
|
||||
#include "hooklib/dvd.h"
|
||||
|
||||
#include "divahook/config.h"
|
||||
|
||||
#include "platform/config.h"
|
||||
@ -50,8 +47,6 @@ void diva_hook_config_load(
|
||||
platform_config_load(&cfg->platform, filename);
|
||||
amex_config_load(&cfg->amex, filename);
|
||||
aime_config_load(&cfg->aime, filename);
|
||||
dvd_config_load(&cfg->dvd, filename);
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
diva_dll_config_load(&cfg->dll, filename);
|
||||
slider_config_load(&cfg->slider, filename);
|
||||
}
|
||||
|
@ -6,25 +6,15 @@
|
||||
|
||||
#include "board/sg-reader.h"
|
||||
|
||||
#include "hooklib/dvd.h"
|
||||
#include "hooklib/touch.h"
|
||||
|
||||
#include "gfxhook/config.h"
|
||||
|
||||
#include "platform/config.h"
|
||||
|
||||
#include "divahook/3mpxsc.h"
|
||||
#include "divahook/diva-dll.h"
|
||||
#include "divahook/slider.h"
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
struct diva_hook_config {
|
||||
struct platform_config platform;
|
||||
struct amex_config amex;
|
||||
struct aime_config aime;
|
||||
struct dvd_config dvd;
|
||||
struct gfx_config gfx;
|
||||
struct touch3mpxsc_config touch3mpxsc;
|
||||
struct touch_screen_config touch;
|
||||
struct diva_dll_config dll;
|
||||
struct slider_config slider;
|
||||
};
|
||||
|
@ -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 <stdlib.h>
|
||||
@ -22,9 +11,6 @@
|
||||
#include "divahook/jvs.h"
|
||||
#include "divahook/slider.h"
|
||||
|
||||
#include "gfxhook/gfx.h"
|
||||
#include "gfxhook/gl.h"
|
||||
|
||||
#include "hook/process.h"
|
||||
|
||||
#include "hooklib/serial.h"
|
||||
@ -41,30 +27,15 @@ static struct diva_hook_config diva_hook_cfg;
|
||||
static DWORD CALLBACK diva_pre_startup(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
HMODULE dbghelp;
|
||||
|
||||
dprintf("--- Begin diva_pre_startup ---\n");
|
||||
|
||||
/* Pin dbghelp so the path hooks apply to it. */
|
||||
|
||||
dbghelp = LoadLibraryW(L"dbghelp.dll");
|
||||
|
||||
if (dbghelp != NULL) {
|
||||
dprintf("Pinned debug helper library, hMod=%p\n", dbghelp);
|
||||
}
|
||||
else {
|
||||
dprintf("Failed to load debug helper library!\n");
|
||||
}
|
||||
|
||||
/* Config load */
|
||||
|
||||
diva_hook_config_load(&diva_hook_cfg, L".\\segatools.ini");
|
||||
|
||||
/* Hook Win32 APIs */
|
||||
|
||||
dvd_hook_init(&diva_hook_cfg.dvd, diva_hook_mod);
|
||||
gfx_hook_init(&diva_hook_cfg.gfx);
|
||||
gfx_gl_hook_init(&diva_hook_cfg.gfx, diva_hook_mod);
|
||||
serial_hook_init();
|
||||
|
||||
/* Initialize emulation hooks */
|
||||
|
@ -63,33 +63,33 @@ static void diva_jvs_read_switches(void *ctx, struct io3_switch_state *out)
|
||||
|
||||
diva_dll.jvs_poll(&opbtn, &gamebtn);
|
||||
|
||||
if (gamebtn & DIVA_IO_GAMEBTN_CIRCLE) {
|
||||
if (gamebtn & 0x01) {
|
||||
out->p1 |= 1 << 6;
|
||||
}
|
||||
|
||||
if (gamebtn & DIVA_IO_GAMEBTN_CROSS) {
|
||||
if (gamebtn & 0x02) {
|
||||
out->p1 |= 1 << 7;
|
||||
}
|
||||
|
||||
if (gamebtn & DIVA_IO_GAMEBTN_SQUARE) {
|
||||
if (gamebtn & 0x04) {
|
||||
out->p1 |= 1 << 8;
|
||||
}
|
||||
|
||||
if (gamebtn & DIVA_IO_GAMEBTN_TRIANGLE) {
|
||||
if (gamebtn & 0x08) {
|
||||
out->p1 |= 1 << 9;
|
||||
}
|
||||
|
||||
if (gamebtn & DIVA_IO_GAMEBTN_START) {
|
||||
if (gamebtn & 0x10) {
|
||||
out->p1 |= 1 << 15;
|
||||
}
|
||||
|
||||
if (opbtn & DIVA_IO_OPBTN_TEST) {
|
||||
if (opbtn & 0x01) {
|
||||
out->system = 0x80;
|
||||
} else {
|
||||
out->system = 0;
|
||||
}
|
||||
|
||||
if (opbtn & DIVA_IO_OPBTN_SERVICE) {
|
||||
if (opbtn & 0x02) {
|
||||
out->p1 |= 1 << 14;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ shared_library(
|
||||
amex_lib,
|
||||
board_lib,
|
||||
divaio_lib,
|
||||
gfxhook_lib,
|
||||
hooklib_lib,
|
||||
jvs_lib,
|
||||
platform_lib,
|
||||
|
@ -99,7 +99,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if defined(LOG_DIVA_SLIDER)
|
||||
#if 0
|
||||
dprintf("TX Buffer:\n");
|
||||
dump_iobuf(&slider_uart.written);
|
||||
#endif
|
||||
@ -118,7 +118,7 @@ static HRESULT slider_handle_irp_locked(struct irp *irp)
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if defined(LOG_DIVA_SLIDER)
|
||||
#if 0
|
||||
dprintf("Deframe Buffer:\n");
|
||||
dump_iobuf(&req_iobuf);
|
||||
#endif
|
||||
|
@ -37,11 +37,11 @@ void diva_io_jvs_poll(uint8_t *opbtn_out, uint8_t *gamebtn_out)
|
||||
opbtn = 0;
|
||||
|
||||
if (GetAsyncKeyState(diva_io_cfg.vk_test) & 0x8000) {
|
||||
opbtn |= DIVA_IO_OPBTN_TEST;
|
||||
opbtn |= 1;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(diva_io_cfg.vk_service) & 0x8000) {
|
||||
opbtn |= DIVA_IO_OPBTN_SERVICE;
|
||||
opbtn |= 2;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < _countof(diva_io_cfg.vk_buttons) ; i++) {
|
||||
|
@ -5,19 +5,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
DIVA_IO_OPBTN_TEST = 0x01,
|
||||
DIVA_IO_OPBTN_SERVICE = 0x02
|
||||
};
|
||||
|
||||
enum {
|
||||
DIVA_IO_GAMEBTN_CIRCLE = 0x01,
|
||||
DIVA_IO_GAMEBTN_CROSS = 0x02,
|
||||
DIVA_IO_GAMEBTN_SQUARE = 0x04,
|
||||
DIVA_IO_GAMEBTN_TRIANGLE = 0x08,
|
||||
DIVA_IO_GAMEBTN_START = 0x10,
|
||||
};
|
||||
|
||||
/* Get the version of the Project Diva IO API that this DLL supports. This
|
||||
function should return a positive 16-bit integer, where the high byte is
|
||||
the major version and the low byte is the minor version (as defined by the
|
||||
|
@ -92,21 +92,9 @@ Controls emulation of the VFD GP1232A02A FUTABA assembly.
|
||||
|
||||
Default: `1`
|
||||
|
||||
Enable VFD emulation. Disable to use a real VFD
|
||||
Enable VFD emulation (currently just stubbed). Disable to use a real VFD
|
||||
GP1232A02A FUTABA assembly (COM port number varies by game).
|
||||
|
||||
### `portNo`
|
||||
|
||||
Default: (game specific)
|
||||
|
||||
Sets the COM port to use for the VFD.
|
||||
|
||||
### `utfConversion`
|
||||
|
||||
Default: `0`
|
||||
|
||||
Converts the strings from the VFD from their respective encoding to UTF, so console output will display as it should on non-Japanese locales.
|
||||
|
||||
## `[amvideo]`
|
||||
|
||||
Controls the `amvideo.dll` stub built into Segatools. This is a DLL that is
|
||||
@ -364,7 +352,7 @@ Enable keychip emulation. Disable to use a real keychip.
|
||||
Default: `A69E-01A88888888`
|
||||
|
||||
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`
|
||||
|
||||
|
@ -122,6 +122,5 @@ void fgo_hook_config_load(
|
||||
fgo_deck_config_load(&cfg->deck, filename);
|
||||
ftdi_config_load(&cfg->ftdi, filename);
|
||||
led15093_config_load(&cfg->led15093, filename);
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
fgo_dll_config_load(&cfg->dll, filename);
|
||||
}
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include "hooklib/touch.h"
|
||||
#include "hooklib/printer.h"
|
||||
|
||||
#include "gfxhook/config.h"
|
||||
|
||||
#include "fgohook/deck.h"
|
||||
#include "fgohook/ftdi.h"
|
||||
#include "fgohook/fgo-dll.h"
|
||||
@ -28,7 +26,6 @@ struct fgo_hook_config {
|
||||
struct deck_config deck;
|
||||
struct ftdi_config ftdi;
|
||||
struct led15093_config led15093;
|
||||
struct gfx_config gfx;
|
||||
struct fgo_dll_config dll;
|
||||
};
|
||||
|
||||
|
@ -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 <stdlib.h>
|
||||
@ -26,7 +9,6 @@
|
||||
|
||||
#include "hook/process.h"
|
||||
|
||||
#include "hooklib/dll.h"
|
||||
#include "hooklib/dvd.h"
|
||||
#include "hooklib/touch.h"
|
||||
#include "hooklib/printer.h"
|
||||
@ -34,8 +16,6 @@
|
||||
#include "hooklib/serial.h"
|
||||
#include "hooklib/spike.h"
|
||||
|
||||
#include "gfxhook/gfx.h"
|
||||
|
||||
#include "fgohook/config.h"
|
||||
#include "fgohook/io4.h"
|
||||
#include "fgohook/fgo-dll.h"
|
||||
@ -52,21 +32,9 @@ static struct fgo_hook_config fgo_hook_cfg;
|
||||
static DWORD CALLBACK fgo_pre_startup(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
HMODULE dbghelp;
|
||||
|
||||
dprintf("--- Begin fgo_pre_startup ---\n");
|
||||
|
||||
/* Pin dbghelp so the path hooks apply to it. */
|
||||
|
||||
dbghelp = LoadLibraryW(L"dbghelp.dll");
|
||||
|
||||
if (dbghelp != NULL) {
|
||||
dprintf("Pinned debug helper library, hMod=%p\n", dbghelp);
|
||||
}
|
||||
else {
|
||||
dprintf("Failed to load debug helper library!\n");
|
||||
}
|
||||
|
||||
/* Load config */
|
||||
|
||||
fgo_hook_config_load(&fgo_hook_cfg, L".\\segatools.ini");
|
||||
@ -74,15 +42,12 @@ static DWORD CALLBACK fgo_pre_startup(void)
|
||||
/* Hook Win32 APIs */
|
||||
|
||||
dvd_hook_init(&fgo_hook_cfg.dvd, fgo_hook_mod);
|
||||
gfx_hook_init(&fgo_hook_cfg.gfx);
|
||||
touch_screen_hook_init(&fgo_hook_cfg.touch, fgo_hook_mod);
|
||||
serial_hook_init();
|
||||
|
||||
/* Hook external DLL APIs */
|
||||
|
||||
printer_hook_init(&fgo_hook_cfg.printer, 4, fgo_hook_mod);
|
||||
dll_hook_push(fgo_hook_mod, L"C330Ausb.dll");
|
||||
dll_hook_push(fgo_hook_mod, L"C330AFWDLusb.dll");
|
||||
|
||||
/* Initialize emulation hooks */
|
||||
|
||||
|
@ -28,7 +28,7 @@ const struct dll_bind_sym fgo_dll_syms[] = {
|
||||
.sym = "fgo_io_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),
|
||||
}
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ EXPORTS
|
||||
fgo_io_init
|
||||
fgo_io_poll
|
||||
fgo_io_led_init
|
||||
fgo_io_led_set_colors
|
||||
fgo_io_led_set_leds
|
||||
fwdlusb_open
|
||||
fwdlusb_close
|
||||
fwdlusb_listupPrinter
|
||||
@ -44,7 +44,7 @@ EXPORTS
|
||||
chcusb_selectPrinter
|
||||
chcusb_selectPrinterSN
|
||||
chcusb_getPrinterInfo
|
||||
chcusb_imageformat=chcusb_imageformat_330
|
||||
chcusb_imageformat
|
||||
chcusb_setmtf
|
||||
chcusb_makeGamma
|
||||
chcusb_setIcctable
|
||||
|
@ -13,7 +13,6 @@ shared_library(
|
||||
link_with : [
|
||||
aimeio_lib,
|
||||
board_lib,
|
||||
gfxhook_lib,
|
||||
hooklib_lib,
|
||||
fgoio_lib,
|
||||
platform_lib,
|
||||
|
@ -145,7 +145,7 @@ HRESULT fgo_io_led_init(void)
|
||||
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;
|
||||
}
|
||||
}
|
@ -52,12 +52,16 @@ HRESULT fgo_io_poll(void);
|
||||
void fgo_io_get_opbtns(uint8_t *opbtn);
|
||||
|
||||
/* 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
|
||||
states returned in *gamebtn. All buttons are active-high.
|
||||
FGO_IO_GAMEBTN enum above for bit mask definitions. Inputs are split into
|
||||
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 */
|
||||
|
||||
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
|
||||
position should be equal to or close to 32767.
|
||||
@ -79,4 +83,4 @@ HRESULT fgo_io_led_init(void);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
UINT max_adapter = IDirect3D9_GetAdapterCount(real);
|
||||
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);
|
||||
}
|
||||
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(
|
||||
|
@ -9,53 +9,18 @@
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
/* Hook functions */
|
||||
typedef BOOL (WINAPI *ShowWindow_t)(HWND hWnd, int nCmdShow);
|
||||
|
||||
static BOOL WINAPI hook_ShowWindow(HWND hWnd, int nCmdShow);
|
||||
static BOOL WINAPI hook_CreateWindowExA(
|
||||
DWORD dwExStyle,
|
||||
LPCSTR lpClassName,
|
||||
LPCSTR lpWindowName,
|
||||
DWORD dwStyle,
|
||||
int X,
|
||||
int Y,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
HWND hWndParent,
|
||||
HMENU hMenu,
|
||||
HINSTANCE hInstance,
|
||||
LPVOID lpParam
|
||||
);
|
||||
|
||||
/* Link pointers */
|
||||
|
||||
static BOOL (WINAPI *next_ShowWindow)(HWND hWnd, int nCmdShow);
|
||||
static BOOL (WINAPI *next_CreateWindowExA)(
|
||||
DWORD dwExStyle,
|
||||
LPCSTR lpClassName,
|
||||
LPCSTR lpWindowName,
|
||||
DWORD dwStyle,
|
||||
int X,
|
||||
int Y,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
HWND hWndParent,
|
||||
HMENU hMenu,
|
||||
HINSTANCE hInstance,
|
||||
LPVOID lpParam
|
||||
);
|
||||
|
||||
static struct gfx_config gfx_config;
|
||||
static ShowWindow_t next_ShowWindow;
|
||||
|
||||
static const struct hook_symbol gfx_hooks[] = {
|
||||
{
|
||||
.name = "ShowWindow",
|
||||
.patch = hook_ShowWindow,
|
||||
.link = (void **) &next_ShowWindow,
|
||||
}, {
|
||||
.name = "CreateWindowExA",
|
||||
.patch = hook_CreateWindowExA,
|
||||
.link = (void **) &next_CreateWindowExA,
|
||||
},
|
||||
};
|
||||
|
||||
@ -81,45 +46,3 @@ static BOOL WINAPI hook_ShowWindow(HWND hWnd, int nCmdShow)
|
||||
|
||||
return next_ShowWindow(hWnd, nCmdShow);
|
||||
}
|
||||
|
||||
static BOOL WINAPI hook_CreateWindowExA(
|
||||
DWORD dwExStyle,
|
||||
LPCSTR lpClassName,
|
||||
LPCSTR lpWindowName,
|
||||
DWORD dwStyle,
|
||||
int X,
|
||||
int Y,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
HWND hWndParent,
|
||||
HMENU hMenu,
|
||||
HINSTANCE hInstance,
|
||||
LPVOID lpParam
|
||||
)
|
||||
{
|
||||
dprintf("Gfx: CreateWindowExA hook hit\n");
|
||||
|
||||
// Set to WS_OVERLAPPEDWINDOW to enable a window with a border and windowed style
|
||||
if (gfx_config.windowed) {
|
||||
dwStyle = WS_OVERLAPPEDWINDOW;
|
||||
|
||||
if (!gfx_config.framed) {
|
||||
dwStyle = WS_POPUP;
|
||||
}
|
||||
}
|
||||
|
||||
return next_CreateWindowExA(
|
||||
dwExStyle,
|
||||
lpClassName,
|
||||
lpWindowName,
|
||||
dwStyle,
|
||||
X,
|
||||
Y,
|
||||
nWidth,
|
||||
nHeight,
|
||||
hWndParent,
|
||||
hMenu,
|
||||
hInstance,
|
||||
lpParam
|
||||
);
|
||||
}
|
||||
|
77
gfxhook/gl.c
77
gfxhook/gl.c
@ -1,77 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gfxhook/gfx.h"
|
||||
#include "gfxhook/gl.h"
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "hooklib/dll.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
/* Hook functions */
|
||||
|
||||
static void WINAPI hook_glutFullScreen(void);
|
||||
static void WINAPI hook_glutInitDisplayMode(unsigned int mode);
|
||||
|
||||
/* Link pointers */
|
||||
|
||||
static void (WINAPI *next_glutFullScreen)(void);
|
||||
static void (WINAPI *next_glutInitDisplayMode)(unsigned int mode);
|
||||
|
||||
static struct gfx_config gfx_config;
|
||||
|
||||
static const struct hook_symbol glut_hooks[] = {
|
||||
{
|
||||
.name = "glutFullScreen",
|
||||
.patch = hook_glutFullScreen,
|
||||
.link = (void **) &next_glutFullScreen,
|
||||
}, {
|
||||
.name = "glutInitDisplayMode",
|
||||
.patch = hook_glutInitDisplayMode,
|
||||
.link = (void **) &next_glutInitDisplayMode,
|
||||
},
|
||||
};
|
||||
|
||||
void gfx_gl_hook_init(const struct gfx_config *cfg, HINSTANCE self)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&gfx_config, cfg, sizeof(*cfg));
|
||||
hook_table_apply(NULL, "glut32.dll", glut_hooks, _countof(glut_hooks));
|
||||
|
||||
if (self != NULL) {
|
||||
dll_hook_push(self, L"glut32.dll");
|
||||
}
|
||||
}
|
||||
|
||||
static void WINAPI hook_glutFullScreen(void)
|
||||
{
|
||||
dprintf("Gfx: glutFullScreen hook hit\n");
|
||||
|
||||
if (gfx_config.windowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
return next_glutFullScreen();
|
||||
}
|
||||
|
||||
static void WINAPI hook_glutInitDisplayMode(unsigned int mode)
|
||||
{
|
||||
dprintf("Gfx: glutInitDisplayMode hook hit\n");
|
||||
|
||||
// GLUT adds a frame when going windowed
|
||||
if (gfx_config.windowed && !gfx_config.framed) {
|
||||
// GLUT_BORDERLESS
|
||||
mode |= 0x0800;
|
||||
}
|
||||
|
||||
return next_glutInitDisplayMode(mode);
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
void gfx_gl_hook_init(const struct gfx_config *cfg, HINSTANCE self);
|
@ -22,8 +22,6 @@ gfxhook_lib = static_library(
|
||||
'dxgi.h',
|
||||
'gfx.c',
|
||||
'gfx.h',
|
||||
'gl.c',
|
||||
'gl.h',
|
||||
'util.c',
|
||||
'util.h',
|
||||
],
|
||||
|
@ -80,6 +80,4 @@ void printer_config_load(struct printer_config *cfg, const wchar_t *filename)
|
||||
cfg->printer_out_path,
|
||||
_countof(cfg->printer_out_path),
|
||||
filename);
|
||||
|
||||
cfg->wait_time = GetPrivateProfileIntW(L"printer", L"waitTime", 0, filename);
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ hooklib_lib = static_library(
|
||||
'fdshark.h',
|
||||
'path.c',
|
||||
'path.h',
|
||||
'procaddr.c',
|
||||
'procaddr.h',
|
||||
'reg.c',
|
||||
'reg.h',
|
||||
'setupapi.c',
|
||||
|
1974
hooklib/printer.c
1974
hooklib/printer.c
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,6 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct printer_config {
|
||||
bool enable;
|
||||
@ -12,13 +11,6 @@ struct printer_config {
|
||||
wchar_t dsp_fw_path[MAX_PATH];
|
||||
wchar_t param_fw_path[MAX_PATH];
|
||||
wchar_t printer_out_path[MAX_PATH];
|
||||
uint32_t wait_time;
|
||||
};
|
||||
|
||||
void printer_hook_init(const struct printer_config *cfg, int rfid_port_no, HINSTANCE self);
|
||||
void printer_hook_insert_hooks(HMODULE target);
|
||||
|
||||
void printer_set_dimensions(int width, int height);
|
||||
int WINAPI fwdlusb_updateFirmware_main(uint8_t update, LPCSTR filename, uint16_t *rResult);
|
||||
int WINAPI fwdlusb_updateFirmware_dsp(uint8_t update, LPCSTR filename, uint16_t *rResult);
|
||||
int WINAPI fwdlusb_updateFirmware_param(uint8_t update, LPCSTR filename, uint16_t *rResult);
|
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
|
||||
);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user