From cd10a98dcc2fc6b6d54a12f1fa5c1604082aab11 Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Sun, 12 Nov 2023 05:13:44 -0500 Subject: [PATCH] tekken: fix io platform: add gethostbyname hook --- dist/tekken/bananatools.ini | 22 ++++++++++++------- meson.build | 1 + platform/meson.build | 1 + platform/misc.c | 41 ++++++++++++++++++++++++++++++++++++ platform/netenv.c | 42 ++++++++++++++++++++++++++++++++++++- tekkenhook/dllmain.c | 2 +- tekkenhook/jvs.c | 27 ++++++++++++++++++++---- tekkenhook/tekken-dll.h | 2 +- tekkenio/config.c | 8 ++++++- tekkenio/config.h | 8 ++++++- tekkenio/tekkenio.c | 34 ++++++++++++++++++++++++------ tekkenio/tekkenio.h | 18 ++++++++++------ 12 files changed, 177 insertions(+), 29 deletions(-) diff --git a/dist/tekken/bananatools.ini b/dist/tekken/bananatools.ini index 02198b3..3421f59 100644 --- a/dist/tekken/bananatools.ini +++ b/dist/tekken/bananatools.ini @@ -16,7 +16,7 @@ serial=282814450001 ; Set the network environment. Most games seem to want 192.168.123.X [netenv] enable=1 -subnet=192.168.123.0 +subnet=192.168.138.0 ; Graphics hook, may cause crashes in some games [gfx] @@ -30,7 +30,7 @@ systemVersion=TE7100-1-NA-SYS0-A03 ; Control the AMCUS replacement class [amcus] -enable=1 +enable=0 game_id=SDBS game_cd=TR21 am_game_ver=1.80 @@ -50,9 +50,15 @@ port=3 ; Mappings for the najv4 IO board. To disable JVS emulation and use ; a real board, set enable to 0 in the "jvs" section. [najv4] -test=0x24 ; "Home" key -coin=0x2D ; "Insert" key -service=0x2E ; "Delete" key -up=0x26 ; Up arrow -down=0x28 ; Down arrow -enter=0x0D ; "Enter" key +test=0x24 +coin=0x2D +service=0x2E +up=0x26 +down=0x28 +left=0x25 +right=0x27 +start=0x20 +p1b1=0x31 +p1b2=0x32 +p1b3=0x33 +p1b4=0x34 diff --git a/meson.build b/meson.build index d77b982..edd8281 100644 --- a/meson.build +++ b/meson.build @@ -39,6 +39,7 @@ dinput8_lib = cc.find_library('dinput8') dxguid_lib = cc.find_library('dxguid') xinput_lib = cc.find_library('xinput') cfgmgr32_lib = cc.find_library('cfgmgr32') +ws232_lib = cc.find_library('ws2_32') inc = include_directories('.') capnhook = subproject('capnhook') diff --git a/platform/meson.build b/platform/meson.build index 7bd7cd5..e5805af 100644 --- a/platform/meson.build +++ b/platform/meson.build @@ -7,6 +7,7 @@ platform_lib = static_library( capnhook.get_variable('hook_dep'), shlwapi_lib, cfgmgr32_lib, + ws232_lib, ], link_with : [ board_lib diff --git a/platform/misc.c b/platform/misc.c index 8601811..cb5fda7 100644 --- a/platform/misc.c +++ b/platform/misc.c @@ -16,12 +16,14 @@ static BOOL WINAPI my_BlockInput(BOOL fBlockIt); static int WINAPI my_ShowCursor(BOOL bShow); static BOOL WINAPI my_GetCursorInfo(PCURSORINFO pci); +static UINT WINAPI my_GetDriveTypeA(LPCSTR lpRootPathName); static HRESULT reg_read_sys_ver(void *bytes, uint32_t *nbytes); static BOOL (WINAPI *next_BlockInput)(BOOL fBlockIt); static int (WINAPI *next_ShowCursor)(BOOL bShow); static BOOL (WINAPI *next_GetCursorInfo)(PCURSORINFO pci); +static UINT (WINAPI *next_GetDriveTypeA)(LPCSTR lpRootPathName); static struct misc_config config; static int real_cursor_state = 0; @@ -42,6 +44,14 @@ static const struct hook_symbol misc_hook_syms[] = { } }; +static const struct hook_symbol misc_k32_syms[] = { + { + .name = "GetDriveTypeA", + .patch = my_GetDriveTypeA, + .link = (void **) &next_GetDriveTypeA, + }, +}; + static const struct reg_hook_val nbgi_reg[] = { { .name = L"SystemVersion", @@ -63,6 +73,12 @@ HRESULT misc_hook_init(const struct misc_config *cfg) "User32.dll", misc_hook_syms, _countof(misc_hook_syms)); + + hook_table_apply( + NULL, + "kernel32.dll", + misc_k32_syms, + _countof(misc_k32_syms)); reg_hook_push_key( HKEY_LOCAL_MACHINE, @@ -124,4 +140,29 @@ static HRESULT reg_read_sys_ver(void *bytes, uint32_t *nbytes) { dprintf("Misc: Get system version\n"); return reg_hook_read_wstr(bytes, nbytes, config.system_version); +} + +static UINT WINAPI my_GetDriveTypeA(LPCSTR lpRootPathName) +{ + dprintf("Misc: Get Drive Type for %s\n", lpRootPathName); + + switch (lpRootPathName[0]) { + case 'C': + case 'c': + case 'D': + case 'd': + case 'E': + case 'e': + case 'F': + case 'f': + case 'G': + case 'g': + case 'H': + case 'h': + case 'I': + case 'i': + case 'J': + case 'j': return DRIVE_FIXED; + default: return next_GetDriveTypeA(lpRootPathName); + } } \ No newline at end of file diff --git a/platform/netenv.c b/platform/netenv.c index 621311c..fabfc27 100644 --- a/platform/netenv.c +++ b/platform/netenv.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include @@ -76,6 +78,8 @@ static uint32_t WINAPI hook_IcmpSendEcho2( uint32_t ReplySize, uint32_t Timeout); +static struct hostent *WSAAPI my_gethostbyname(const char *name); + /* Link pointers */ static uint32_t (WINAPI *next_GetAdaptersAddresses)( @@ -122,6 +126,8 @@ static uint32_t (WINAPI *next_IcmpSendEcho)( DWORD ReplySize, DWORD Timeout); +static struct hostent* (*WSAAPI next_gethostbyname)(const char *name); + static const struct hook_symbol netenv_hook_syms[] = { { .name = "GetAdaptersAddresses", @@ -149,7 +155,14 @@ static const struct hook_symbol netenv_hook_syms[] = { .link = (void **) &next_IcmpSendEcho2, } }; - +static const struct hook_symbol netenv_ws2_syms[] = { + { + .name = "gethostbyname", + .ordinal = 52, + .patch = my_gethostbyname, + .link = (void **) &next_gethostbyname, + } +}; static uint32_t netenv_ip_prefix; static uint32_t netenv_ip_iface; static uint32_t netenv_ip_router; @@ -175,6 +188,13 @@ HRESULT netenv_hook_init( "iphlpapi.dll", netenv_hook_syms, _countof(netenv_hook_syms)); + + hook_table_apply( + NULL, + "ws2_32.dll", + netenv_ws2_syms, + _countof(netenv_ws2_syms)); + return S_OK; } @@ -551,3 +571,23 @@ static uint32_t WINAPI hook_IcmpSendEcho( return 1; } + +static struct hostent WSAAPI *my_gethostbyname(const char *name) +{ + char my_hostname[256]; + gethostname(my_hostname, 256); + dprintf("Netenv: gethostbyname for %s\n", name); + if (strcmp(my_hostname, name)) { + return next_gethostbyname(name); + } + dprintf("Netenv: gethostbyname for local computer\n"); + struct hostent *h = malloc(sizeof(struct hostent));; + h->h_addrtype = AF_INET; + h->h_addr_list = malloc(sizeof(char*)); + h->h_addr_list[0] = malloc(sizeof(char) * 4); + h->h_addr_list[0][0] = (char)(netenv_ip_iface >> 24); + h->h_addr_list[0][1] = (char)(netenv_ip_iface >> 16); + h->h_addr_list[0][2] = (char)(netenv_ip_iface >> 8); + h->h_addr_list[0][3] = (char)netenv_ip_iface; + return h; +} \ No newline at end of file diff --git a/tekkenhook/dllmain.c b/tekkenhook/dllmain.c index 472552f..63007c5 100644 --- a/tekkenhook/dllmain.c +++ b/tekkenhook/dllmain.c @@ -36,7 +36,7 @@ static DWORD CALLBACK tekken_pre_startup(void) struct dongle_info dinfo; dinfo.vid = 0x0B9A; - dinfo.pid = 0x0C10; + dinfo.pid = 0x0C20; wcscpy_s(dinfo.manufacturer, _countof(dinfo.manufacturer), L"BM"); wcscpy_s(dinfo.product, _countof(dinfo.product), L"RUDI04GBN-274713"); diff --git a/tekkenhook/jvs.c b/tekkenhook/jvs.c index b9e6c45..a2b26c1 100644 --- a/tekkenhook/jvs.c +++ b/tekkenhook/jvs.c @@ -55,13 +55,14 @@ HRESULT tekken_jvs_init(struct jvs_node **out) static void tekken_jvs_read_switches(void *ctx, struct najv4_switch_state *out) { uint8_t opbtn = 0; + uint16_t gamebtn = 0; //dprintf("Tekken JVS: Read Switches\n"); assert(out != NULL); assert(tekken_dll.jvs_poll != NULL); - tekken_dll.jvs_poll(&opbtn); + tekken_dll.jvs_poll(&opbtn, &gamebtn); out->system = 0; out->p1 = 0; @@ -74,15 +75,33 @@ static void tekken_jvs_read_switches(void *ctx, struct najv4_switch_state *out) out->p1 |= 0x4000; } - if (opbtn & 0x04) { // Up + if (gamebtn & 0x01) { // Up out->p1 |= 0x2000; } - if (opbtn & 0x08) { // Down + if (gamebtn & 0x02) { // Down out->p1 |= 0x1000; } - if (opbtn & 0x10) { // Enter + if (gamebtn & 0x04) { // Left + out->p1 |= 0x0800; + } + if (gamebtn & 0x08) { // Right + out->p1 |= 0x0400; + } + if (gamebtn & 0x10) { // Start + out->p1 |= 0x8000; + } + if (gamebtn & 0x20) { // P1B1 out->p1 |= 0x0200; } + if (gamebtn & 0x40) { // P1B2 + out->p1 |= 0x0100; + } + if (gamebtn & 0x80) { // P1B3 + out->p1 |= 0x0040; + } + if (gamebtn & 0x100) { // P1B4 + out->p1 |= 0x0020; + } } static void tekken_jvs_read_coin_counter(void *ctx, uint8_t slot_no, uint16_t *out) diff --git a/tekkenhook/tekken-dll.h b/tekkenhook/tekken-dll.h index df183b4..d2e7f14 100644 --- a/tekkenhook/tekken-dll.h +++ b/tekkenhook/tekken-dll.h @@ -7,7 +7,7 @@ struct tekken_dll { uint16_t api_version; HRESULT (*jvs_init)(void); - HRESULT (*jvs_poll)(uint8_t *opbtn); + HRESULT (*jvs_poll)(uint8_t *opbtn, uint16_t *gamebtn); void (*jvs_read_coin_counter)(uint16_t *coins); }; diff --git a/tekkenio/config.c b/tekkenio/config.c index 2a2f2d6..3a4865e 100644 --- a/tekkenio/config.c +++ b/tekkenio/config.c @@ -13,5 +13,11 @@ void tekken_io_najv4_config_load(struct tekken_najv4_config *cfg, const wchar_t cfg->coin = GetPrivateProfileIntW(L"najv4", L"coin", VK_INSERT, filename); cfg->up = GetPrivateProfileIntW(L"najv4", L"up", VK_UP, filename); cfg->down = GetPrivateProfileIntW(L"najv4", L"down", VK_DOWN, filename); - cfg->enter = GetPrivateProfileIntW(L"najv4", L"enter", VK_RETURN, filename); + cfg->left = GetPrivateProfileIntW(L"najv4", L"left", VK_LEFT, filename); + cfg->right = GetPrivateProfileIntW(L"najv4", L"right", VK_RIGHT, filename); + cfg->start = GetPrivateProfileIntW(L"najv4", L"start", VK_SPACE, filename); + cfg->p1b1 = GetPrivateProfileIntW(L"najv4", L"p1b1", '1', filename); + cfg->p1b2 = GetPrivateProfileIntW(L"najv4", L"p1b2", '2', filename); + cfg->p1b3 = GetPrivateProfileIntW(L"najv4", L"p1b3", '3', filename); + cfg->p1b4 = GetPrivateProfileIntW(L"najv4", L"p1b4", '4', filename); } diff --git a/tekkenio/config.h b/tekkenio/config.h index e779170..f80364c 100644 --- a/tekkenio/config.h +++ b/tekkenio/config.h @@ -8,8 +8,14 @@ struct tekken_najv4_config { uint8_t service; uint8_t up; uint8_t down; - uint8_t enter; + uint8_t left; + uint8_t right; + uint8_t start; uint8_t coin; + uint8_t p1b1; + uint8_t p1b2; + uint8_t p1b3; + uint8_t p1b4; }; void tekken_io_najv4_config_load(struct tekken_najv4_config *cfg, const wchar_t *filename); diff --git a/tekkenio/tekkenio.c b/tekkenio/tekkenio.c index 5e74c33..f6568b0 100644 --- a/tekkenio/tekkenio.c +++ b/tekkenio/tekkenio.c @@ -27,9 +27,10 @@ HRESULT tekken_io_jvs_init(void) return S_OK; } -HRESULT tekken_io_jvs_poll(uint8_t *opbtn) +HRESULT tekken_io_jvs_poll(uint8_t *opbtn, uint16_t *gamebtn) { *opbtn = 0; + *gamebtn = 0; if ((GetAsyncKeyState(najv4_cfg.test) & 0x8000)) { *opbtn |= TEKKEN_IO_OPBTN_TEST; @@ -40,15 +41,36 @@ HRESULT tekken_io_jvs_poll(uint8_t *opbtn) } if (GetAsyncKeyState(najv4_cfg.up) & 0x8000) { - *opbtn |= TEKKEN_IO_OPBTN_UP; + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_UP; } if (GetAsyncKeyState(najv4_cfg.down) & 0x8000) { - *opbtn |= TEKKEN_IO_OPBTN_DOWN; + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_DOWN; + } + + if (GetAsyncKeyState(najv4_cfg.left) & 0x8000) { + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_LEFT; + } + + if (GetAsyncKeyState(najv4_cfg.right) & 0x8000) { + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_RIGHT; } - if (GetAsyncKeyState(najv4_cfg.enter) & 0x8000) { - *opbtn |= TEKKEN_IO_OPBTN_ENTER; + if (GetAsyncKeyState(najv4_cfg.start) & 0x8000) { + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_START; + } + + if (GetAsyncKeyState(najv4_cfg.p1b1) & 0x8000) { + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_BUTTON1; + } + if (GetAsyncKeyState(najv4_cfg.p1b2) & 0x8000) { + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_BUTTON2; + } + if (GetAsyncKeyState(najv4_cfg.p1b3) & 0x8000) { + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_BUTTON3; + } + if (GetAsyncKeyState(najv4_cfg.p1b4) & 0x8000) { + *gamebtn |= TEKKEN_IO_GAMEBTN_P1_BUTTON4; } return S_OK; @@ -56,7 +78,7 @@ HRESULT tekken_io_jvs_poll(uint8_t *opbtn) void tekken_io_jvs_read_coin_counter(uint16_t *coins) { - if (GetAsyncKeyState(VK_INSERT) & 0x8000) { + if (GetAsyncKeyState(najv4_cfg.coin) & 0x8000) { if (!tekken_io_coin) { tekken_io_coin = true; tekken_coin_ct++; diff --git a/tekkenio/tekkenio.h b/tekkenio/tekkenio.h index 6a0d5b1..b8d4605 100644 --- a/tekkenio/tekkenio.h +++ b/tekkenio/tekkenio.h @@ -9,12 +9,18 @@ enum { TEKKEN_IO_OPBTN_TEST = 0x01, TEKKEN_IO_OPBTN_SERVICE = 0x02, - TEKKEN_IO_OPBTN_UP = 0x04, - TEKKEN_IO_OPBTN_DOWN = 0x08, - TEKKEN_IO_OPBTN_ENTER = 0x10, - TEKKEN_IO_OPBTN_COIN = 0x20, }; - +enum { + TEKKEN_IO_GAMEBTN_P1_UP = 0x01, + TEKKEN_IO_GAMEBTN_P1_DOWN = 0x02, + TEKKEN_IO_GAMEBTN_P1_LEFT = 0x04, + TEKKEN_IO_GAMEBTN_P1_RIGHT = 0x08, + TEKKEN_IO_GAMEBTN_P1_START = 0x10, + TEKKEN_IO_GAMEBTN_P1_BUTTON1 = 0x20, + TEKKEN_IO_GAMEBTN_P1_BUTTON2 = 0x40, + TEKKEN_IO_GAMEBTN_P1_BUTTON3 = 0x80, + TEKKEN_IO_GAMEBTN_P1_BUTTON4 = 0x100, +}; /* 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 @@ -38,6 +44,6 @@ HRESULT tekken_io_jvs_init(void); Minimum API version: 0x0100 */ -HRESULT tekken_io_jvs_poll(uint8_t *opbtn); +HRESULT tekken_io_jvs_poll(uint8_t *opbtn, uint16_t *gamebtn); void tekken_io_jvs_read_coin_counter(uint16_t *coins);