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
[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

View File

@ -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')

View File

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

View File

@ -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);
}
}

View File

@ -1,6 +1,8 @@
#include <windows.h>
#include <wincrypt.h>
#include <iphlpapi.h>
#include <winsock.h>
#include <winsock2.h>
#include <stddef.h>
#include <stdint.h>
@ -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;
}

View File

@ -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");

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)
{
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)

View File

@ -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);
};

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->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);
}

View File

@ -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);

View File

@ -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++;

View File

@ -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);