From affe3ac0828d2469581c73d9d5c8bc0d92c236ad Mon Sep 17 00:00:00 2001 From: 00C0FFEE <49476850+00C0FFEE@users.noreply.github.com> Date: Mon, 1 Jul 2019 14:13:28 +0200 Subject: [PATCH] JusticeLeague-ADDED 1st GLOBAL-VR game to be added to TP!!! --- .../Functions/Games/Other/JusticeLeague.cpp | 210 ++++++++++++++++++ .../Games/TypeX2/DirectInputWrapper.cpp | 2 +- OpenParrot/src/Functions/WindowedDx9.cpp | 2 +- OpenParrot/src/Functions/XInputEmu.cpp | 50 ++++- OpenParrot/src/Utility/GameDetect.cpp | 20 +- OpenParrot/src/Utility/GameID.h | 3 +- 6 files changed, 280 insertions(+), 7 deletions(-) create mode 100644 OpenParrot/src/Functions/Games/Other/JusticeLeague.cpp diff --git a/OpenParrot/src/Functions/Games/Other/JusticeLeague.cpp b/OpenParrot/src/Functions/Games/Other/JusticeLeague.cpp new file mode 100644 index 0000000..83de667 --- /dev/null +++ b/OpenParrot/src/Functions/Games/Other/JusticeLeague.cpp @@ -0,0 +1,210 @@ +#include +#include "Utility/InitFunction.h" +#include "Functions/Global.h" +#include "Utility\Hooking.Patterns.h" +#include +#include +#include +#include +#include +#include + +#pragma comment(lib, "Ws2_32.lib") +#if _M_IX86 +#define clamp( x, xmin, xmax ) min( xmax, max( x, xmin ) ) +typedef unsigned int U32; +typedef unsigned char U8; + +static DWORD BaseAddress8 = 0x00400000; +static int horizontal8 = 0; +static int vertical8 = 0; +static HWND hWndRT8 = 0; + +static bool previousLeft = false; +static bool previousRight = false; +static bool previousUp = false; +static bool previousDown = false; + +static bool TESTpressed = false; +static bool COIN1pressed = false; +static bool COIN2pressed = false; + +// controls +extern int* ffbOffset; +extern int* ffbOffset2; +extern int* ffbOffset3; +extern int* ffbOffset4; +// hooks ori +BOOL(__stdcall* original_SetWindowPos8)(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); +BOOL(__stdcall* original_CreateWindowExA8)(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); +BOOL(__stdcall* original_GetPrivateProfileStringA8)(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize, LPCSTR lpFileName); + + +DWORD WINAPI InputRT8(LPVOID lpParam) +{ + int deltaTimer = 16; + + while (true) + { + // ESCAPE QUITS GAME + if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT8 == 0) + { + hWndRT8 = FindWindowA(NULL, "Justice League"); + } + if (hWndTMP == hWndRT8) + { + exit(0); + } + } + + // regular buttons are emulated by XINPUTEMU + // TEST + if (*ffbOffset & 0x01) + { + if (TESTpressed == false) + { + keybd_event(0x4F, MapVirtualKey(0x4F, MAPVK_VK_TO_VSC), 0, 0); + TESTpressed = true; + } + } + else + { + if (TESTpressed == true) + { + keybd_event(0x4F, MapVirtualKey(0x4F, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0); + TESTpressed = false; + } + } + Sleep(deltaTimer); + } + + return 0; +} + +DWORD WINAPI WindowRT8(LPVOID lpParam) +{ + while (true) + { + // LEFT-CLICK MOVES WINDOW FROM TOP-LEFT CORNER + if (GetAsyncKeyState(VK_LBUTTON) & 0x8000) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT8 == 0) + { + hWndRT8 = FindWindowA(NULL, "Justice League"); + } + if (hWndTMP == hWndRT8) + { + POINT point; + GetCursorPos(&point); + RECT rect; + GetWindowRect(hWndRT8, &rect); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + LPARAM blah = MAKELPARAM(point.x, point.y); + int xClick = LOWORD(blah); + int yClick = HIWORD(blah); + if ((xClick + (width/2)) > horizontal8) + { + xClick = (horizontal8 - width); + } + if ((yClick + (height/2)) > vertical8) + { + yClick = (vertical8 - height); + } + original_SetWindowPos8(hWndRT8, HWND_TOP, xClick, yClick, 1360, 768, SWP_NOSIZE); + SetForegroundWindow(hWndRT8); + + } + } + // RIGHT-CLICK MINIMIZES WINDOW + if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT8 == 0) + { + hWndRT8 = FindWindowA(NULL, "Justice League"); + } + if (hWndTMP == hWndRT8) + { + RECT rect; + GetWindowRect(hWndRT8, &rect); + int currentwidth = rect.right - rect.left; + int currentheight = rect.bottom - rect.top; + original_SetWindowPos8(hWndRT8, HWND_BOTTOM, 0, 0, 1360, 768, SWP_NOSIZE); + ShowWindow(hWndRT8, SW_MINIMIZE); + } + else ShowWindow(hWndRT8, SW_SHOWDEFAULT); + } + } +} + +DWORD WINAPI GetPrivateProfileStringART8(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, DWORD nSize, LPCSTR lpFileName) +{ + char buffer[256]; + LPCSTR fs = "true"; + LPCSTR resX = itoa(horizontal8, buffer, 10); + LPCSTR resY = itoa(vertical8, buffer, 10); + if (ToBool(config["General"]["Windowed"])) + { + fs = "false"; + resX = "1360"; + resY = "768"; + } + + if (_stricmp(lpKeyName, "Fullscreen") == 0) + { + WritePrivateProfileStringA(lpAppName, lpKeyName, fs, lpFileName); + } + if (_stricmp(lpKeyName, "ScreenResolutionX") == 0) + { + WritePrivateProfileStringA(lpAppName, lpKeyName, resX, lpFileName); + } + if (_stricmp(lpKeyName, "ScreenResolutionY") == 0) + { + WritePrivateProfileStringA(lpAppName, lpKeyName, resY, lpFileName); + } + if (_stricmp(lpKeyName, "DisplayWidth") == 0) + { + WritePrivateProfileStringA(lpAppName, lpKeyName, resX, lpFileName); + } + if (_stricmp(lpKeyName, "DisplayHeight") == 0) + { + WritePrivateProfileStringA(lpAppName, lpKeyName, resY, lpFileName); + } + + return original_GetPrivateProfileStringA8(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, lpFileName); +} + +DWORD WINAPI CreateWindowExART8(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) +{ + return original_CreateWindowExA8(dwExStyle, lpClassName, "Justice League", 0x96000000, 0, 0, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); +} + +DWORD WINAPI SetWindowPosRT8(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) +{ + return original_SetWindowPos8(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); +} + +static InitFunction JLeagueFunc([]() +{ + GetDesktopResolution(horizontal8, vertical8); + + CreateThread(NULL, 0, InputRT8, NULL, 0, NULL); + + MH_Initialize(); + MH_CreateHookApi(L"kernel32.dll", "GetPrivateProfileStringA", &GetPrivateProfileStringART8, (void**)& original_GetPrivateProfileStringA8); + MH_CreateHookApi(L"user32.dll", "CreateWindowExA", &CreateWindowExART8, (void**)& original_CreateWindowExA8); + MH_CreateHookApi(L"user32.dll", "SetWindowPos", &SetWindowPosRT8, (void**)& original_SetWindowPos8); + MH_EnableHook(MH_ALL_HOOKS); + + if (ToBool(config["General"]["Windowed"])) + { + CreateThread(NULL, 0, WindowRT8, NULL, 0, NULL); + } + +}, GameID::JLeague); +#endif \ No newline at end of file diff --git a/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp index 7d30710..65b1e1f 100644 --- a/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp +++ b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp @@ -376,7 +376,7 @@ HRESULT __stdcall Hook_DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFI static InitFunction initFunc([]() { - if (GameDetect::currentGame == GameID::PokkenTournament || GameDetect::currentGame == GameID::FNFDrift || GameDetect::currentGame == GameID::FNFSC || GameDetect::currentGame == GameID::FNF || GameDetect::currentGame == GameID::FNFSB || GameDetect::currentGame == GameID::FNFSB2 || GameDetect::currentGame == GameID::GHA) + if (GameDetect::currentGame == GameID::PokkenTournament || GameDetect::currentGame == GameID::FNFDrift || GameDetect::currentGame == GameID::FNFSC || GameDetect::currentGame == GameID::FNF || GameDetect::currentGame == GameID::FNFSB || GameDetect::currentGame == GameID::FNFSB2 || GameDetect::currentGame == GameID::GHA || GameDetect::currentGame == GameID::JLeague) return; MH_Initialize(); diff --git a/OpenParrot/src/Functions/WindowedDx9.cpp b/OpenParrot/src/Functions/WindowedDx9.cpp index 3df28cd..1881093 100644 --- a/OpenParrot/src/Functions/WindowedDx9.cpp +++ b/OpenParrot/src/Functions/WindowedDx9.cpp @@ -70,7 +70,7 @@ extern linb::ini config; static InitFunction initFunc([]() { - if (GameDetect::currentGame == GameID::BG4) + if (GameDetect::currentGame == GameID::BG4 || GameDetect::currentGame == GameID::JLeague) return; if (ToBool(config["General"]["Windowed"])) { diff --git a/OpenParrot/src/Functions/XInputEmu.cpp b/OpenParrot/src/Functions/XInputEmu.cpp index e4b0e8e..6f4d5ee 100644 --- a/OpenParrot/src/Functions/XInputEmu.cpp +++ b/OpenParrot/src/Functions/XInputEmu.cpp @@ -118,6 +118,54 @@ DWORD WINAPI XInputGetState gamepadState.bRightTrigger = 0; } + if (GameDetect::currentGame == GameID::JLeague) + { + gamepadState.wButtons = 0; + gamepadState.bLeftTrigger = 0; + gamepadState.bRightTrigger = 0; + gamepadState.sThumbRX = 0; + gamepadState.sThumbRY = 0; + // AXIS X + gamepadState.sThumbLX = *ffbOffset2; + // AXIS Y + gamepadState.sThumbLY = *ffbOffset3; + // START + if (*ffbOffset & 0x08) + { + gamepadState.wButtons = XINPUT_GAMEPAD_START; + } + // BUTTON1 + if (*ffbOffset & 0x0100) + { + gamepadState.wButtons = XINPUT_GAMEPAD_A; + } + // BUTTON2 + if (*ffbOffset & 0x0200) + { + gamepadState.wButtons = XINPUT_GAMEPAD_B; + } + // BUTTON3 + if (*ffbOffset & 0x0400) + { + gamepadState.wButtons = XINPUT_GAMEPAD_X; + } + // BUTTON4 + if (*ffbOffset & 0x0800) + { + gamepadState.wButtons = XINPUT_GAMEPAD_Y; + } + } + else + { + gamepadState.wButtons = 0; + gamepadState.bLeftTrigger = 0; + gamepadState.bRightTrigger = 0; + gamepadState.sThumbLX = 0; + gamepadState.sThumbLY = 0; + gamepadState.sThumbRX = 0; + gamepadState.sThumbRY = 0; + } + #ifdef _M_IX86 if (GameDetect::currentGame == GameID::Daytona3) { @@ -375,7 +423,7 @@ LPCWSTR ptrToUse; static InitFunction XInputHook([]() { - if (GameDetect::currentGame == GameID::PokkenTournament || GameDetect::currentGame == GameID::SchoolOfRagnarok || GameDetect::currentGame == GameID::Daytona3 || GameDetect::currentGame == GameID::GHA) + if (GameDetect::currentGame == GameID::PokkenTournament || GameDetect::currentGame == GameID::SchoolOfRagnarok || GameDetect::currentGame == GameID::Daytona3 || GameDetect::currentGame == GameID::GHA || GameDetect::currentGame == GameID::JLeague) { controllerInit = true; diff --git a/OpenParrot/src/Utility/GameDetect.cpp b/OpenParrot/src/Utility/GameDetect.cpp index 61bce85..9b3aa3d 100644 --- a/OpenParrot/src/Utility/GameDetect.cpp +++ b/OpenParrot/src/Utility/GameDetect.cpp @@ -1,11 +1,13 @@ #include #include "GameDetect.h" +#include #pragma optimize("", off) bool GameDetect::isNesica = false; bool GameDetect::enableNesysEmu = true; NesicaKey GameDetect::NesicaKey; X2Type GameDetect::X2Type = X2Type::None; static char newCrc[0x400]; + void GameDetect::DetectCurrentGame() { uint32_t crcResult = GetCRC32(GetModuleHandle(nullptr), 0x400); @@ -408,10 +410,19 @@ void GameDetect::DetectCurrentGame() currentGame = GameID::Daytona3; break; } - if (*(uint32_t*)(moduleBase + 0x2CC751) == 0x6B75C084) + // IF GAME = JusticeLeague (if workingdir\JLA.exe exists) , AVOID THIS CHECK (note: darius checked offset is beyond JLA exe limits and TP crashes...) + char working_directory[MAX_PATH + 1]; + GetCurrentDirectoryA(sizeof(working_directory), working_directory); + std::string JLAexestr0 = working_directory; + std::string JLAexestr = JLAexestr0 + "\\JLA.exe"; + bool JLAexists(std::filesystem::exists(JLAexestr.c_str())); + if (JLAexists == false) { - currentGame = GameID::DariusBurst; - break; + if (*(uint32_t*)(moduleBase + 0x2CC751) == 0x6B75C084) + { + currentGame = GameID::DariusBurst; + break; + } } #else // X64 @@ -456,6 +467,9 @@ void GameDetect::DetectCurrentGame() case 0xfe7afff4: currentGame = GameID::FNFSB2; break; + case 0x72c27333: + currentGame = GameID::JLeague; + break; default: #ifdef _DEBUG info(true, "---------------------------------"); diff --git a/OpenParrot/src/Utility/GameID.h b/OpenParrot/src/Utility/GameID.h index 6ca421c..8ad78f3 100644 --- a/OpenParrot/src/Utility/GameID.h +++ b/OpenParrot/src/Utility/GameID.h @@ -57,5 +57,6 @@ enum class GameID FNF, FNFSB, FNFSB2, - GHA + GHA, + JLeague }; \ No newline at end of file