tekken: fix io

platform: add gethostbyname hook
This commit is contained in:
Hay1tsme 2023-11-12 05:13:44 -05:00
parent 5e5614d24b
commit cd10a98dcc
12 changed files with 177 additions and 29 deletions

View File

@ -16,7 +16,7 @@ serial=282814450001
; Set the network environment. Most games seem to want 192.168.123.X ; Set the network environment. Most games seem to want 192.168.123.X
[netenv] [netenv]
enable=1 enable=1
subnet=192.168.123.0 subnet=192.168.138.0
; Graphics hook, may cause crashes in some games ; Graphics hook, may cause crashes in some games
[gfx] [gfx]
@ -30,7 +30,7 @@ systemVersion=TE7100-1-NA-SYS0-A03
; Control the AMCUS replacement class ; Control the AMCUS replacement class
[amcus] [amcus]
enable=1 enable=0
game_id=SDBS game_id=SDBS
game_cd=TR21 game_cd=TR21
am_game_ver=1.80 am_game_ver=1.80
@ -50,9 +50,15 @@ port=3
; Mappings for the najv4 IO board. To disable JVS emulation and use ; Mappings for the najv4 IO board. To disable JVS emulation and use
; a real board, set enable to 0 in the "jvs" section. ; a real board, set enable to 0 in the "jvs" section.
[najv4] [najv4]
test=0x24 ; "Home" key test=0x24
coin=0x2D ; "Insert" key coin=0x2D
service=0x2E ; "Delete" key service=0x2E
up=0x26 ; Up arrow up=0x26
down=0x28 ; Down arrow down=0x28
enter=0x0D ; "Enter" key left=0x25
right=0x27
start=0x20
p1b1=0x31
p1b2=0x32
p1b3=0x33
p1b4=0x34

View File

@ -39,6 +39,7 @@ dinput8_lib = cc.find_library('dinput8')
dxguid_lib = cc.find_library('dxguid') dxguid_lib = cc.find_library('dxguid')
xinput_lib = cc.find_library('xinput') xinput_lib = cc.find_library('xinput')
cfgmgr32_lib = cc.find_library('cfgmgr32') cfgmgr32_lib = cc.find_library('cfgmgr32')
ws232_lib = cc.find_library('ws2_32')
inc = include_directories('.') inc = include_directories('.')
capnhook = subproject('capnhook') capnhook = subproject('capnhook')

View File

@ -7,6 +7,7 @@ platform_lib = static_library(
capnhook.get_variable('hook_dep'), capnhook.get_variable('hook_dep'),
shlwapi_lib, shlwapi_lib,
cfgmgr32_lib, cfgmgr32_lib,
ws232_lib,
], ],
link_with : [ link_with : [
board_lib board_lib

View File

@ -16,12 +16,14 @@
static BOOL WINAPI my_BlockInput(BOOL fBlockIt); static BOOL WINAPI my_BlockInput(BOOL fBlockIt);
static int WINAPI my_ShowCursor(BOOL bShow); static int WINAPI my_ShowCursor(BOOL bShow);
static BOOL WINAPI my_GetCursorInfo(PCURSORINFO pci); 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 HRESULT reg_read_sys_ver(void *bytes, uint32_t *nbytes);
static BOOL (WINAPI *next_BlockInput)(BOOL fBlockIt); static BOOL (WINAPI *next_BlockInput)(BOOL fBlockIt);
static int (WINAPI *next_ShowCursor)(BOOL bShow); static int (WINAPI *next_ShowCursor)(BOOL bShow);
static BOOL (WINAPI *next_GetCursorInfo)(PCURSORINFO pci); static BOOL (WINAPI *next_GetCursorInfo)(PCURSORINFO pci);
static UINT (WINAPI *next_GetDriveTypeA)(LPCSTR lpRootPathName);
static struct misc_config config; static struct misc_config config;
static int real_cursor_state = 0; 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[] = { static const struct reg_hook_val nbgi_reg[] = {
{ {
.name = L"SystemVersion", .name = L"SystemVersion",
@ -63,6 +73,12 @@ HRESULT misc_hook_init(const struct misc_config *cfg)
"User32.dll", "User32.dll",
misc_hook_syms, misc_hook_syms,
_countof(misc_hook_syms)); _countof(misc_hook_syms));
hook_table_apply(
NULL,
"kernel32.dll",
misc_k32_syms,
_countof(misc_k32_syms));
reg_hook_push_key( reg_hook_push_key(
HKEY_LOCAL_MACHINE, HKEY_LOCAL_MACHINE,
@ -124,4 +140,29 @@ static HRESULT reg_read_sys_ver(void *bytes, uint32_t *nbytes)
{ {
dprintf("Misc: Get system version\n"); dprintf("Misc: Get system version\n");
return reg_hook_read_wstr(bytes, nbytes, config.system_version); 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);
}
} }

View File

@ -1,6 +1,8 @@
#include <windows.h> #include <windows.h>
#include <wincrypt.h> #include <wincrypt.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#include <winsock.h>
#include <winsock2.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@ -76,6 +78,8 @@ static uint32_t WINAPI hook_IcmpSendEcho2(
uint32_t ReplySize, uint32_t ReplySize,
uint32_t Timeout); uint32_t Timeout);
static struct hostent *WSAAPI my_gethostbyname(const char *name);
/* Link pointers */ /* Link pointers */
static uint32_t (WINAPI *next_GetAdaptersAddresses)( static uint32_t (WINAPI *next_GetAdaptersAddresses)(
@ -122,6 +126,8 @@ static uint32_t (WINAPI *next_IcmpSendEcho)(
DWORD ReplySize, DWORD ReplySize,
DWORD Timeout); DWORD Timeout);
static struct hostent* (*WSAAPI next_gethostbyname)(const char *name);
static const struct hook_symbol netenv_hook_syms[] = { static const struct hook_symbol netenv_hook_syms[] = {
{ {
.name = "GetAdaptersAddresses", .name = "GetAdaptersAddresses",
@ -149,7 +155,14 @@ static const struct hook_symbol netenv_hook_syms[] = {
.link = (void **) &next_IcmpSendEcho2, .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_prefix;
static uint32_t netenv_ip_iface; static uint32_t netenv_ip_iface;
static uint32_t netenv_ip_router; static uint32_t netenv_ip_router;
@ -175,6 +188,13 @@ HRESULT netenv_hook_init(
"iphlpapi.dll", "iphlpapi.dll",
netenv_hook_syms, netenv_hook_syms,
_countof(netenv_hook_syms)); _countof(netenv_hook_syms));
hook_table_apply(
NULL,
"ws2_32.dll",
netenv_ws2_syms,
_countof(netenv_ws2_syms));
return S_OK; return S_OK;
} }
@ -551,3 +571,23 @@ static uint32_t WINAPI hook_IcmpSendEcho(
return 1; 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;
}

View File

@ -36,7 +36,7 @@ static DWORD CALLBACK tekken_pre_startup(void)
struct dongle_info dinfo; struct dongle_info dinfo;
dinfo.vid = 0x0B9A; dinfo.vid = 0x0B9A;
dinfo.pid = 0x0C10; dinfo.pid = 0x0C20;
wcscpy_s(dinfo.manufacturer, _countof(dinfo.manufacturer), L"BM"); wcscpy_s(dinfo.manufacturer, _countof(dinfo.manufacturer), L"BM");
wcscpy_s(dinfo.product, _countof(dinfo.product), L"RUDI04GBN-274713"); wcscpy_s(dinfo.product, _countof(dinfo.product), L"RUDI04GBN-274713");

View File

@ -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) static void tekken_jvs_read_switches(void *ctx, struct najv4_switch_state *out)
{ {
uint8_t opbtn = 0; uint8_t opbtn = 0;
uint16_t gamebtn = 0;
//dprintf("Tekken JVS: Read Switches\n"); //dprintf("Tekken JVS: Read Switches\n");
assert(out != NULL); assert(out != NULL);
assert(tekken_dll.jvs_poll != NULL); assert(tekken_dll.jvs_poll != NULL);
tekken_dll.jvs_poll(&opbtn); tekken_dll.jvs_poll(&opbtn, &gamebtn);
out->system = 0; out->system = 0;
out->p1 = 0; out->p1 = 0;
@ -74,15 +75,33 @@ static void tekken_jvs_read_switches(void *ctx, struct najv4_switch_state *out)
out->p1 |= 0x4000; out->p1 |= 0x4000;
} }
if (opbtn & 0x04) { // Up if (gamebtn & 0x01) { // Up
out->p1 |= 0x2000; out->p1 |= 0x2000;
} }
if (opbtn & 0x08) { // Down if (gamebtn & 0x02) { // Down
out->p1 |= 0x1000; 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; 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) static void tekken_jvs_read_coin_counter(void *ctx, uint8_t slot_no, uint16_t *out)

View File

@ -7,7 +7,7 @@
struct tekken_dll { struct tekken_dll {
uint16_t api_version; uint16_t api_version;
HRESULT (*jvs_init)(void); 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); void (*jvs_read_coin_counter)(uint16_t *coins);
}; };

View File

@ -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->coin = GetPrivateProfileIntW(L"najv4", L"coin", VK_INSERT, filename);
cfg->up = GetPrivateProfileIntW(L"najv4", L"up", VK_UP, filename); cfg->up = GetPrivateProfileIntW(L"najv4", L"up", VK_UP, filename);
cfg->down = GetPrivateProfileIntW(L"najv4", L"down", VK_DOWN, 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);
} }

View File

@ -8,8 +8,14 @@ struct tekken_najv4_config {
uint8_t service; uint8_t service;
uint8_t up; uint8_t up;
uint8_t down; uint8_t down;
uint8_t enter; uint8_t left;
uint8_t right;
uint8_t start;
uint8_t coin; 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); void tekken_io_najv4_config_load(struct tekken_najv4_config *cfg, const wchar_t *filename);

View File

@ -27,9 +27,10 @@ HRESULT tekken_io_jvs_init(void)
return S_OK; return S_OK;
} }
HRESULT tekken_io_jvs_poll(uint8_t *opbtn) HRESULT tekken_io_jvs_poll(uint8_t *opbtn, uint16_t *gamebtn)
{ {
*opbtn = 0; *opbtn = 0;
*gamebtn = 0;
if ((GetAsyncKeyState(najv4_cfg.test) & 0x8000)) { if ((GetAsyncKeyState(najv4_cfg.test) & 0x8000)) {
*opbtn |= TEKKEN_IO_OPBTN_TEST; *opbtn |= TEKKEN_IO_OPBTN_TEST;
@ -40,15 +41,36 @@ HRESULT tekken_io_jvs_poll(uint8_t *opbtn)
} }
if (GetAsyncKeyState(najv4_cfg.up) & 0x8000) { if (GetAsyncKeyState(najv4_cfg.up) & 0x8000) {
*opbtn |= TEKKEN_IO_OPBTN_UP; *gamebtn |= TEKKEN_IO_GAMEBTN_P1_UP;
} }
if (GetAsyncKeyState(najv4_cfg.down) & 0x8000) { 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) { if (GetAsyncKeyState(najv4_cfg.start) & 0x8000) {
*opbtn |= TEKKEN_IO_OPBTN_ENTER; *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; 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) 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) { if (!tekken_io_coin) {
tekken_io_coin = true; tekken_io_coin = true;
tekken_coin_ct++; tekken_coin_ct++;

View File

@ -9,12 +9,18 @@
enum { enum {
TEKKEN_IO_OPBTN_TEST = 0x01, TEKKEN_IO_OPBTN_TEST = 0x01,
TEKKEN_IO_OPBTN_SERVICE = 0x02, 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 /* 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 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 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 */ 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); void tekken_io_jvs_read_coin_counter(uint16_t *coins);