From e5028fb0028616d5c87789adf4bf4bd3104a0a79 Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Thu, 3 Oct 2024 21:08:27 -0400 Subject: [PATCH 1/2] dns: allow uPnP packets through --- hooklib/dns.c | 4 ++++ platform/netenv.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/hooklib/dns.c b/hooklib/dns.c index a07b43c..e7d97c2 100644 --- a/hooklib/dns.c +++ b/hooklib/dns.c @@ -420,6 +420,10 @@ static int WSAAPI hook_getaddrinfo( goto end; } + if (!strcmp(pNodeName, "239.255.255.250") && !strcmp(pServiceName, "1900")) { + return next_getaddrinfo(pNodeName, pServiceName, pHints, ppResult); + } + mbstowcs_s(&wstr_c, NULL, 0, pNodeName, 0); wstr = malloc(wstr_c * sizeof(wchar_t)); diff --git a/platform/netenv.c b/platform/netenv.c index fabfc27..0801011 100644 --- a/platform/netenv.c +++ b/platform/netenv.c @@ -406,6 +406,10 @@ static uint32_t WINAPI hook_GetBestRoute( (int) _byteswap_ulong(src_ip), (int) _byteswap_ulong(dest_ip)); + if ((int) _byteswap_ulong(src_ip) == 0xdfffffff) { + return next_GetBestRoute(src_ip, dest_ip, route); + } + memset(route, 0, sizeof(*route)); /* This doesn't seem to get read? It just needs to succeed. */ From 43a6dfbcb4bb60e197a2438cda4b739bde9b923e Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Fri, 4 Oct 2024 03:09:51 -0400 Subject: [PATCH 2/2] add kizuna 2, load aime reader properly --- Package.mk | 12 ++++ aimeio/aimeio.c | 2 +- board/sg-nfc.c | 4 +- dist/kizuna/bananatools.ini | 54 +++++++++++++++ dist/kizuna/start.bat | 10 +++ kizunahook/config.c | 37 ++++++++++ kizunahook/config.h | 29 ++++++++ kizunahook/dllmain.c | 104 ++++++++++++++++++++++++++++ kizunahook/kizuna-dll.c | 106 +++++++++++++++++++++++++++++ kizunahook/kizuna-dll.h | 23 +++++++ kizunahook/kizunahook.def | 15 ++++ kizunahook/meson.build | 33 +++++++++ kizunahook/usio.c | 99 +++++++++++++++++++++++++++ kizunahook/usio.h | 7 ++ kizunaio/config.c | 29 ++++++++ kizunaio/config.h | 30 ++++++++ kizunaio/kizunaio.c | 132 ++++++++++++++++++++++++++++++++++++ kizunaio/kizunaio.def | 9 +++ kizunaio/kizunaio.h | 67 ++++++++++++++++++ kizunaio/meson.build | 16 +++++ meson.build | 4 +- platform/dns.c | 6 ++ saohook/config.c | 1 + saohook/meson.build | 3 +- saohook/saohook.def | 6 ++ 25 files changed, 833 insertions(+), 5 deletions(-) create mode 100644 dist/kizuna/bananatools.ini create mode 100644 dist/kizuna/start.bat create mode 100644 kizunahook/config.c create mode 100644 kizunahook/config.h create mode 100644 kizunahook/dllmain.c create mode 100644 kizunahook/kizuna-dll.c create mode 100644 kizunahook/kizuna-dll.h create mode 100644 kizunahook/kizunahook.def create mode 100644 kizunahook/meson.build create mode 100644 kizunahook/usio.c create mode 100644 kizunahook/usio.h create mode 100644 kizunaio/config.c create mode 100644 kizunaio/config.h create mode 100644 kizunaio/kizunaio.c create mode 100644 kizunaio/kizunaio.def create mode 100644 kizunaio/kizunaio.h create mode 100644 kizunaio/meson.build diff --git a/Package.mk b/Package.mk index a59e755..afed3f0 100644 --- a/Package.mk +++ b/Package.mk @@ -64,6 +64,17 @@ $(BUILD_DIR_ZIP)/tekken.zip: $(V)strip $(BUILD_DIR_ZIP)/tekken/*.{exe,dll} $(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: \ $(DOC_DIR)/ferrumhook.md \ $(DOC_DIR)/taikohook.md \ @@ -80,6 +91,7 @@ $(BUILD_DIR_ZIP)/bananatools.zip: \ $(BUILD_DIR_ZIP)/sao.zip \ $(BUILD_DIR_ZIP)/mkac.zip \ $(BUILD_DIR_ZIP)/tekken.zip \ + $(BUILD_DIR_ZIP)/kizuna.zip \ $(BUILD_DIR_ZIP)/doc.zip \ README.md \ diff --git a/aimeio/aimeio.c b/aimeio/aimeio.c index f505aac..2555eb4 100644 --- a/aimeio/aimeio.c +++ b/aimeio/aimeio.c @@ -170,7 +170,7 @@ uint16_t aime_io_get_api_version(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; } diff --git a/board/sg-nfc.c b/board/sg-nfc.c index 2db684d..3e57b26 100644 --- a/board/sg-nfc.c +++ b/board/sg-nfc.c @@ -204,7 +204,7 @@ static HRESULT sg_nfc_cmd_get_fw_version( { /* Dest version is not NUL terminated, this is intentional */ 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; } @@ -216,7 +216,7 @@ static HRESULT sg_nfc_cmd_get_hw_version( { /* Dest version is not NUL terminated, this is intentional */ 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; } diff --git a/dist/kizuna/bananatools.ini b/dist/kizuna/bananatools.ini new file mode 100644 index 0000000..3c381b3 --- /dev/null +++ b/dist/kizuna/bananatools.ini @@ -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 + diff --git a/dist/kizuna/start.bat b/dist/kizuna/start.bat new file mode 100644 index 0000000..206038b --- /dev/null +++ b/dist/kizuna/start.bat @@ -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 \ No newline at end of file diff --git a/kizunahook/config.c b/kizunahook/config.c new file mode 100644 index 0000000..87af819 --- /dev/null +++ b/kizunahook/config.c @@ -0,0 +1,37 @@ +#include +#include + +#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); +} diff --git a/kizunahook/config.h b/kizunahook/config.h new file mode 100644 index 0000000..8128af2 --- /dev/null +++ b/kizunahook/config.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#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); + diff --git a/kizunahook/dllmain.c b/kizunahook/dllmain.c new file mode 100644 index 0000000..cc71c61 --- /dev/null +++ b/kizunahook/dllmain.c @@ -0,0 +1,104 @@ +#include +#include + +#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); +} \ No newline at end of file diff --git a/kizunahook/kizuna-dll.c b/kizunahook/kizuna-dll.c new file mode 100644 index 0000000..5acb803 --- /dev/null +++ b/kizunahook/kizuna-dll.c @@ -0,0 +1,106 @@ +#include + +#include +#include + +#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; +} \ No newline at end of file diff --git a/kizunahook/kizuna-dll.h b/kizunahook/kizuna-dll.h new file mode 100644 index 0000000..095167d --- /dev/null +++ b/kizunahook/kizuna-dll.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#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); diff --git a/kizunahook/kizunahook.def b/kizunahook/kizunahook.def new file mode 100644 index 0000000..01d694a --- /dev/null +++ b/kizunahook/kizunahook.def @@ -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 \ No newline at end of file diff --git a/kizunahook/meson.build b/kizunahook/meson.build new file mode 100644 index 0000000..059e0a4 --- /dev/null +++ b/kizunahook/meson.build @@ -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', + ], +) diff --git a/kizunahook/usio.c b/kizunahook/usio.c new file mode 100644 index 0000000..139944a --- /dev/null +++ b/kizunahook/usio.c @@ -0,0 +1,99 @@ +#include + +#include +#include +#include +#include + +#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; +} diff --git a/kizunahook/usio.h b/kizunahook/usio.h new file mode 100644 index 0000000..f4b4883 --- /dev/null +++ b/kizunahook/usio.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#include "board/usio.h" + +HRESULT kizuna_usio_hook_init(const struct usio_config *cfg); \ No newline at end of file diff --git a/kizunaio/config.c b/kizunaio/config.c new file mode 100644 index 0000000..927df51 --- /dev/null +++ b/kizunaio/config.c @@ -0,0 +1,29 @@ +#include + +#include +#include +#include + +#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); +} \ No newline at end of file diff --git a/kizunaio/config.h b/kizunaio/config.h new file mode 100644 index 0000000..2e78b76 --- /dev/null +++ b/kizunaio/config.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#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); \ No newline at end of file diff --git a/kizunaio/kizunaio.c b/kizunaio/kizunaio.c new file mode 100644 index 0000000..f65ff50 --- /dev/null +++ b/kizunaio/kizunaio.c @@ -0,0 +1,132 @@ +#include +#include + +#include +#include +#include + +#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; +} \ No newline at end of file diff --git a/kizunaio/kizunaio.def b/kizunaio/kizunaio.def new file mode 100644 index 0000000..ceb5fa2 --- /dev/null +++ b/kizunaio/kizunaio.def @@ -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 \ No newline at end of file diff --git a/kizunaio/kizunaio.h b/kizunaio/kizunaio.h new file mode 100644 index 0000000..d51ae32 --- /dev/null +++ b/kizunaio/kizunaio.h @@ -0,0 +1,67 @@ +#pragma once + +#include + +#include + +#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); \ No newline at end of file diff --git a/kizunaio/meson.build b/kizunaio/meson.build new file mode 100644 index 0000000..e7a2316 --- /dev/null +++ b/kizunaio/meson.build @@ -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', + ], +) diff --git a/meson.build b/meson.build index edd8281..3894773 100644 --- a/meson.build +++ b/meson.build @@ -61,10 +61,12 @@ subdir('exvs2io') subdir('saoio') subdir('mkacio') subdir('tekkenio') +subdir('kizunaio') subdir('taikohook') subdir('ferrumhook') subdir('exvs2hook') subdir('saohook') subdir('mkachook') -subdir('tekkenhook') \ No newline at end of file +subdir('tekkenhook') +subdir('kizunahook') diff --git a/platform/dns.c b/platform/dns.c index 2c8886f..b457365 100644 --- a/platform/dns.c +++ b/platform/dns.c @@ -73,6 +73,12 @@ HRESULT dns_platform_hook_init(const struct dns_config *cfg) 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 // *cannot* resolve diff --git a/saohook/config.c b/saohook/config.c index a541321..4e4e98f 100644 --- a/saohook/config.c +++ b/saohook/config.c @@ -59,6 +59,7 @@ void sao_hook_config_load( assert(cfg != NULL); assert(filename != NULL); + aime_config_load(&cfg->aime, filename); platform_config_load(&cfg->platform, filename); sao_dll_config_load(&cfg->dll, filename); gfx_config_load(&cfg->gfx, filename); diff --git a/saohook/meson.build b/saohook/meson.build index e1ef0e8..4445d54 100644 --- a/saohook/meson.build +++ b/saohook/meson.build @@ -18,7 +18,8 @@ shared_library( hooklib_lib, gfxhook_lib, jvs_lib, - board_lib + board_lib, + aimeio_lib ], sources : [ 'dllmain.c', diff --git a/saohook/saohook.def b/saohook/saohook.def index d9bfa74..6a0d4fe 100644 --- a/saohook/saohook.def +++ b/saohook/saohook.def @@ -1,6 +1,12 @@ LIBRARY saohook 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_init sao_io_read_coin_counter