Add support for Pokken Tournament
Also add XInput emulator.
This commit is contained in:
parent
d767d783b7
commit
a1a6db144d
100
OpenParrot/src/Functions/Games/ES3B/PokkenTournament.cpp
Normal file
100
OpenParrot/src/Functions/Games/ES3B/PokkenTournament.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include <StdInc.h>
|
||||
#include "Utility/InitFunction.h"
|
||||
#include "Functions/Global.h"
|
||||
#include "Utility\Hooking.Patterns.h"
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
#ifdef _M_AMD64
|
||||
extern LPCSTR hookPort;
|
||||
|
||||
static int PokkenGetSerial(int, int, int, int, char* dst)
|
||||
{
|
||||
OutputDebugStringA("Getting Dongle Serial...");
|
||||
memset(dst, 0x00, 0x628);
|
||||
memcpy(dst + 0x428, L"274713190000\0\0", 26);
|
||||
OutputDebugStringA("Got Dongle Serial!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ReturnTrue()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static InitFunction PokkenFunc([]()
|
||||
{
|
||||
hookPort = "COM3";
|
||||
uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0);
|
||||
|
||||
// force windowed
|
||||
// BE 01 00 00 00 8B CE -0x8 // ok 10-24
|
||||
// 18: imageBase + 0x5A5A2A
|
||||
char* windowedPattern = hook::get_pattern<char>("BE 01 00 00 00 8B CE", -0x8);
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
injector::MakeNOP(windowedPattern, 8);
|
||||
injector::WriteMemory<BYTE>(windowedPattern + 0x48, 0x00, true);
|
||||
}
|
||||
|
||||
// Remove BlockInput
|
||||
injector::MakeNOP(windowedPattern+8, 13);
|
||||
|
||||
// make english into japanese
|
||||
// TODO: other system locales
|
||||
// 65 6E 00 00 6A 61 00 00 // ok 10-24
|
||||
// 18: imageBase + 0x9AC1FC
|
||||
char* localePattern = hook::get_pattern<char>("65 6E 00 00 6A 61 00 00");
|
||||
injector::WriteMemory<char>(localePattern, 'j', true);
|
||||
injector::WriteMemory<char>(localePattern + 0x1, 'a', true);
|
||||
|
||||
|
||||
// dongle
|
||||
// 41 B8 28 06 00 00 49 8B CE -0x42 // ok 10-24
|
||||
// 18: imageBase + 0x318610
|
||||
safeJMP(hook::get_pattern("41 B8 28 06 00 00 49 8B CE", -0x42), PokkenGetSerial);
|
||||
|
||||
// icmp pinging
|
||||
// 44 89 4C 24 20 53 41 54 48 83 EC 58 // ok 10-24
|
||||
// 18: imageBase + 0x609450
|
||||
safeJMP(hook::get_pattern("44 89 4C 24 20 53 41 54 48 83 EC 58"), ReturnTrue);
|
||||
|
||||
// subnet check (don't force 192.168.123.xxx)
|
||||
// 48 8B C4 55 48 8D 68 A1 48 81 EC B0 00 00 00 48 C7 45 D7 FE // ok 10-24
|
||||
// 18: imageBase + 0x60A5E0
|
||||
safeJMP(hook::get_pattern("48 8B C4 55 48 8D 68 A1 48 81 EC B0 00 00 00 48 C7 45 D7 FE"), ReturnTrue);
|
||||
|
||||
// no cpuid detection (crashes on Core 2?)
|
||||
// 48 89 5C 24 08 4C 8B C9 C7 41 08 FF FF FF FF // ok 10-24
|
||||
// 18: imageBase + 0x6F7C80
|
||||
injector::MakeRET(hook::get_pattern("48 89 5C 24 08 4C 8B C9 C7 41 08 FF FF FF FF"));
|
||||
|
||||
// don't give usb controller error #2
|
||||
// 48 8D 8F F8 00 00 00 88 9F 05 01 00 00 -0x2 // ok 10-24
|
||||
// 18: imageBase + 0x661820
|
||||
injector::MakeNOP(hook::get_pattern("48 8D 8F F8 00 00 00 88 9F 05 01 00 00", -0x2), 2);
|
||||
|
||||
auto chars = { 'F', 'G', 'J' };
|
||||
|
||||
for (auto cha : chars)
|
||||
{
|
||||
auto patterns = hook::pattern(va("%02X 3A 5C", cha));
|
||||
|
||||
if (patterns.size() > 0)
|
||||
{
|
||||
for (int i = 0; i < patterns.size(); i++)
|
||||
{
|
||||
char* text = patterns.get(i).get<char>(0);
|
||||
std::string text_str(text);
|
||||
|
||||
std::string to_replace = va("%c:\\", cha);
|
||||
std::string replace_with = va(".\\%c", cha);
|
||||
|
||||
std::string replaced = text_str.replace(0, to_replace.length(), replace_with);
|
||||
|
||||
injector::WriteMemoryRaw(text, (char*)replaced.c_str(), replaced.length() + 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, GameID::PokkenTournament);
|
||||
#endif
|
@ -376,6 +376,9 @@ HRESULT __stdcall Hook_DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFI
|
||||
|
||||
static InitFunction initFunc([]()
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::PokkenTournament)
|
||||
return;
|
||||
|
||||
MH_Initialize();
|
||||
|
||||
MH_CreateHookApi(L"DINPUT8.dll", "DirectInput8Create", &Hook_DirectInput8Create, (void**)&__DirectInput8Create);
|
||||
|
334
OpenParrot/src/Functions/PokkenXInputEmu.cpp
Normal file
334
OpenParrot/src/Functions/PokkenXInputEmu.cpp
Normal file
@ -0,0 +1,334 @@
|
||||
#pragma optimize("", off)
|
||||
#ifdef _M_AMD64
|
||||
#include "StdInc.h"
|
||||
#include "Utility/GameDetect.h"
|
||||
#include "Utility/InitFunction.h"
|
||||
#include "PokkenXInputEmu.h"
|
||||
|
||||
struct XboxOneControllerHandler
|
||||
{
|
||||
struct usb_dev_handle *handle;
|
||||
bool isConnected;
|
||||
XBOXONE_STATE controllerState;
|
||||
|
||||
uint8_t lastState[64];
|
||||
unsigned int tickCount;
|
||||
|
||||
XINPUT_GAMEPAD lastGamepadState;
|
||||
};
|
||||
|
||||
XboxOneControllerHandler *controllerHandler[4] = { NULL, NULL, NULL, NULL };
|
||||
HANDLE XboxOneControllerThread[4] = { 0 };
|
||||
HANDLE XboxOneControllerMutex[4] = { 0 };
|
||||
|
||||
static unsigned short idVendor = 0x045E;
|
||||
static unsigned short idProduct = 0x02D1;
|
||||
|
||||
int configuration = 1;
|
||||
int interface = 0;
|
||||
int endpointIn = 0x81;
|
||||
int endpointOut = 0x01;
|
||||
int timeout = 2000; // milliseconds
|
||||
bool controllerInit = false;
|
||||
bool runThread = true;
|
||||
|
||||
// Structure we receive from the controller
|
||||
struct XboxOneControllerState
|
||||
{
|
||||
char eventCount;
|
||||
char unknown;
|
||||
char buttons1;
|
||||
char buttons2;
|
||||
short leftTrigger; // Triggers are 0 - 1023
|
||||
short rightTrigger;
|
||||
short thumbLX; // Axes are -32767 - 32767
|
||||
short thumbLY;
|
||||
short thumbRX;
|
||||
short thumbRY;
|
||||
};
|
||||
|
||||
bool connectController(bool enable)
|
||||
{
|
||||
controllerInit = enable;
|
||||
return true;
|
||||
}
|
||||
|
||||
int iround(double num) {
|
||||
return (num > 0.0) ? (int)floor(num + 0.5) : (int)ceil(num - 0.5);
|
||||
}
|
||||
|
||||
extern int* ffbOffset;
|
||||
|
||||
DWORD WINAPI XInputGetState
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__out XINPUT_STATE* pState // Receives the current state
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
XINPUT_GAMEPAD gamepadState = { 0 };
|
||||
|
||||
gamepadState.wButtons |= *ffbOffset;
|
||||
|
||||
if (pState->dwPacketNumber == UINT_MAX)
|
||||
pState->dwPacketNumber = 0;
|
||||
else
|
||||
pState->dwPacketNumber++;
|
||||
|
||||
pState->Gamepad = gamepadState;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI XInputSetState
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__in XINPUT_VIBRATION* pVibration // The vibration information to send to the controller
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
// We're receiving as XInput [0 ~ 65535], need to be [0 ~ 255] !!
|
||||
int leftVal = iround(((float)pVibration->wLeftMotorSpeed / 65535) * 255);
|
||||
int rightVal = iround(((float)pVibration->wRightMotorSpeed / 65535) * 255);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI XInputGetCapabilities
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__in DWORD dwFlags, // Input flags that identify the device type
|
||||
__out XINPUT_CAPABILITIES* pCapabilities // Receives the capabilities
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
|
||||
if (dwFlags > XINPUT_FLAG_GAMEPAD)
|
||||
{
|
||||
return ERROR_BAD_ARGUMENTS;
|
||||
}
|
||||
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
pCapabilities->Flags = XINPUT_CAPS_VOICE_SUPPORTED;
|
||||
pCapabilities->Type = XINPUT_DEVTYPE_GAMEPAD;
|
||||
pCapabilities->SubType = XINPUT_DEVSUBTYPE_GAMEPAD;
|
||||
|
||||
pCapabilities->Gamepad.wButtons = 0xF3FF;
|
||||
|
||||
pCapabilities->Gamepad.bLeftTrigger = 0xFF;
|
||||
pCapabilities->Gamepad.bRightTrigger = 0xFF;
|
||||
|
||||
pCapabilities->Gamepad.sThumbLX = (SHORT)0xFFC0;
|
||||
pCapabilities->Gamepad.sThumbLY = (SHORT)0xFFC0;
|
||||
pCapabilities->Gamepad.sThumbRX = (SHORT)0xFFC0;
|
||||
pCapabilities->Gamepad.sThumbRY = (SHORT)0xFFC0;
|
||||
|
||||
pCapabilities->Vibration.wLeftMotorSpeed = 0xFF;
|
||||
pCapabilities->Vibration.wRightMotorSpeed = 0xFF;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
void WINAPI XInputEnable
|
||||
(
|
||||
__in bool enable // [in] Indicates whether xinput is enabled or disabled.
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
|
||||
if (controllerInit && !enable)
|
||||
{
|
||||
XINPUT_VIBRATION Vibration = { 0, 0 };
|
||||
int xboxControllerCounter = 0;
|
||||
|
||||
while (xboxControllerCounter < 4)
|
||||
{
|
||||
if (controllerHandler[xboxControllerCounter])
|
||||
{
|
||||
XInputSetState(xboxControllerCounter, &Vibration);
|
||||
}
|
||||
xboxControllerCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI XInputGetDSoundAudioDeviceGuids
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__out GUID* pDSoundRenderGuid, // DSound device ID for render
|
||||
__out GUID* pDSoundCaptureGuid // DSound device ID for capture
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
pDSoundRenderGuid = NULL;
|
||||
pDSoundCaptureGuid = NULL;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD XInputGetBatteryInformation
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__in BYTE devType, // Which device on this user index
|
||||
__out XINPUT_BATTERY_INFORMATION* pBatteryInformation // Contains the level and types of batteries
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
pBatteryInformation->BatteryType = BATTERY_TYPE_WIRED;
|
||||
pBatteryInformation->BatteryLevel = BATTERY_LEVEL_FULL;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI XInputGetKeystroke
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__reserved DWORD dwReserved, // Reserved for future use
|
||||
__out PXINPUT_KEYSTROKE pKeystroke // Pointer to an XINPUT_KEYSTROKE structure that receives an input event.
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
return ERROR_EMPTY; // or ERROR_SUCCESS
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI XInputGetStateEx
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__out XINPUT_STATE* pState // Receives the current state
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
XINPUT_GAMEPAD gamepadState = { 0 };
|
||||
|
||||
gamepadState.wButtons = *ffbOffset;
|
||||
|
||||
if (pState->dwPacketNumber == UINT_MAX)
|
||||
pState->dwPacketNumber = 0;
|
||||
else
|
||||
pState->dwPacketNumber++;
|
||||
pState->Gamepad = gamepadState;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI XInputSetStateEx
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__in XINPUT_VIBRATION_EX* pVibration // The vibration information to send to the controller
|
||||
)
|
||||
{
|
||||
if (!controllerInit)
|
||||
{
|
||||
connectController(true);
|
||||
}
|
||||
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
int leftTriggerVal = iround(((float)pVibration->wLeftTriggerMotorSpeed / 65535) * 255);
|
||||
int rightTriggerVal = iround(((float)pVibration->wRightTriggerMotorSpeed / 65535) * 255);
|
||||
int leftVal = iround(((float)pVibration->wLeftMotorSpeed / 65535) * 255);
|
||||
int rightVal = iround(((float)pVibration->wRightMotorSpeed / 65535) * 255);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
static InitFunction XInputHook([]()
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::PokkenTournament || GameDetect::currentGame == GameID::SchoolOfRagnarok)
|
||||
{
|
||||
controllerInit = true;
|
||||
|
||||
MH_Initialize();
|
||||
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputGetState", &XInputGetState, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputSetState", &XInputSetState, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputGetCapabilities", &XInputGetCapabilities, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputEnable", &XInputEnable, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputGetDSoundAudioDeviceGuids", &XInputGetDSoundAudioDeviceGuids, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputGetBatteryInformation", &XInputGetBatteryInformation, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputGetKeystroke", &XInputGetKeystroke, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputGetStateEx", &XInputGetStateEx, NULL);
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputSetStateEx", &XInputSetStateEx, NULL);
|
||||
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
}
|
||||
});
|
||||
#pragma optimize("", on)
|
||||
#endif
|
154
OpenParrot/src/Functions/PokkenXInputEmu.h
Normal file
154
OpenParrot/src/Functions/PokkenXInputEmu.h
Normal file
@ -0,0 +1,154 @@
|
||||
#include "StdInc.h"
|
||||
#ifdef _M_AMD64
|
||||
|
||||
//
|
||||
// Stricture used for our Xbox One Controller
|
||||
//
|
||||
struct XBOXONE_STATE
|
||||
{
|
||||
int guideButton;
|
||||
int view;
|
||||
int menu;
|
||||
int rightShoulder;
|
||||
int rightTrigger;
|
||||
int rightThumb;
|
||||
int leftShoulder;
|
||||
int leftTrigger;
|
||||
int leftThumb;
|
||||
int thumbRX;
|
||||
int thumbRY;
|
||||
int thumbLX;
|
||||
int thumbLY;
|
||||
int up;
|
||||
int down;
|
||||
int left;
|
||||
int right;
|
||||
int yButton;
|
||||
int bButton;
|
||||
int aButton;
|
||||
int xButton;
|
||||
};
|
||||
|
||||
//
|
||||
// Device types available in XINPUT_CAPABILITIES
|
||||
//
|
||||
#define XINPUT_DEVTYPE_GAMEPAD 0x01
|
||||
|
||||
//
|
||||
// Device subtypes available in XINPUT_CAPABILITIES
|
||||
//
|
||||
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
|
||||
|
||||
//
|
||||
// Flags for XINPUT_CAPABILITIES
|
||||
//
|
||||
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
|
||||
|
||||
//
|
||||
// Constants for gamepad buttons
|
||||
//
|
||||
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
|
||||
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
|
||||
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
|
||||
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
|
||||
#define XINPUT_GAMEPAD_START 0x0010
|
||||
#define XINPUT_GAMEPAD_BACK 0x0020
|
||||
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
|
||||
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
|
||||
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
|
||||
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
|
||||
#define XINPUT_GAMEPAD_A 0x1000
|
||||
#define XINPUT_GAMEPAD_B 0x2000
|
||||
#define XINPUT_GAMEPAD_X 0x4000
|
||||
#define XINPUT_GAMEPAD_Y 0x8000
|
||||
|
||||
#define XINPUT_GAMEPAD_GUIDE 0x400
|
||||
|
||||
//
|
||||
// Flags to pass to XInputGetCapabilities
|
||||
//
|
||||
#define XINPUT_FLAG_GAMEPAD 0x00000001
|
||||
|
||||
//
|
||||
// Devices that support batteries
|
||||
//
|
||||
#define BATTERY_DEVTYPE_GAMEPAD 0x00
|
||||
#define BATTERY_DEVTYPE_HEADSET 0x01
|
||||
|
||||
//
|
||||
// Flags for battery status level
|
||||
//
|
||||
#define BATTERY_TYPE_DISCONNECTED 0x00 // This device is not connected
|
||||
#define BATTERY_TYPE_WIRED 0x01 // Wired device, no battery
|
||||
#define BATTERY_TYPE_ALKALINE 0x02 // Alkaline battery source
|
||||
#define BATTERY_TYPE_NIMH 0x03 // Nickel Metal Hydride battery source
|
||||
#define BATTERY_TYPE_UNKNOWN 0xFF // Cannot determine the battery type
|
||||
|
||||
// These are only valid for wireless, connected devices, with known battery types
|
||||
// The amount of use time remaining depends on the type of device.
|
||||
#define BATTERY_LEVEL_EMPTY 0x00
|
||||
#define BATTERY_LEVEL_LOW 0x01
|
||||
#define BATTERY_LEVEL_MEDIUM 0x02
|
||||
#define BATTERY_LEVEL_FULL 0x03
|
||||
|
||||
// User index definitions
|
||||
#define XUSER_MAX_COUNT 4
|
||||
|
||||
//
|
||||
// Structures used by XInput APIs
|
||||
//
|
||||
typedef struct _XINPUT_GAMEPAD
|
||||
{
|
||||
WORD wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
|
||||
|
||||
typedef struct _XINPUT_STATE
|
||||
{
|
||||
DWORD dwPacketNumber;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
} XINPUT_STATE, *PXINPUT_STATE;
|
||||
|
||||
typedef struct _XINPUT_VIBRATION
|
||||
{
|
||||
WORD wLeftMotorSpeed;
|
||||
WORD wRightMotorSpeed;
|
||||
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
|
||||
|
||||
typedef struct _XINPUT_VIBRATION_EX
|
||||
{
|
||||
WORD wLeftMotorSpeed;
|
||||
WORD wRightMotorSpeed;
|
||||
WORD wLeftTriggerMotorSpeed;
|
||||
WORD wRightTriggerMotorSpeed;
|
||||
} XINPUT_VIBRATION_EX, *PXINPUT_VIBRATION_EX;
|
||||
|
||||
typedef struct _XINPUT_CAPABILITIES
|
||||
{
|
||||
BYTE Type;
|
||||
BYTE SubType;
|
||||
WORD Flags;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
XINPUT_VIBRATION Vibration;
|
||||
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
|
||||
|
||||
typedef struct _XINPUT_BATTERY_INFORMATION
|
||||
{
|
||||
BYTE BatteryType;
|
||||
BYTE BatteryLevel;
|
||||
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
|
||||
|
||||
typedef struct _XINPUT_KEYSTROKE
|
||||
{
|
||||
WORD VirtualKey;
|
||||
WCHAR Unicode;
|
||||
WORD Flags;
|
||||
BYTE UserIndex;
|
||||
BYTE HidCode;
|
||||
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
|
||||
#endif
|
@ -241,7 +241,7 @@ extern linb::ini config;
|
||||
|
||||
static InitFunction initFunc([]()
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::SchoolOfRagnarok)
|
||||
if (GameDetect::currentGame == GameID::PokkenTournament || GameDetect::currentGame == GameID::SchoolOfRagnarok)
|
||||
return;
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
|
@ -201,6 +201,11 @@ void GameDetect::DetectCurrentGame()
|
||||
currentGame = GameID::SchoolOfRagnarok;
|
||||
isNesica = true;
|
||||
}
|
||||
if (*(uint32_t*)(moduleBase + 0x1C04) == 0x7401C3F6)
|
||||
{
|
||||
currentGame = GameID::PokkenTournament;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -38,4 +38,5 @@ enum class GameID
|
||||
RaidenIV,
|
||||
VirtuaRLimit,
|
||||
SchoolOfRagnarok,
|
||||
PokkenTournament,
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user