mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-21 21:00:02 +01:00
sdvxhook2-cn: sdvx5 cn support
This commit is contained in:
parent
214a31b24d
commit
6d638ff1ae
16
Module.mk
16
Module.mk
@ -136,6 +136,7 @@ include src/main/p4ioemu/Module.mk
|
||||
include src/main/pcbidgen/Module.mk
|
||||
include src/main/sdvxhook/Module.mk
|
||||
include src/main/sdvxhook2/Module.mk
|
||||
include src/main/sdvxhook2-cn/Module.mk
|
||||
include src/main/sdvxio/Module.mk
|
||||
include src/main/sdvxio-kfca/Module.mk
|
||||
include src/main/security/Module.mk
|
||||
@ -436,6 +437,20 @@ $(zipdir)/sdvx-05.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/sdvx-05-cn.zip: \
|
||||
build/bin/avs2_1700-64/launcher.exe \
|
||||
build/bin/avs2_1700-64/sdvxhook2-cn.dll \
|
||||
build/bin/indep-64/config.exe \
|
||||
build/bin/indep-64/eamio.dll \
|
||||
build/bin/indep-64/geninput.dll \
|
||||
build/bin/indep-64/sdvxio.dll \
|
||||
dist/sdvx5/config.bat \
|
||||
dist/sdvx5/gamestart-cn.bat \
|
||||
dist/sdvx5/sdvxhook2-cn.conf \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/ddr-12-to-16.zip: \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/avs2_1508-32/ddrhook.dll \
|
||||
@ -523,6 +538,7 @@ $(BUILDDIR)/bemanitools.zip: \
|
||||
$(zipdir)/src.zip \
|
||||
$(zipdir)/sdvx-01-to-04.zip \
|
||||
$(zipdir)/sdvx-05.zip \
|
||||
$(zipdir)/sdvx-05-cn.zip \
|
||||
$(zipdir)/tools.zip \
|
||||
$(zipdir)/tools-x64.zip \
|
||||
CHANGELOG.md \
|
||||
|
17
dist/sdvx5/gamestart-cn.bat
vendored
Normal file
17
dist/sdvx5/gamestart-cn.bat
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
@echo off
|
||||
cd /d %~dp0
|
||||
|
||||
if not exist dev mkdir dev
|
||||
if not exist dev\e mkdir dev\e
|
||||
if not exist dev\g mkdir dev\g
|
||||
if not exist dev\nvram mkdir dev\nvram
|
||||
if not exist dev\raw mkdir dev\raw
|
||||
if not exist dev\raw\c.dest echo $null >> dev\raw\c.dest
|
||||
if not exist dev\raw\log mkdir dev\raw\log
|
||||
if not exist dev\raw\fscache mkdir dev\raw\fscache
|
||||
|
||||
for /R prop\defaults %%D in (*.*) do (
|
||||
if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram
|
||||
)
|
||||
|
||||
launcher -H 268435456 -K sdvxhook2-cn.dll soundvoltex.dll --config sdvxhook2-cn.conf %*
|
24
dist/sdvx5/sdvxhook2-cn.conf
vendored
Normal file
24
dist/sdvx5/sdvxhook2-cn.conf
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Disable IO emulation and enable usage of real KFCA hardware
|
||||
io.disable_io_emu=false
|
||||
|
||||
# Path to unis version file under the prop.s folder
|
||||
cn.unis_path=prop/unis.xml
|
||||
|
||||
# Run the game in a framed window (requires windowed option)
|
||||
gfx.framed=true
|
||||
|
||||
# Run the game windowed
|
||||
gfx.windowed=false
|
||||
|
||||
# Windowed width, -1 for default size
|
||||
gfx.window_width=720
|
||||
|
||||
# Windowed height, -1 for default size
|
||||
gfx.window_height=1280
|
||||
|
||||
# Disables the camera emulation
|
||||
cam.disable_emu=false
|
||||
|
||||
# Override camera device ID detection (copy from device manager, do not escape)
|
||||
cam.device_id1=
|
||||
|
29
src/main/sdvxhook2-cn/Module.mk
Normal file
29
src/main/sdvxhook2-cn/Module.mk
Normal file
@ -0,0 +1,29 @@
|
||||
avsdlls += sdvxhook2-cn
|
||||
|
||||
ldflags_sdvxhook2-cn := \
|
||||
-liphlpapi \
|
||||
-lsetupapi \
|
||||
-lcfgmgr32 \
|
||||
-lmf \
|
||||
-lmfplat \
|
||||
-lole32 \
|
||||
|
||||
deplibs_sdvxhook2-cn := \
|
||||
avs \
|
||||
|
||||
libs_sdvxhook2-cn := \
|
||||
acioemu \
|
||||
camhook \
|
||||
d3d9exhook \
|
||||
sdvxio \
|
||||
hook \
|
||||
hooklib \
|
||||
cconfig \
|
||||
util \
|
||||
|
||||
src_sdvxhook2-cn := \
|
||||
acio.c \
|
||||
kfca.c \
|
||||
dllmain.c \
|
||||
config-cn.c \
|
||||
unis-version.c \
|
92
src/main/sdvxhook2-cn/acio.c
Normal file
92
src/main/sdvxhook2-cn/acio.c
Normal file
@ -0,0 +1,92 @@
|
||||
// clang-format off
|
||||
// Don't format because the order is important here
|
||||
#include <windows.h>
|
||||
#include <devioctl.h>
|
||||
#include <ntdef.h>
|
||||
#include <ntddser.h>
|
||||
// clang-format on
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "acioemu/addr.h"
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
#include "hooklib/rs232.h"
|
||||
|
||||
#include "sdvxhook2-cn/acio.h"
|
||||
#include "sdvxhook2-cn/kfca.h"
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/iobuf.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static struct ac_io_emu ac_io_emu;
|
||||
|
||||
void ac_io_port_init(void)
|
||||
{
|
||||
ac_io_emu_init(&ac_io_emu, L"\\\\.\\COM2");
|
||||
|
||||
kfca_init(&ac_io_emu);
|
||||
|
||||
rs232_hook_add_fd(ac_io_emu.fd);
|
||||
}
|
||||
|
||||
void ac_io_port_fini(void)
|
||||
{
|
||||
ac_io_emu_fini(&ac_io_emu);
|
||||
}
|
||||
|
||||
HRESULT ac_io_port_dispatch_irp(struct irp *irp)
|
||||
{
|
||||
const struct ac_io_message *msg;
|
||||
HRESULT hr;
|
||||
|
||||
log_assert(irp != NULL);
|
||||
|
||||
if (!ac_io_emu_match_irp(&ac_io_emu, irp)) {
|
||||
return irp_invoke_next(irp);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
hr = ac_io_emu_dispatch_irp(&ac_io_emu, irp);
|
||||
|
||||
if (hr != S_OK) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
msg = ac_io_emu_request_peek(&ac_io_emu);
|
||||
|
||||
switch (msg->addr) {
|
||||
case 0:
|
||||
ac_io_emu_cmd_assign_addrs(&ac_io_emu, msg, 1);
|
||||
log_warning("ac_io_emu_cmd_assign_addrs");
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
kfca_dispatch_request(msg);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_BROADCAST:
|
||||
log_warning("Broadcast? (0x70) message on ACIO bus");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
log_warning(
|
||||
"ACIO message on unhandled bus address: %d", msg->addr);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ac_io_emu_request_pop(&ac_io_emu);
|
||||
}
|
||||
}
|
14
src/main/sdvxhook2-cn/acio.h
Normal file
14
src/main/sdvxhook2-cn/acio.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef SDVXHOOK2_5_AC_IO_H
|
||||
#define SDVXHOOK2_5_AC_IO_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
void ac_io_port_init(void);
|
||||
void ac_io_port_fini(void);
|
||||
HRESULT ac_io_port_dispatch_irp(struct irp *irp);
|
||||
|
||||
#endif
|
55
src/main/sdvxhook2-cn/config-cn.c
Normal file
55
src/main/sdvxhook2-cn/config-cn.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include "cconfig/cconfig-util.h"
|
||||
|
||||
#include "sdvxhook2-cn/config-cn.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#define SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY "io.disable_io_emu"
|
||||
#define SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY "cn.unis_path"
|
||||
|
||||
#define SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE false
|
||||
#define SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE "prop/unis.xml"
|
||||
|
||||
void sdvxhook2_cn_config_init(struct cconfig *config)
|
||||
{
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY,
|
||||
SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE,
|
||||
"Disable IO emulation and enable usage of real KFCA hardware");
|
||||
|
||||
cconfig_util_set_str(
|
||||
config,
|
||||
SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY,
|
||||
SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE,
|
||||
"Path to unis version file under the prop.s folder");
|
||||
}
|
||||
|
||||
void sdvxhook2_cn_config_get(
|
||||
struct sdvxhook2_cn_config *cn_config, struct cconfig *config)
|
||||
{
|
||||
if (!cconfig_util_get_bool(
|
||||
config,
|
||||
SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY,
|
||||
&cn_config->disable_io_emu,
|
||||
SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY,
|
||||
SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_str(
|
||||
config,
|
||||
SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY,
|
||||
cn_config->unis_path,
|
||||
sizeof(cn_config->unis_path),
|
||||
SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%s'",
|
||||
SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY,
|
||||
SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE);
|
||||
}
|
||||
}
|
18
src/main/sdvxhook2-cn/config-cn.h
Normal file
18
src/main/sdvxhook2-cn/config-cn.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef SDVXHOOK2_CN_CONFIG_H
|
||||
#define SDVXHOOK2_CN_CONFIG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "cconfig/cconfig.h"
|
||||
|
||||
struct sdvxhook2_cn_config {
|
||||
bool disable_io_emu;
|
||||
char unis_path[256];
|
||||
};
|
||||
|
||||
void sdvxhook2_cn_config_init(struct cconfig *config);
|
||||
|
||||
void sdvxhook2_cn_config_get(
|
||||
struct sdvxhook2_cn_config *cn_config, struct cconfig *config);
|
||||
|
||||
#endif
|
151
src/main/sdvxhook2-cn/dllmain.c
Normal file
151
src/main/sdvxhook2-cn/dllmain.c
Normal file
@ -0,0 +1,151 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bemanitools/eamio.h"
|
||||
#include "bemanitools/sdvxio.h"
|
||||
|
||||
#include "cconfig/cconfig-hook.h"
|
||||
|
||||
#include "hooklib/acp.h"
|
||||
#include "hooklib/adapter.h"
|
||||
#include "hooklib/app.h"
|
||||
#include "hooklib/rs232.h"
|
||||
|
||||
#include "sdvxhook2-cn/acio.h"
|
||||
#include "sdvxhook2-cn/config-cn.h"
|
||||
#include "sdvxhook2-cn/unis-version.h"
|
||||
|
||||
#include "camhook/cam.h"
|
||||
#include "camhook/config-cam.h"
|
||||
|
||||
#include "d3d9exhook/config-gfx.h"
|
||||
#include "d3d9exhook/d3d9ex.h"
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
#include "util/thread.h"
|
||||
|
||||
#define SDVXHOOK2_CN_INFO_HEADER \
|
||||
"sdvxhook for VW CN" \
|
||||
", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV) "\n"
|
||||
#define SDVXHOOK2_CN_CMD_USAGE \
|
||||
"Usage: launcher.exe -K sdvxhook2.dll <soundvoltex.dll> [options...]"
|
||||
|
||||
static const irp_handler_t sdvxhook_handlers[] = {
|
||||
ac_io_port_dispatch_irp,
|
||||
};
|
||||
|
||||
struct sdvxhook2_cn_config config_cn;
|
||||
struct camhook_config_cam config_cam;
|
||||
struct d3d9exhook_config_gfx config_gfx;
|
||||
|
||||
static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
{
|
||||
struct cconfig *config;
|
||||
|
||||
log_info("--- Begin sdvxhook dll_entry_init ---");
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
sdvxhook2_cn_config_init(config);
|
||||
d3d9exhook_config_gfx_init(config);
|
||||
camhook_config_cam_init(config, 1);
|
||||
|
||||
if (!cconfig_hook_config_init(
|
||||
config,
|
||||
SDVXHOOK2_CN_INFO_HEADER "\n" SDVXHOOK2_CN_CMD_USAGE,
|
||||
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
|
||||
cconfig_finit(config);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sdvxhook2_cn_config_get(&config_cn, config);
|
||||
camhook_config_cam_get(&config_cam, config, 1);
|
||||
d3d9exhook_config_gfx_get(&config_gfx, config);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
log_info(SDVXHOOK2_CN_INFO_HEADER);
|
||||
log_info("Initializing sdvxhook2-cn...");
|
||||
|
||||
d3d9ex_configure(&config_gfx);
|
||||
|
||||
/* Start up sdvxio.DLL */
|
||||
if (!config_cn.disable_io_emu) {
|
||||
log_info("Starting sdvx IO backend");
|
||||
sdvx_io_set_loggers(
|
||||
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
|
||||
|
||||
if (!sdvx_io_init(
|
||||
avs_thread_create, avs_thread_join, avs_thread_destroy)) {
|
||||
log_fatal("Initializing sdvx IO backend failed");
|
||||
}
|
||||
}
|
||||
|
||||
/* iohooks are okay, even if emu is diabled since the fake handlers won't be
|
||||
* used */
|
||||
iohook_init(sdvxhook_handlers, lengthof(sdvxhook_handlers));
|
||||
rs232_hook_init();
|
||||
rs232_hook_limit_hooks();
|
||||
|
||||
if (!config_cn.disable_io_emu) {
|
||||
ac_io_port_init();
|
||||
}
|
||||
|
||||
// camera hooks
|
||||
if (!config_cam.disable_emu) {
|
||||
camhook_init(&config_cam);
|
||||
}
|
||||
|
||||
unis_version_hook_init(config_cn.unis_path);
|
||||
|
||||
log_info("--- End sdvxhook dll_entry_init ---");
|
||||
|
||||
return app_hook_invoke_init(sidcode, param);
|
||||
}
|
||||
|
||||
static bool my_dll_entry_main(void)
|
||||
{
|
||||
bool result;
|
||||
|
||||
result = app_hook_invoke_main();
|
||||
|
||||
if (!config_cam.disable_emu) {
|
||||
camhook_fini();
|
||||
}
|
||||
|
||||
if (!config_cn.disable_io_emu) {
|
||||
log_misc("Shutting down sdvx IO backend");
|
||||
sdvx_io_fini();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook library Resort Anthem onwards
|
||||
*/
|
||||
BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
||||
{
|
||||
if (reason != DLL_PROCESS_ATTACH) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
log_to_external(
|
||||
log_body_misc, log_body_info, log_body_warning, log_body_fatal);
|
||||
|
||||
app_hook_init(my_dll_entry_init, my_dll_entry_main);
|
||||
|
||||
acp_hook_init();
|
||||
adapter_hook_init();
|
||||
d3d9ex_hook_init();
|
||||
|
||||
end:
|
||||
return TRUE;
|
||||
}
|
196
src/main/sdvxhook2-cn/kfca.c
Normal file
196
src/main/sdvxhook2-cn/kfca.c
Normal file
@ -0,0 +1,196 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "acio/acio.h"
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
#include "bemanitools/sdvxio.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/time.h"
|
||||
|
||||
static void kfca_send_version(const struct ac_io_message *req);
|
||||
static void kfca_report_status(const struct ac_io_message *req, uint8_t status);
|
||||
static void kfca_report_0128(const struct ac_io_message *req);
|
||||
static void kfca_poll(const struct ac_io_message *req);
|
||||
static void kfca_poll_thunk(void *ctx_ptr, struct ac_io_message *resp);
|
||||
|
||||
static struct ac_io_emu *kfca_ac_io_emu;
|
||||
|
||||
void kfca_init(struct ac_io_emu *emu)
|
||||
{
|
||||
log_assert(emu != NULL);
|
||||
|
||||
kfca_ac_io_emu = emu;
|
||||
}
|
||||
|
||||
void kfca_dispatch_request(const struct ac_io_message *req)
|
||||
{
|
||||
uint16_t cmd_code;
|
||||
|
||||
cmd_code = ac_io_u16(req->cmd.code);
|
||||
|
||||
switch (cmd_code) {
|
||||
case AC_IO_CMD_GET_VERSION:
|
||||
log_misc("AC_IO_CMD_GET_VERSION(%d)", req->addr);
|
||||
kfca_send_version(req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_START_UP:
|
||||
log_misc("AC_IO_CMD_START_UP(%d)", req->addr);
|
||||
kfca_report_status(req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_KFCA_POLL:
|
||||
kfca_poll(req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_KFCA_WATCHDOG:
|
||||
log_misc("AC_IO_CMD_KFCA_WATCHDOG(%d)", req->addr);
|
||||
kfca_report_status(req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_KFCA_AMP_CONTROL:
|
||||
log_misc("AC_IO_CMD_KFCA_AMP_CONTROL(%d)", req->addr);
|
||||
kfca_report_0128(req);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
log_warning(
|
||||
"Unknown ACIO message %04x on KFCA mode, addr=%d",
|
||||
cmd_code,
|
||||
req->addr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void kfca_send_version(const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(resp.cmd.version);
|
||||
resp.cmd.version.type = ac_io_u32(AC_IO_NODE_TYPE_KFCA);
|
||||
resp.cmd.version.flag = 0x00;
|
||||
resp.cmd.version.major = 0x01;
|
||||
resp.cmd.version.minor = 0x01;
|
||||
resp.cmd.version.revision = 0x00;
|
||||
memcpy(
|
||||
resp.cmd.version.product_code,
|
||||
"KFCA",
|
||||
sizeof(resp.cmd.version.product_code));
|
||||
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
|
||||
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
||||
|
||||
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void kfca_report_status(const struct ac_io_message *req, uint8_t status)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(resp.cmd.status);
|
||||
resp.cmd.status = status;
|
||||
|
||||
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void kfca_report_0128(const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = req->cmd.nbytes;
|
||||
memcpy(resp.cmd.raw, req->cmd.raw, req->cmd.nbytes);
|
||||
|
||||
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void kfca_poll(const struct ac_io_message *req)
|
||||
{
|
||||
static uint32_t last_poll = 0;
|
||||
uint64_t delay;
|
||||
const struct ac_io_kfca_poll_out *pout;
|
||||
uintptr_t ctx;
|
||||
size_t i;
|
||||
|
||||
/* Handle lighting output immediately */
|
||||
|
||||
pout = &req->cmd.kfca_poll_out;
|
||||
|
||||
sdvx_io_set_gpio_lights(ac_io_u32(pout->gpio));
|
||||
|
||||
for (i = 0; i < lengthof(pout->pwm); i++) {
|
||||
sdvx_io_set_pwm_light(i, pout->pwm[i]);
|
||||
}
|
||||
|
||||
sdvx_io_write_output();
|
||||
|
||||
/* SDVX expects only one poll response per frame.
|
||||
|
||||
We use a thunk here to defer polling until right before the response
|
||||
is due. */
|
||||
|
||||
delay = time_get_elapsed_ms(last_poll) < 16 ? 16000 : 0;
|
||||
last_poll = time_get_counter();
|
||||
ctx = req->addr | (req->cmd.code << 8) | (req->cmd.seq_no << 24);
|
||||
|
||||
ac_io_emu_response_push_thunk(
|
||||
kfca_ac_io_emu, kfca_poll_thunk, (void *) ctx, delay);
|
||||
}
|
||||
|
||||
static void kfca_poll_thunk(void *ctx_ptr, struct ac_io_message *resp)
|
||||
{
|
||||
struct ac_io_kfca_poll_in *pin;
|
||||
uintptr_t ctx;
|
||||
uint8_t req_addr;
|
||||
uint16_t req_code;
|
||||
uint8_t req_seq_no;
|
||||
|
||||
/* Unpack context "pointer" for relevant response information */
|
||||
|
||||
ctx = (uintptr_t) ctx_ptr;
|
||||
req_addr = ctx;
|
||||
req_code = ctx >> 8;
|
||||
req_seq_no = ctx >> 24;
|
||||
|
||||
/* Poll input now and construct an immediate response */
|
||||
|
||||
pin = &resp->cmd.kfca_poll_in;
|
||||
|
||||
resp->addr = req_addr | AC_IO_RESPONSE_FLAG;
|
||||
resp->cmd.code = req_code;
|
||||
resp->cmd.seq_no = req_seq_no;
|
||||
resp->cmd.nbytes = sizeof(*pin);
|
||||
|
||||
sdvx_io_read_input();
|
||||
|
||||
memset(pin, 0, sizeof(*pin));
|
||||
|
||||
pin->adc[0] = sdvx_io_get_spinner_pos(0) << 6;
|
||||
pin->adc[1] = sdvx_io_get_spinner_pos(1) << 6;
|
||||
|
||||
pin->gpio_sys |= sdvx_io_get_input_gpio_sys() & 0x3F;
|
||||
|
||||
pin->adc[0] = ac_io_u16(pin->adc[0]);
|
||||
pin->adc[1] = ac_io_u16(pin->adc[1]);
|
||||
pin->gpio[0] = ac_io_u16(sdvx_io_get_input_gpio(0));
|
||||
pin->gpio[1] = ac_io_u16(sdvx_io_get_input_gpio(1));
|
||||
}
|
11
src/main/sdvxhook2-cn/kfca.h
Normal file
11
src/main/sdvxhook2-cn/kfca.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef SDVXHOOK_KFCA_H
|
||||
#define SDVXHOOK_KFCA_H
|
||||
|
||||
#include "acio/acio.h"
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
void kfca_init(struct ac_io_emu *emu);
|
||||
void kfca_dispatch_request(const struct ac_io_message *req);
|
||||
|
||||
#endif
|
4
src/main/sdvxhook2-cn/sdvxhook2-cn.def
Normal file
4
src/main/sdvxhook2-cn/sdvxhook2-cn.def
Normal file
@ -0,0 +1,4 @@
|
||||
LIBRARY sdvxhook2-cn
|
||||
|
||||
EXPORTS
|
||||
DllMain@12 @1 NONAME
|
84
src/main/sdvxhook2-cn/unis-version.c
Normal file
84
src/main/sdvxhook2-cn/unis-version.c
Normal file
@ -0,0 +1,84 @@
|
||||
#define LOG_MODULE "unis-version"
|
||||
|
||||
// clang-format off
|
||||
// Don't format because the order is important here
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
// clang-format on
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hook/com-proxy.h"
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
#include "util/time.h"
|
||||
|
||||
LPWSTR *(*real_CommandLineToArgvW)(LPCWSTR lpCmdLine, int *pNumArgs);
|
||||
|
||||
LPWSTR *my_CommandLineToArgvW(LPCWSTR lpCmdLine, int *pNumArgs);
|
||||
|
||||
static const struct hook_symbol unis_shell32_syms[] = {
|
||||
{.name = "CommandLineToArgvW",
|
||||
.patch = my_CommandLineToArgvW,
|
||||
.link = (void **) &real_CommandLineToArgvW},
|
||||
};
|
||||
|
||||
bool (*real_IsInComm)(void);
|
||||
bool my_IsInComm(void);
|
||||
|
||||
bool (*real_IsConnectServer)(void);
|
||||
bool my_IsConnectServer(void);
|
||||
|
||||
bool (*real_IsPlayerForbidState)(int pnum);
|
||||
bool my_IsPlayerForbidState(int pnum);
|
||||
|
||||
static wchar_t unis_cmd_path[256 + 16];
|
||||
|
||||
static const struct hook_symbol unis_unisintr_syms[] = {
|
||||
{.name = "IsInComm",
|
||||
.patch = my_IsInComm,
|
||||
.link = (void **) &real_IsInComm},
|
||||
{.name = "IsConnectServer",
|
||||
.patch = my_IsConnectServer,
|
||||
.link = (void **) &real_IsConnectServer},
|
||||
{.name = "IsPlayerForbidState",
|
||||
.patch = my_IsPlayerForbidState,
|
||||
.link = (void **) &real_IsPlayerForbidState},
|
||||
};
|
||||
|
||||
LPWSTR *my_CommandLineToArgvW(LPCWSTR lpCmdLine, int *pNumArgs)
|
||||
{
|
||||
return real_CommandLineToArgvW(unis_cmd_path, pNumArgs);
|
||||
}
|
||||
|
||||
bool my_IsInComm(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool my_IsConnectServer(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool my_IsPlayerForbidState(int pnum)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void unis_version_hook_init(const char* unis_path)
|
||||
{
|
||||
hook_table_apply(
|
||||
NULL, "Shell32.dll", unis_shell32_syms, lengthof(unis_shell32_syms));
|
||||
hook_table_apply(
|
||||
NULL, "unisintr.dll", unis_unisintr_syms, lengthof(unis_unisintr_syms));
|
||||
|
||||
wcscpy(unis_cmd_path, L"launcher.exe ");
|
||||
wchar_t *end = wcsrchr(unis_cmd_path, L'\0');
|
||||
mbstowcs(end, unis_path, 256);
|
||||
|
||||
log_info("Inserted hooks for unis version detection");
|
||||
}
|
6
src/main/sdvxhook2-cn/unis-version.h
Normal file
6
src/main/sdvxhook2-cn/unis-version.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef SDVXHOOK2_5_UNIS_VERSION_H
|
||||
#define SDVXHOOK2_5_UNIS_VERSION_H
|
||||
|
||||
void unis_version_hook_init(const char* unis_path);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user