From 440d7a3c415ebc73837453b29c00b6b83074f4f7 Mon Sep 17 00:00:00 2001 From: 00C0FFEE <49476850+00C0FFEE@users.noreply.github.com> Date: Wed, 8 May 2019 11:58:14 +0200 Subject: [PATCH] FNFSC_added --- .../src/Functions/Games/Other/FNFSC.cpp | 298 ++++++++++++++++++ .../Games/TypeX2/DirectInputWrapper.cpp | 2 + OpenParrot/src/Functions/WindowedDx8.cpp | 2 + OpenParrot/src/Utility/GameDetect.cpp | 3 + OpenParrot/src/Utility/GameID.h | 3 +- 5 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 OpenParrot/src/Functions/Games/Other/FNFSC.cpp diff --git a/OpenParrot/src/Functions/Games/Other/FNFSC.cpp b/OpenParrot/src/Functions/Games/Other/FNFSC.cpp new file mode 100644 index 0000000..9e8f719 --- /dev/null +++ b/OpenParrot/src/Functions/Games/Other/FNFSC.cpp @@ -0,0 +1,298 @@ +#include +#include "Utility/InitFunction.h" +#include "Functions/Global.h" +#include "Utility\Hooking.Patterns.h" +#include +#include +#include + +#pragma comment(lib, "Ws2_32.lib") + +#define clamp( x, xmin, xmax ) min( xmax, max( x, xmin ) ) +typedef unsigned int U32; + +DWORD BaseAddress2 = 0x00400000; +int horizontal2 = 0; +int vertical2 = 0; +HWND hWndRT2 = 0; +HCURSOR cursorhndle2; +// controls +extern int* ffbOffset; +extern int* ffbOffset2; +extern int* ffbOffset3; +extern int* ffbOffset4; +// hooks ori +BOOL(__stdcall *original_SetWindowPos2)(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); +BOOL(__stdcall *original_CreateWindowExA2)(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); + +DWORD WINAPI InputRT2(LPVOID lpParam) +{ + int deltaTimer = 16; + INT_PTR keyboardBuffer = (0x437F6F8 + BaseAddress2); + INT_PTR keyboardBuffer2 = (0x437FC08 + BaseAddress2); + bool previousLeft = false; + bool previousRight = false; + bool previousUp = false; + bool previousDown = false; + + while (true) + { + // ESCAPE QUITS GAME + if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) + { + exit(0); + } + // buttons see bitwise values in TPui//RawThrills.cs + // START ( = NITRO too) + if (*ffbOffset & 0x08) + { + injector::WriteMemory((keyboardBuffer2 + 4 * 0x00), 2, true); + injector::WriteMemory((keyboardBuffer + DIK_NUMPADENTER), 2, true); + + } + // TEST + if (*ffbOffset & 0x01) + { + injector::WriteMemory(keyboardBuffer2 + 0x0B * sizeof(U32), 2, true); + } + // NITRO ( = START too) + if (*ffbOffset & 0x100) + { + injector::WriteMemory((keyboardBuffer2 + 4 * 0x00), 2, true); + injector::WriteMemory((keyboardBuffer + DIK_NUMPADENTER), 2, true); + } + // SHIFT DOWN + if (*ffbOffset & 0x2000) + { + if (!previousDown) + { + injector::WriteMemory((keyboardBuffer + DIK_DOWN), 2, true); + previousDown = true; + } + + else + { + previousDown = false; + } + } + // SHIFT UP + if (*ffbOffset & 0x1000) + { + if (!previousUp) + { + injector::WriteMemory((keyboardBuffer + DIK_UP), 2, true); + previousUp = true; + } + + else + { + previousUp = false; + } + } + // BUTTON 1/ VIEW 1 + if (*ffbOffset & 0x200) + { + injector::WriteMemory(keyboardBuffer + DIK_A, 2, true); + injector::WriteMemory(keyboardBuffer2 + 0x01 * sizeof(U32), 2, true); + } + // BUTTON 2/ VIEW 2 + if (*ffbOffset & 0x400) + { + injector::WriteMemory(keyboardBuffer + DIK_B, 2, true); + injector::WriteMemory(keyboardBuffer2 + 0x02 * sizeof(U32), 2, true); + } + // BUTTON 3/ VIEW 3 + if (*ffbOffset & 0x800) + { + injector::WriteMemory(keyboardBuffer + DIK_E, 2, true); + injector::WriteMemory(keyboardBuffer2 + 0x03 * sizeof(U32), 2, true); + } + // MENU LEFT + if (*ffbOffset & 0x4000) + { + if (!previousLeft) + { + injector::WriteMemory((keyboardBuffer + DIK_LEFT), 2, true); + previousLeft = true; + } + + else + { + previousLeft = false; + } + } + // MENU RIGHT + if (*ffbOffset & 0x8000) + { + if (!previousRight) + { + injector::WriteMemory((keyboardBuffer + DIK_RIGHT), 2, true); + previousRight = true; + } + + else + { + previousRight = false; + } + } + // WHEEL + int iWheel0 = (((float)*ffbOffset2) - 128); + float wheel = (iWheel0 * 0.0078125f); + int iWheel = (int)(2047.5 + 2047.5 * wheel); + injector::WriteMemory((0x437F808 + BaseAddress2) + 0x20 * sizeof(U32), iWheel, true); + injector::WriteMemory((0x4380208 + BaseAddress2), wheel, true); + //// GAS + float gas = (float)*ffbOffset3 / 255.0f; + int iGas = (int)(gas * 4095); + injector::WriteMemory((0x437F808 + BaseAddress2) + 0x21 * sizeof(U32), iGas, true); + injector::WriteMemory((0x438020C + BaseAddress2), gas, true); + //// BRAKE + float brake = (float)*ffbOffset4 / 255.0f; + int iBrake = (int)(brake * 4095); + injector::WriteMemory((0x437F808 + BaseAddress2) + 0x22 * sizeof(U32), iBrake, true); + injector::WriteMemory((0x438020C + BaseAddress2), brake, true); + + //DEBUG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // info(true, "test value %f ", test); + //DEBUG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Sleep(deltaTimer); + } + + return 0; +} + +DWORD WINAPI FullscreenRT2(LPVOID lpParam) +{ + while (true) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT2 == 0) + { + hWndRT2 = FindWindowA(NULL, "FNF SuperCars"); + } + if (hWndTMP == hWndRT2) + { + // UGLY FULLSCREEN FIX (borderless window resized to desktop size) + RECT rect; + GetWindowRect(hWndRT2, &rect); + int currentwidth = rect.right - rect.left; + int currentheight = rect.bottom - rect.top; + if (currentwidth != horizontal2) + original_SetWindowPos2(hWndRT2, NULL, 0, 0, horizontal2, vertical2, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); + if (currentheight != vertical2) + original_SetWindowPos2(hWndRT2, NULL, 0, 0, horizontal2, vertical2, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); + } + Sleep(2000); + } +} + +DWORD WINAPI WindowRT2(LPVOID lpParam) +{ + while (true) + { + // RIGHT-CLICK MINIMIZES WINDOW + if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT2 == 0) + { + hWndRT2 = FindWindowA(NULL, "FNF SuperCars"); + } + if (hWndTMP == hWndRT2) + { + original_SetWindowPos2(hWndRT2, HWND_BOTTOM, 0, 0, 1360, 768, SWP_NOSIZE); + ShowWindow(hWndRT2, SW_MINIMIZE); + } + } + } +} + +BOOL(__stdcall *original_DefWindowProcA2)(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +DWORD WINAPI DefWindowProcART2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static int xClick; + static int yClick; + + switch (message) + { + case WM_LBUTTONDOWN: + SetCapture(hWnd); + xClick = LOWORD(lParam); + yClick = HIWORD(lParam); + break; + + case WM_LBUTTONUP: + ReleaseCapture(); + break; + + case WM_MOUSEMOVE: + { + if (GetCapture() == hWnd) + { + RECT rcWindow; + GetWindowRect(hWnd, &rcWindow); + int xMouse = LOWORD(lParam); + int yMouse = HIWORD(lParam); + int xWindow = rcWindow.left + xMouse - xClick; + int yWindow = rcWindow.top + yMouse - yClick; + original_SetWindowPos2(hWnd, NULL, xWindow, yWindow, 1360, 768, SWP_NOSIZE | SWP_NOZORDER); + } + break; + } + + } + return original_DefWindowProcA2(hWnd, message, wParam, lParam); +} + +DWORD WINAPI CreateWindowExART2(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_CreateWindowExA2(dwExStyle, lpClassName, "FNF SuperCars", 0x96000000, 0, 0, 1360, 768, hWndParent, hMenu, hInstance, lpParam); +} + +DWORD WINAPI SetCursorPosRT2(int X, int Y) +{ + return 1; +} + +DWORD WINAPI SetWindowPosRT2(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) +{ + return 1; +} + +static InitFunction FNFSCFunc([]() +{ + GetDesktopResolution(horizontal2, vertical2); + cursorhndle2 = GetCursor(); + + // REMOVE ERROR MESSAGEBOX ON CLOSE + injector::WriteMemory((0x73794 + BaseAddress2), 0xEB, true); + + // REMOVE CMD WATSON nonsense + injector::MakeNOP((0x5F3882), 2, true); + + CreateThread(NULL, 0, InputRT2, NULL, 0, NULL); + + MH_Initialize(); + MH_CreateHookApi(L"user32.dll", "CreateWindowExA", &CreateWindowExART2, (void**)&original_CreateWindowExA2); + MH_CreateHookApi(L"user32.dll", "SetWindowPos", &SetWindowPosRT2, (void**)&original_SetWindowPos2); + MH_EnableHook(MH_ALL_HOOKS); + + if (ToBool(config["General"]["Windowed"])) + { + // NO HIDE CURSOR + injector::WriteMemory((0x72FCF + BaseAddress2), 0x01, true); + + CreateThread(NULL, 0, WindowRT2, NULL, 0, NULL); + + MH_Initialize(); + MH_CreateHookApi(L"user32.dll", "DefWindowProcA", &DefWindowProcART2, (void**)&original_DefWindowProcA2); + MH_CreateHookApi(L"user32.dll", "SetCursorPos", &SetCursorPosRT2, NULL); + MH_EnableHook(MH_ALL_HOOKS); + } + else + { + CreateThread(NULL, 0, FullscreenRT2, NULL, 0, NULL); + } + +}, GameID::FNFSC); diff --git a/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp index 4b0d1d5..7d0fc64 100644 --- a/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp +++ b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp @@ -380,6 +380,8 @@ static InitFunction initFunc([]() return; if (GameDetect::currentGame == GameID::FNFDrift) return; + if (GameDetect::currentGame == GameID::FNFSC) + return; MH_Initialize(); MH_CreateHookApi(L"DINPUT8.dll", "DirectInput8Create", &Hook_DirectInput8Create, (void**)&__DirectInput8Create); diff --git a/OpenParrot/src/Functions/WindowedDx8.cpp b/OpenParrot/src/Functions/WindowedDx8.cpp index fceb4c2..10a4321 100644 --- a/OpenParrot/src/Functions/WindowedDx8.cpp +++ b/OpenParrot/src/Functions/WindowedDx8.cpp @@ -80,6 +80,8 @@ static InitFunction initFunc([]() { if (GameDetect::currentGame == GameID::BG4) return; + if (GameDetect::currentGame == GameID::FNFSC) // FORCE BORDERLESS WINDOW MODE FOR FULLSCREEN + InitD3D8WindowHook(); if (ToBool(config["General"]["Windowed"])) { InitD3D8WindowHook(); diff --git a/OpenParrot/src/Utility/GameDetect.cpp b/OpenParrot/src/Utility/GameDetect.cpp index a925954..d831e5a 100644 --- a/OpenParrot/src/Utility/GameDetect.cpp +++ b/OpenParrot/src/Utility/GameDetect.cpp @@ -377,6 +377,9 @@ void GameDetect::DetectCurrentGame() case 0x47922b80: // FNF Drift currentGame = GameID::FNFDrift; break; + case 0x4929f3ca: // FNF SuperCars + currentGame = GameID::FNFSC; + break; //case 0xea1984ff: // currentGame = GameID::ExBoardGeneric; // break; diff --git a/OpenParrot/src/Utility/GameID.h b/OpenParrot/src/Utility/GameID.h index 58bdbaf..5bf4db6 100644 --- a/OpenParrot/src/Utility/GameID.h +++ b/OpenParrot/src/Utility/GameID.h @@ -52,5 +52,6 @@ enum class GameID GRID, UltraStreetFighterIV, UltraStreetFighterIVDevExe, - FNFDrift + FNFDrift, + FNFSC }; \ No newline at end of file