add kizuna 2, load aime reader properly
This commit is contained in:
parent
e5028fb002
commit
43a6dfbcb4
12
Package.mk
12
Package.mk
@ -64,6 +64,17 @@ $(BUILD_DIR_ZIP)/tekken.zip:
|
|||||||
$(V)strip $(BUILD_DIR_ZIP)/tekken/*.{exe,dll}
|
$(V)strip $(BUILD_DIR_ZIP)/tekken/*.{exe,dll}
|
||||||
$(V)cd $(BUILD_DIR_ZIP)/tekken ; zip -r ../tekken.zip *
|
$(V)cd $(BUILD_DIR_ZIP)/tekken ; zip -r ../tekken.zip *
|
||||||
|
|
||||||
|
$(BUILD_DIR_ZIP)/kizuna.zip:
|
||||||
|
$(V)echo ... $@
|
||||||
|
$(V)mkdir -p $(BUILD_DIR_ZIP)/kizuna
|
||||||
|
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
|
||||||
|
$(BUILD_DIR_64)/kizunahook/kizunahook.dll \
|
||||||
|
$(DIST_DIR)/kizuna/bananatools.ini \
|
||||||
|
$(DIST_DIR)/kizuna/start.bat \
|
||||||
|
$(BUILD_DIR_ZIP)/kizuna
|
||||||
|
$(V)strip $(BUILD_DIR_ZIP)/kizuna/*.{exe,dll}
|
||||||
|
$(V)cd $(BUILD_DIR_ZIP)/kizuna ; zip -r ../kizuna.zip *
|
||||||
|
|
||||||
$(BUILD_DIR_ZIP)/doc.zip: \
|
$(BUILD_DIR_ZIP)/doc.zip: \
|
||||||
$(DOC_DIR)/ferrumhook.md \
|
$(DOC_DIR)/ferrumhook.md \
|
||||||
$(DOC_DIR)/taikohook.md \
|
$(DOC_DIR)/taikohook.md \
|
||||||
@ -80,6 +91,7 @@ $(BUILD_DIR_ZIP)/bananatools.zip: \
|
|||||||
$(BUILD_DIR_ZIP)/sao.zip \
|
$(BUILD_DIR_ZIP)/sao.zip \
|
||||||
$(BUILD_DIR_ZIP)/mkac.zip \
|
$(BUILD_DIR_ZIP)/mkac.zip \
|
||||||
$(BUILD_DIR_ZIP)/tekken.zip \
|
$(BUILD_DIR_ZIP)/tekken.zip \
|
||||||
|
$(BUILD_DIR_ZIP)/kizuna.zip \
|
||||||
$(BUILD_DIR_ZIP)/doc.zip \
|
$(BUILD_DIR_ZIP)/doc.zip \
|
||||||
README.md \
|
README.md \
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ uint16_t aime_io_get_api_version(void)
|
|||||||
|
|
||||||
HRESULT aime_io_init(void)
|
HRESULT aime_io_init(void)
|
||||||
{
|
{
|
||||||
aime_io_config_read(&aime_io_cfg, L".\\segatools.ini");
|
aime_io_config_read(&aime_io_cfg, L".\\bananatools.ini");
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ static HRESULT sg_nfc_cmd_get_fw_version(
|
|||||||
{
|
{
|
||||||
/* Dest version is not NUL terminated, this is intentional */
|
/* Dest version is not NUL terminated, this is intentional */
|
||||||
sg_res_init(&res->res, req, sizeof(res->version));
|
sg_res_init(&res->res, req, sizeof(res->version));
|
||||||
memcpy(res->version, "TN32MSEC003S F/W Ver1.2E", sizeof(res->version));
|
memcpy(res->version, "\x94", sizeof(res->version));
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ static HRESULT sg_nfc_cmd_get_hw_version(
|
|||||||
{
|
{
|
||||||
/* Dest version is not NUL terminated, this is intentional */
|
/* Dest version is not NUL terminated, this is intentional */
|
||||||
sg_res_init(&res->res, req, sizeof(res->version));
|
sg_res_init(&res->res, req, sizeof(res->version));
|
||||||
memcpy(res->version, "TN32MSEC003S H/W Ver3.0J", sizeof(res->version));
|
memcpy(res->version, "837-15396-6728", sizeof(res->version));
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
54
dist/kizuna/bananatools.ini
vendored
Normal file
54
dist/kizuna/bananatools.ini
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
; Controls the virtual file system hooks. These redirect file i/o
|
||||||
|
; requests to a folder specified below, instead of the drive.
|
||||||
|
; These are all required, even if the game doesn't use one of them.
|
||||||
|
[vfs]
|
||||||
|
path=
|
||||||
|
|
||||||
|
[dns]
|
||||||
|
default=localhost
|
||||||
|
|
||||||
|
; Security dongle emulation, disable if you have a
|
||||||
|
; real dongle connected that you want to use
|
||||||
|
[dongle]
|
||||||
|
enable=1
|
||||||
|
serial=284013090501
|
||||||
|
|
||||||
|
; Set the network environment. Most games seem to want 192.168.123.X
|
||||||
|
[netenv]
|
||||||
|
enable=1
|
||||||
|
subnet=192.168.10.0
|
||||||
|
|
||||||
|
; Graphics hook, may cause crashes in some games
|
||||||
|
[gfx]
|
||||||
|
enable=1
|
||||||
|
windowed=1
|
||||||
|
framed=0
|
||||||
|
monitor=0
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
systemVersion=SK2100-1-NA-SYS0-L02
|
||||||
|
|
||||||
|
; Control the AMCUS replacement class
|
||||||
|
[amcus]
|
||||||
|
enable=0
|
||||||
|
game_id=SDGG
|
||||||
|
game_cd=SK21
|
||||||
|
am_game_ver=1.00
|
||||||
|
cacfg_game_ver=33.02
|
||||||
|
server_uri=localhost
|
||||||
|
server_host=localhost
|
||||||
|
|
||||||
|
[reader]
|
||||||
|
enable=1
|
||||||
|
access_code=00000000000000000000
|
||||||
|
|
||||||
|
; USIO config
|
||||||
|
[usio]
|
||||||
|
enable=1
|
||||||
|
test=0x24
|
||||||
|
service=0x2E
|
||||||
|
coin=0x2D
|
||||||
|
up=0x26
|
||||||
|
down=0x28
|
||||||
|
enter=0x0D
|
||||||
|
|
10
dist/kizuna/start.bat
vendored
Normal file
10
dist/kizuna/start.bat
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
pushd %~dp0
|
||||||
|
|
||||||
|
start inject.exe -d -k kizunahook.dll AMCUS\AMAuthd.exe
|
||||||
|
inject.exe -d -k kizunahook.dll WindowsNoEditor\KizunaGame\Binaries\Win64\TKizunaGame-Win64-Shipping.exe
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo The game process has terminated
|
||||||
|
pause
|
37
kizunahook/config.c
Normal file
37
kizunahook/config.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "kizunahook/config.h"
|
||||||
|
|
||||||
|
#include "platform/config.h"
|
||||||
|
|
||||||
|
void kizuna_dll_config_load(
|
||||||
|
struct kizuna_dll_config *cfg,
|
||||||
|
const wchar_t *filename)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
assert(filename != NULL);
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(
|
||||||
|
L"kizunaio",
|
||||||
|
L"path",
|
||||||
|
L"",
|
||||||
|
cfg->path,
|
||||||
|
_countof(cfg->path),
|
||||||
|
filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
void kizuna_hook_config_load(
|
||||||
|
struct kizuna_hook_config *cfg,
|
||||||
|
const wchar_t *filename)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
assert(filename != NULL);
|
||||||
|
|
||||||
|
aime_config_load(&cfg->aime, filename);
|
||||||
|
platform_config_load(&cfg->platform, filename);
|
||||||
|
kizuna_dll_config_load(&cfg->dll, filename);
|
||||||
|
gfx_config_load(&cfg->gfx, filename);
|
||||||
|
bpreader_config_load(&cfg->reader, filename);
|
||||||
|
usio_config_load(&cfg->usio, filename);
|
||||||
|
}
|
29
kizunahook/config.h
Normal file
29
kizunahook/config.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "kizunahook/kizuna-dll.h"
|
||||||
|
|
||||||
|
#include "platform/config.h"
|
||||||
|
#include "gfxhook/config.h"
|
||||||
|
#include "amcus/config.h"
|
||||||
|
#include "board/config.h"
|
||||||
|
|
||||||
|
struct kizuna_hook_config {
|
||||||
|
struct platform_config platform;
|
||||||
|
struct aime_config aime;
|
||||||
|
struct kizuna_dll_config dll;
|
||||||
|
struct gfx_config gfx;
|
||||||
|
struct amcus_config amcus;
|
||||||
|
struct bpreader_config reader;
|
||||||
|
struct usio_config usio;
|
||||||
|
};
|
||||||
|
|
||||||
|
void kizuna_dll_config_load(
|
||||||
|
struct kizuna_dll_config *cfg,
|
||||||
|
const wchar_t *filename);
|
||||||
|
|
||||||
|
void kizuna_hook_config_load(
|
||||||
|
struct kizuna_hook_config *cfg,
|
||||||
|
const wchar_t *filename);
|
||||||
|
|
104
kizunahook/dllmain.c
Normal file
104
kizunahook/dllmain.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "kizunahook/config.h"
|
||||||
|
#include "kizunahook/kizuna-dll.h"
|
||||||
|
#include "kizunahook/usio.h"
|
||||||
|
|
||||||
|
#include "amcus/amcus.h"
|
||||||
|
|
||||||
|
#include "hook/process.h"
|
||||||
|
|
||||||
|
#include "hooklib/serial.h"
|
||||||
|
#include "board/sg-reader.h"
|
||||||
|
#include "board/vfd.h"
|
||||||
|
|
||||||
|
#include "platform/platform.h"
|
||||||
|
#include "gfxhook/gfx.h"
|
||||||
|
#include "gfxhook/dxgi.h"
|
||||||
|
#include "gfxhook/d3d11.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
static HMODULE kizuna_hook_mod;
|
||||||
|
static process_entry_t kizuna_startup;
|
||||||
|
static struct kizuna_hook_config kizuna_hook_cfg;
|
||||||
|
|
||||||
|
static DWORD CALLBACK kizuna_pre_startup(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
dprintf("--- Begin kizuna_pre_startup ---\n");
|
||||||
|
|
||||||
|
kizuna_hook_config_load(&kizuna_hook_cfg, L".\\bananatools.ini");
|
||||||
|
|
||||||
|
serial_hook_init();
|
||||||
|
|
||||||
|
struct dongle_info dinfo;
|
||||||
|
dinfo.pid = 0x0C00;
|
||||||
|
dinfo.vid = 0x0B9A;
|
||||||
|
|
||||||
|
hr = platform_hook_init(&kizuna_hook_cfg.platform, PLATFORM_BNA1, NULL, kizuna_hook_mod, dinfo);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ExitProcess(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = sg_reader_hook_init(&kizuna_hook_cfg.aime, 1, kizuna_hook_mod);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ExitProcess(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = vfd_hook_init(2);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ExitProcess(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = kizuna_dll_init(&kizuna_hook_cfg.dll, kizuna_hook_mod);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ExitProcess(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = kizuna_usio_hook_init(&kizuna_hook_cfg.usio);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ExitProcess(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = amcus_hook_init(&kizuna_hook_cfg.amcus);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ExitProcess(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_hook_init(&kizuna_hook_cfg.gfx);
|
||||||
|
gfx_d3d11_hook_init(&kizuna_hook_cfg.gfx, kizuna_hook_mod);
|
||||||
|
gfx_dxgi_hook_init(&kizuna_hook_cfg.gfx, kizuna_hook_mod);
|
||||||
|
|
||||||
|
dprintf("--- End kizuna_pre_startup ---\n");
|
||||||
|
|
||||||
|
return kizuna_startup();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (cause != DLL_PROCESS_ATTACH) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
kizuna_hook_mod = mod;
|
||||||
|
|
||||||
|
hr = process_hijack_startup(kizuna_pre_startup, &kizuna_startup);
|
||||||
|
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
dprintf("Failed to hijack process startup: %x\n", (int) hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
106
kizunahook/kizuna-dll.c
Normal file
106
kizunahook/kizuna-dll.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "kizunahook/kizuna-dll.h"
|
||||||
|
|
||||||
|
#include "util/dll-bind.h"
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
const struct dll_bind_sym kizuna_dll_syms[] = {
|
||||||
|
{
|
||||||
|
.sym = "kizuna_io_init",
|
||||||
|
.off = offsetof(struct kizuna_dll, init),
|
||||||
|
}, {
|
||||||
|
.sym = "kizuna_io_read_coin_counter",
|
||||||
|
.off = offsetof(struct kizuna_dll, read_coin_counter),
|
||||||
|
}, {
|
||||||
|
.sym = "kizuna_io_get_opbtns",
|
||||||
|
.off = offsetof(struct kizuna_dll, get_opbtns),
|
||||||
|
}, {
|
||||||
|
.sym = "kizuna_io_get_analog",
|
||||||
|
.off = offsetof(struct kizuna_dll, get_analog),
|
||||||
|
}, {
|
||||||
|
.sym = "kizuna_io_get_gamebtns",
|
||||||
|
.off = offsetof(struct kizuna_dll, get_gamebtns),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kizuna_dll kizuna_dll;
|
||||||
|
|
||||||
|
HRESULT kizuna_dll_init(const struct kizuna_dll_config *cfg, HINSTANCE self)
|
||||||
|
{
|
||||||
|
uint16_t (*get_api_version)(void);
|
||||||
|
const struct dll_bind_sym *sym;
|
||||||
|
HINSTANCE owned;
|
||||||
|
HINSTANCE src;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
assert(cfg != NULL);
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
if (cfg->path[0] != L'\0') {
|
||||||
|
owned = LoadLibraryW(cfg->path);
|
||||||
|
|
||||||
|
if (owned == NULL) {
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
dprintf("Kizuna IO: Failed to load IO DLL: %lx: %S\n",
|
||||||
|
hr,
|
||||||
|
cfg->path);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("Kizuna IO: Using custom IO DLL: %S\n", cfg->path);
|
||||||
|
src = owned;
|
||||||
|
} else {
|
||||||
|
owned = NULL;
|
||||||
|
src = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_api_version = (void *) GetProcAddress(src, "kizuna_io_get_api_version");
|
||||||
|
|
||||||
|
if (get_api_version != NULL) {
|
||||||
|
kizuna_dll.api_version = get_api_version();
|
||||||
|
} else {
|
||||||
|
kizuna_dll.api_version = 0x0100;
|
||||||
|
dprintf("Custom IO DLL does not expose kizuna_io_get_api_version, "
|
||||||
|
"assuming API version 1.0.\n"
|
||||||
|
"Please ask the developer to update their DLL.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kizuna_dll.api_version >= 0x0200) {
|
||||||
|
hr = E_NOTIMPL;
|
||||||
|
dprintf("Kizuna IO: Custom IO DLL implements an unsupported "
|
||||||
|
"API version (%#04x). Please update Segatools.\n",
|
||||||
|
kizuna_dll.api_version);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
sym = kizuna_dll_syms;
|
||||||
|
hr = dll_bind(&kizuna_dll, src, &sym, _countof(kizuna_dll_syms));
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
if (src != self) {
|
||||||
|
dprintf("Kizuna IO: Custom IO DLL does not provide function "
|
||||||
|
"\"%s\". Please contact your IO DLL's developer for "
|
||||||
|
"further assistance.\n",
|
||||||
|
sym->sym);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
} else {
|
||||||
|
dprintf("Internal error: could not reflect \"%s\"\n", sym->sym);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
owned = NULL;
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (owned != NULL) {
|
||||||
|
FreeLibrary(owned);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
23
kizunahook/kizuna-dll.h
Normal file
23
kizunahook/kizuna-dll.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "kizunaio/kizunaio.h"
|
||||||
|
|
||||||
|
struct kizuna_dll {
|
||||||
|
uint16_t api_version;
|
||||||
|
HRESULT (*init)(void);
|
||||||
|
HRESULT (*poll)(void);
|
||||||
|
void (*read_coin_counter)(uint16_t *coins, uint16_t *services);
|
||||||
|
void (*get_opbtns)(uint8_t *opbtn);
|
||||||
|
void (*get_gamebtns)(uint8_t *gamebtns);
|
||||||
|
void (*get_analog)(uint8_t *x, uint8_t *y);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kizuna_dll_config {
|
||||||
|
wchar_t path[MAX_PATH];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct kizuna_dll kizuna_dll;
|
||||||
|
|
||||||
|
HRESULT kizuna_dll_init(const struct kizuna_dll_config *cfg, HINSTANCE self);
|
15
kizunahook/kizunahook.def
Normal file
15
kizunahook/kizunahook.def
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
LIBRARY kizunahook
|
||||||
|
|
||||||
|
EXPORTS
|
||||||
|
aime_io_get_api_version
|
||||||
|
aime_io_init
|
||||||
|
aime_io_led_set_color
|
||||||
|
aime_io_nfc_get_aime_id
|
||||||
|
aime_io_nfc_get_felica_id
|
||||||
|
aime_io_nfc_poll
|
||||||
|
kizuna_io_get_api_version
|
||||||
|
kizuna_io_init
|
||||||
|
kizuna_io_read_coin_counter
|
||||||
|
kizuna_io_get_analog
|
||||||
|
kizuna_io_get_gamebtns
|
||||||
|
kizuna_io_get_opbtns
|
33
kizunahook/meson.build
Normal file
33
kizunahook/meson.build
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
shared_library(
|
||||||
|
'kizunahook',
|
||||||
|
name_prefix : '',
|
||||||
|
include_directories : inc,
|
||||||
|
implicit_include_directories : false,
|
||||||
|
vs_module_defs : 'kizunahook.def',
|
||||||
|
c_pch : '../precompiled.h',
|
||||||
|
dependencies : [
|
||||||
|
capnhook.get_variable('hook_dep'),
|
||||||
|
capnhook.get_variable('hooklib_dep'),
|
||||||
|
xinput_lib,
|
||||||
|
],
|
||||||
|
link_with : [
|
||||||
|
kizunaio_lib,
|
||||||
|
amcus_lib,
|
||||||
|
platform_lib,
|
||||||
|
util_lib,
|
||||||
|
hooklib_lib,
|
||||||
|
gfxhook_lib,
|
||||||
|
jvs_lib,
|
||||||
|
board_lib,
|
||||||
|
aimeio_lib
|
||||||
|
],
|
||||||
|
sources : [
|
||||||
|
'dllmain.c',
|
||||||
|
'config.c',
|
||||||
|
'config.h',
|
||||||
|
'kizuna-dll.c',
|
||||||
|
'kizuna-dll.h',
|
||||||
|
'usio.c',
|
||||||
|
'usio.h',
|
||||||
|
],
|
||||||
|
)
|
99
kizunahook/usio.c
Normal file
99
kizunahook/usio.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "board/usio.h"
|
||||||
|
|
||||||
|
#include "kizunahook/kizuna-dll.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
bool kizuna_io_coin = false;
|
||||||
|
uint16_t kizuna_io_coins = 0;
|
||||||
|
|
||||||
|
static HRESULT kizuna_usio_poll(void *ctx, struct usio_state *state);
|
||||||
|
|
||||||
|
static const struct usio_ops kizuna_usio_ops = {
|
||||||
|
.poll = kizuna_usio_poll,
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT kizuna_usio_hook_init(const struct usio_config *cfg)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
assert(kizuna_dll.init != NULL);
|
||||||
|
|
||||||
|
hr = usio_hook_init(cfg, &kizuna_usio_ops, NULL, NULL);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("Kizuna USIO: Init\n");
|
||||||
|
|
||||||
|
return kizuna_dll.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT kizuna_usio_poll(void *ctx, struct usio_state *state)
|
||||||
|
{
|
||||||
|
uint8_t opbtn_out = 0;
|
||||||
|
uint8_t gamebtn_out = 0;
|
||||||
|
uint8_t x = 128;
|
||||||
|
uint8_t y = 128;
|
||||||
|
uint16_t coin_ct = 0;
|
||||||
|
uint16_t service_ct = 0;
|
||||||
|
|
||||||
|
kizuna_dll.get_opbtns(&opbtn_out);
|
||||||
|
kizuna_dll.get_analog(&x, &y);
|
||||||
|
kizuna_dll.read_coin_counter(&coin_ct, &service_ct);
|
||||||
|
kizuna_dll.get_gamebtns(&gamebtn_out);
|
||||||
|
|
||||||
|
state->op_btns = 0;
|
||||||
|
state->p1_btns = 0;
|
||||||
|
state->p2_btns = 0;
|
||||||
|
|
||||||
|
if (opbtn_out & 0x01) {
|
||||||
|
state->op_btns |= 0x80; // Test
|
||||||
|
}
|
||||||
|
if (opbtn_out & 0x02) {
|
||||||
|
state->p1_btns |= 0x40; // Service
|
||||||
|
}
|
||||||
|
if (opbtn_out & 0x04) {
|
||||||
|
state->p1_btns |= 0x20; // Up
|
||||||
|
}
|
||||||
|
if (opbtn_out & 0x08) {
|
||||||
|
state->p1_btns |= 0x10; // Down
|
||||||
|
}
|
||||||
|
if (opbtn_out & 0x10) {
|
||||||
|
state->p1_btns |= 0x02; // Enter
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gamebtn_out & 0x01) {
|
||||||
|
state->p1_btns |= 0x2000;
|
||||||
|
}
|
||||||
|
if (gamebtn_out & 0x02) {
|
||||||
|
state->p1_btns |= 0x1000;
|
||||||
|
}
|
||||||
|
if (gamebtn_out & 0x04) {
|
||||||
|
state->p1_btns |= 0x0800;
|
||||||
|
}
|
||||||
|
if (gamebtn_out & 0x08) {
|
||||||
|
state->p1_btns |= 0x4000;
|
||||||
|
}
|
||||||
|
if (gamebtn_out & 0x10) {
|
||||||
|
state->p1_btns |= 0x01;
|
||||||
|
}
|
||||||
|
if (gamebtn_out & 0x20) {
|
||||||
|
state->p1_btns |= 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->analog[0] = x << 8;
|
||||||
|
state->analog[1] = y << 8;
|
||||||
|
|
||||||
|
state->coins[0].current_coin_count = coin_ct;
|
||||||
|
state->service.current_coin_count = service_ct;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
7
kizunahook/usio.h
Normal file
7
kizunahook/usio.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "board/usio.h"
|
||||||
|
|
||||||
|
HRESULT kizuna_usio_hook_init(const struct usio_config *cfg);
|
29
kizunaio/config.c
Normal file
29
kizunaio/config.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "kizunaio/config.h"
|
||||||
|
|
||||||
|
void kizuna_io_config_load(struct kizuna_input_config *cfg, const wchar_t *filename)
|
||||||
|
{
|
||||||
|
cfg->test = GetPrivateProfileIntW(L"usio", L"test", VK_HOME, filename);
|
||||||
|
cfg->service = GetPrivateProfileIntW(L"usio", L"service", VK_DELETE, filename);
|
||||||
|
cfg->coin = GetPrivateProfileIntW(L"usio", L"coin", VK_INSERT, filename);
|
||||||
|
cfg->up = GetPrivateProfileIntW(L"usio", L"up", VK_UP, filename);
|
||||||
|
cfg->down = GetPrivateProfileIntW(L"usio", L"down", VK_DOWN, filename);
|
||||||
|
cfg->enter = GetPrivateProfileIntW(L"usio", L"enter", VK_RETURN, filename);
|
||||||
|
|
||||||
|
cfg->stick_up = GetPrivateProfileIntW(L"usio", L"stick_up", 'W', filename);
|
||||||
|
cfg->stick_left = GetPrivateProfileIntW(L"usio", L"stick_left", 'A', filename);
|
||||||
|
cfg->stick_down = GetPrivateProfileIntW(L"usio", L"stick_down", 'S', filename);
|
||||||
|
cfg->stick_right = GetPrivateProfileIntW(L"usio", L"stick_right", 'D', filename);
|
||||||
|
cfg->stick_btn1 = GetPrivateProfileIntW(L"usio", L"stick_btn1", 'R', filename);
|
||||||
|
cfg->stick_btn2 = GetPrivateProfileIntW(L"usio", L"stick_btn2", 'F', filename);
|
||||||
|
cfg->stick_btn3 = GetPrivateProfileIntW(L"usio", L"stick_btn3", 'V', filename);
|
||||||
|
|
||||||
|
cfg->btn1 = GetPrivateProfileIntW(L"usio", L"btn1", '1', filename);
|
||||||
|
cfg->btn2 = GetPrivateProfileIntW(L"usio", L"btn2", '2', filename);
|
||||||
|
cfg->btn3 = GetPrivateProfileIntW(L"usio", L"btn3", '3', filename);
|
||||||
|
}
|
30
kizunaio/config.h
Normal file
30
kizunaio/config.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct kizuna_input_config {
|
||||||
|
uint8_t test;
|
||||||
|
uint8_t service;
|
||||||
|
uint8_t up;
|
||||||
|
uint8_t down;
|
||||||
|
uint8_t enter;
|
||||||
|
uint8_t coin;
|
||||||
|
|
||||||
|
uint8_t stick_up;
|
||||||
|
uint8_t stick_down;
|
||||||
|
uint8_t stick_left;
|
||||||
|
uint8_t stick_right;
|
||||||
|
|
||||||
|
uint8_t stick_btn1;
|
||||||
|
uint8_t stick_btn2;
|
||||||
|
uint8_t stick_btn3;
|
||||||
|
|
||||||
|
uint8_t btn1;
|
||||||
|
uint8_t btn2;
|
||||||
|
uint8_t btn3;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
void kizuna_io_config_load(struct kizuna_input_config *cfg, const wchar_t *filename);
|
132
kizunaio/kizunaio.c
Normal file
132
kizunaio/kizunaio.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <xinput.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "kizunaio/kizunaio.h"
|
||||||
|
#include "kizunaio/config.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
static bool kizuna_io_coin = false;
|
||||||
|
static bool kizuna_io_service = false;
|
||||||
|
static bool kizuna_test_toggle = false;
|
||||||
|
static bool kizuna_test_last_state = false;
|
||||||
|
static uint16_t kizuna_coin_ct = 0;
|
||||||
|
static uint16_t kizuna_service_ct = 0;
|
||||||
|
static struct kizuna_input_config cfg;
|
||||||
|
|
||||||
|
uint16_t kizuna_io_get_api_version(void)
|
||||||
|
{
|
||||||
|
return 0x0100;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT kizuna_io_init(void)
|
||||||
|
{
|
||||||
|
dprintf("Kizuna IO: Init\n");
|
||||||
|
kizuna_io_config_load(&cfg, L".\\bananatools.ini");
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kizuna_io_get_opbtns(uint8_t *opbtn)
|
||||||
|
{
|
||||||
|
if ((GetAsyncKeyState(cfg.test) & 0x8000)) {
|
||||||
|
if (!kizuna_test_last_state) {
|
||||||
|
kizuna_test_toggle = !kizuna_test_toggle;
|
||||||
|
}
|
||||||
|
kizuna_test_last_state = true;
|
||||||
|
} else {
|
||||||
|
kizuna_test_last_state = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.service) & 0x8000) {
|
||||||
|
*opbtn |= KIZUNA_IO_OPBTN_SERVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.up) & 0x8000) {
|
||||||
|
*opbtn |= KIZUNA_IO_OPBTN_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.down) & 0x8000) {
|
||||||
|
*opbtn |= KIZUNA_IO_OPBTN_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.enter) & 0x8000) {
|
||||||
|
*opbtn |= KIZUNA_IO_OPBTN_ENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kizuna_test_toggle) {
|
||||||
|
*opbtn |= KIZUNA_IO_OPBTN_TEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void kizuna_io_get_gamebtns(uint8_t *gamebtns)
|
||||||
|
{
|
||||||
|
*gamebtns = 0;
|
||||||
|
if (GetAsyncKeyState(cfg.btn1) & 0x8000) {
|
||||||
|
*gamebtns |= KIZUNA_IO_GAMEBTN_1;
|
||||||
|
}
|
||||||
|
if (GetAsyncKeyState(cfg.btn2) & 0x8000) {
|
||||||
|
*gamebtns |= KIZUNA_IO_GAMEBTN_2;
|
||||||
|
}
|
||||||
|
if (GetAsyncKeyState(cfg.btn3) & 0x8000) {
|
||||||
|
*gamebtns |= KIZUNA_IO_GAMEBTN_3;
|
||||||
|
}
|
||||||
|
if (GetAsyncKeyState(cfg.stick_btn1) & 0x8000) {
|
||||||
|
*gamebtns |= KIZUNA_IO_GAMEBTN_STICK1;
|
||||||
|
}
|
||||||
|
if (GetAsyncKeyState(cfg.stick_btn2) & 0x8000) {
|
||||||
|
*gamebtns |= KIZUNA_IO_GAMEBTN_STICK2;
|
||||||
|
}
|
||||||
|
if (GetAsyncKeyState(cfg.stick_btn3) & 0x8000) {
|
||||||
|
*gamebtns |= KIZUNA_IO_GAMEBTN_STICK3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void kizuna_io_get_analog(uint8_t *x, uint8_t *y)
|
||||||
|
{
|
||||||
|
*x = 128;
|
||||||
|
*y = 128;
|
||||||
|
if (GetAsyncKeyState(cfg.stick_up) & 0x8000) {
|
||||||
|
*y += 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.stick_down) & 0x8000) {
|
||||||
|
*y -= 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.stick_right) & 0x8000) {
|
||||||
|
*x += 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.stick_left) & 0x8000) {
|
||||||
|
*x -= 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void kizuna_io_read_coin_counter(uint16_t *coins, uint16_t *services)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.coin) & 0x8000) {
|
||||||
|
if (!kizuna_io_coin) {
|
||||||
|
kizuna_io_coin = true;
|
||||||
|
kizuna_coin_ct++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
kizuna_io_coin = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState(cfg.service) & 0x8000) {
|
||||||
|
if (!kizuna_io_service) {
|
||||||
|
kizuna_io_service = true;
|
||||||
|
kizuna_service_ct++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
kizuna_io_service = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*coins = kizuna_coin_ct;
|
||||||
|
*services = kizuna_service_ct;
|
||||||
|
}
|
9
kizunaio/kizunaio.def
Normal file
9
kizunaio/kizunaio.def
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
LIBRARY kizunahook
|
||||||
|
|
||||||
|
EXPORTS
|
||||||
|
kizuna_io_get_api_version
|
||||||
|
kizuna_io_init
|
||||||
|
kizuna_io_read_coin_counter
|
||||||
|
kizuna_io_get_analog
|
||||||
|
kizuna_io_get_gamebtns
|
||||||
|
kizuna_io_get_opbtns
|
67
kizunaio/kizunaio.h
Normal file
67
kizunaio/kizunaio.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "kizunaio/config.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
KIZUNA_IO_OPBTN_TEST = 0x01,
|
||||||
|
KIZUNA_IO_OPBTN_SERVICE = 0x02,
|
||||||
|
KIZUNA_IO_OPBTN_UP = 0x04,
|
||||||
|
KIZUNA_IO_OPBTN_DOWN = 0x08,
|
||||||
|
KIZUNA_IO_OPBTN_ENTER = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
KIZUNA_IO_GAMEBTN_1 = 0x0001,
|
||||||
|
KIZUNA_IO_GAMEBTN_2 = 0x0002,
|
||||||
|
KIZUNA_IO_GAMEBTN_3 = 0x0004,
|
||||||
|
KIZUNA_IO_GAMEBTN_STICK1 = 0x0008,
|
||||||
|
KIZUNA_IO_GAMEBTN_STICK2 = 0x0010,
|
||||||
|
KIZUNA_IO_GAMEBTN_STICK3 = 0x0020,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get the version of the Pokken 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
|
||||||
|
Semantic Versioning standard).
|
||||||
|
|
||||||
|
The latest API version as of this writing is 0x0100. */
|
||||||
|
|
||||||
|
uint16_t kizuna_io_get_api_version(void);
|
||||||
|
|
||||||
|
/* Initialize the IO DLL. This is the second function that will be called on
|
||||||
|
your DLL, after kizuna_io_get_api_version.
|
||||||
|
|
||||||
|
All subsequent calls to this API may originate from arbitrary threads.
|
||||||
|
|
||||||
|
Minimum API version: 0x0100 */
|
||||||
|
|
||||||
|
HRESULT kizuna_io_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the state of the cabinet's operator buttons as of the last poll. See
|
||||||
|
KIZUNA_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 kizuna_io_get_opbtns(uint8_t *opbtn);
|
||||||
|
|
||||||
|
/* Get the state of the cabinet's gameplay buttons as of the last poll. See
|
||||||
|
KIZUNA_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 kizuna_io_get_analog(uint8_t *x, uint8_t *y);
|
||||||
|
|
||||||
|
void kizuna_io_get_gamebtns(uint8_t *gamebtns);
|
||||||
|
|
||||||
|
void kizuna_io_read_coin_counter(uint16_t *coins, uint16_t *services);
|
16
kizunaio/meson.build
Normal file
16
kizunaio/meson.build
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
kizunaio_lib = static_library(
|
||||||
|
'kizunaio',
|
||||||
|
name_prefix : '',
|
||||||
|
include_directories : inc,
|
||||||
|
implicit_include_directories : false,
|
||||||
|
c_pch : '../precompiled.h',
|
||||||
|
dependencies : [
|
||||||
|
xinput_lib,
|
||||||
|
],
|
||||||
|
sources : [
|
||||||
|
'kizunaio.c',
|
||||||
|
'kizunaio.h',
|
||||||
|
'config.c',
|
||||||
|
'config.h',
|
||||||
|
],
|
||||||
|
)
|
@ -61,10 +61,12 @@ subdir('exvs2io')
|
|||||||
subdir('saoio')
|
subdir('saoio')
|
||||||
subdir('mkacio')
|
subdir('mkacio')
|
||||||
subdir('tekkenio')
|
subdir('tekkenio')
|
||||||
|
subdir('kizunaio')
|
||||||
|
|
||||||
subdir('taikohook')
|
subdir('taikohook')
|
||||||
subdir('ferrumhook')
|
subdir('ferrumhook')
|
||||||
subdir('exvs2hook')
|
subdir('exvs2hook')
|
||||||
subdir('saohook')
|
subdir('saohook')
|
||||||
subdir('mkachook')
|
subdir('mkachook')
|
||||||
subdir('tekkenhook')
|
subdir('tekkenhook')
|
||||||
|
subdir('kizunahook')
|
||||||
|
@ -73,6 +73,12 @@ HRESULT dns_platform_hook_init(const struct dns_config *cfg)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr = dns_hook_push(L"dev-game.sk2.nbgi-amnet.jp", cfg->startup);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
// if your ISP resolves bad domains, it will kill the network. These 2
|
// if your ISP resolves bad domains, it will kill the network. These 2
|
||||||
// *cannot* resolve
|
// *cannot* resolve
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ void sao_hook_config_load(
|
|||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
assert(filename != NULL);
|
assert(filename != NULL);
|
||||||
|
|
||||||
|
aime_config_load(&cfg->aime, filename);
|
||||||
platform_config_load(&cfg->platform, filename);
|
platform_config_load(&cfg->platform, filename);
|
||||||
sao_dll_config_load(&cfg->dll, filename);
|
sao_dll_config_load(&cfg->dll, filename);
|
||||||
gfx_config_load(&cfg->gfx, filename);
|
gfx_config_load(&cfg->gfx, filename);
|
||||||
|
@ -18,7 +18,8 @@ shared_library(
|
|||||||
hooklib_lib,
|
hooklib_lib,
|
||||||
gfxhook_lib,
|
gfxhook_lib,
|
||||||
jvs_lib,
|
jvs_lib,
|
||||||
board_lib
|
board_lib,
|
||||||
|
aimeio_lib
|
||||||
],
|
],
|
||||||
sources : [
|
sources : [
|
||||||
'dllmain.c',
|
'dllmain.c',
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
LIBRARY saohook
|
LIBRARY saohook
|
||||||
|
|
||||||
EXPORTS
|
EXPORTS
|
||||||
|
aime_io_get_api_version
|
||||||
|
aime_io_init
|
||||||
|
aime_io_led_set_color
|
||||||
|
aime_io_nfc_get_aime_id
|
||||||
|
aime_io_nfc_get_felica_id
|
||||||
|
aime_io_nfc_poll
|
||||||
sao_io_get_api_version
|
sao_io_get_api_version
|
||||||
sao_io_init
|
sao_io_init
|
||||||
sao_io_read_coin_counter
|
sao_io_read_coin_counter
|
||||||
|
Loading…
Reference in New Issue
Block a user