From 7e11e0ea67de2369cab537b9db6b7776dee55db0 Mon Sep 17 00:00:00 2001 From: 00C0FFEE <49476850+00C0FFEE@users.noreply.github.com> Date: Tue, 14 May 2019 08:36:25 +0200 Subject: [PATCH 1/2] FNFSB_added --- .../src/Functions/Games/Other/FNFSB.cpp | 355 ++++++++++++++++++ .../Games/TypeX2/DirectInputWrapper.cpp | 2 + OpenParrot/src/Utility/GameDetect.cpp | 3 + OpenParrot/src/Utility/GameID.h | 3 +- 4 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 OpenParrot/src/Functions/Games/Other/FNFSB.cpp diff --git a/OpenParrot/src/Functions/Games/Other/FNFSB.cpp b/OpenParrot/src/Functions/Games/Other/FNFSB.cpp new file mode 100644 index 0000000..aa39f6b --- /dev/null +++ b/OpenParrot/src/Functions/Games/Other/FNFSB.cpp @@ -0,0 +1,355 @@ +#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 ) ) + +DWORD BaseAddress4 = 0x00400000; +int horizontal4 = 0; +int vertical4 = 0; +HWND hWndRT4 = 0; +// controls +extern int* ffbOffset; +extern int* ffbOffset2; +extern int* ffbOffset3; +extern int* ffbOffset4; +// hooks ori +BOOL(__stdcall *original_SetWindowPos4)(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); +BOOL(__stdcall *original_CreateWindowExA4)(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_DefWindowProcA4)(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +DWORD WINAPI DefWindowProcART4(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_SetWindowPos4(hWnd, HWND_TOP, xWindow, yWindow, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + } + break; + } + + } + return original_DefWindowProcA4(hWnd, message, wParam, lParam); +} + +DWORD WINAPI InputRT4(LPVOID lpParam) +{ + int deltaTimer = 16; + INT_PTR keyboardBuffer = (0x31943C8 + BaseAddress4); + 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 + if (*ffbOffset & 0x08) + { + injector::WriteMemory((keyboardBuffer + DIK_SPACE), 2, true); + } + // TEST + if (*ffbOffset & 0x01) + { + injector::WriteMemory((0x41599 + BaseAddress4), 0xEB, true); + } + // NITRO ( = START too) + if (*ffbOffset & 0x100) + { + injector::WriteMemory((keyboardBuffer + DIK_N), 2, true); + injector::WriteMemory((keyboardBuffer + DIK_SPACE), 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_F1), 2, true); + injector::WriteMemory((keyboardBuffer + DIK_A), 2, true); + } + // BUTTON 2/ VIEW 2 + if (*ffbOffset & 0x400) + { + injector::WriteMemory((keyboardBuffer + DIK_F2), 2, true); + injector::WriteMemory((keyboardBuffer + DIK_B), 2, true); + } + // BUTTON 3/ VIEW 3 + if (*ffbOffset & 0x800) + { + injector::WriteMemory((keyboardBuffer + DIK_E), 2, true); + injector::WriteMemory((keyboardBuffer + DIK_W), 2, true); + } + // MENU LEFT + if (*ffbOffset & 0x4000) + { + if (previousLeft == false) + { + injector::WriteMemory((keyboardBuffer + DIK_LEFT), 2, true); + previousLeft = true; + } + + else + { + previousLeft = false; + } + } + // MENU RIGHT + if (*ffbOffset & 0x8000) + { + if (previousRight == false) + { + injector::WriteMemory((keyboardBuffer + DIK_RIGHT), 2, true); + previousRight = true; + } + + else + { + previousRight = false; + } + } + + INPUT input[4]; + WORD vkey; + // WHEEL + if (*ffbOffset2 >= 0x85) // RIGHT + { + vkey = 0x66; // NUMPAD6 key down + input[0].type = INPUT_KEYBOARD; + input[0].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[0].ki.time = 0; + input[0].ki.dwExtraInfo = 0; + input[0].ki.wVk = vkey; + input[0].ki.dwFlags = 0; + vkey = 0x64; // NUMPAD4 key up + input[1].type = INPUT_KEYBOARD; + input[1].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[1].ki.time = 0; + input[1].ki.dwExtraInfo = 0; + input[1].ki.wVk = vkey; + input[1].ki.dwFlags = KEYEVENTF_KEYUP; + } + else if (*ffbOffset2 <= 0x75) // LEFT + { + vkey = 0x66; // NUMPAD6 key up + input[0].type = INPUT_KEYBOARD; + input[0].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[0].ki.time = 0; + input[0].ki.dwExtraInfo = 0; + input[0].ki.wVk = vkey; + input[0].ki.dwFlags = KEYEVENTF_KEYUP; + vkey = 0x64; // NUMPAD4 key down + input[1].type = INPUT_KEYBOARD; + input[1].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[1].ki.time = 0; + input[1].ki.dwExtraInfo = 0; + input[1].ki.wVk = vkey; + input[1].ki.dwFlags = 0; + + } + else // CENTER + { + vkey = 0x66; // NUMPAD6 key up + input[0].type = INPUT_KEYBOARD; + input[0].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[0].ki.time = 0; + input[0].ki.dwExtraInfo = 0; + input[0].ki.wVk = vkey; + input[0].ki.dwFlags = KEYEVENTF_KEYUP; + vkey = 0x64; // NUMPAD4 key up + input[1].type = INPUT_KEYBOARD; + input[1].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[1].ki.time = 0; + input[1].ki.dwExtraInfo = 0; + input[1].ki.wVk = vkey; + input[1].ki.dwFlags = KEYEVENTF_KEYUP; + } + + // GAS + if (*ffbOffset3 >= 5) + { + vkey = 0x51; // Q key (qwerty A) + input[2].type = INPUT_KEYBOARD; + input[2].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[2].ki.time = 0; + input[2].ki.dwExtraInfo = 0; + input[2].ki.wVk = vkey; + input[2].ki.dwFlags = 0; + } + else + { + vkey = 0x51; // Q key (qwerty A) + input[2].type = INPUT_KEYBOARD; + input[2].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[2].ki.time = 0; + input[2].ki.dwExtraInfo = 0; + input[2].ki.wVk = vkey; + input[2].ki.dwFlags = KEYEVENTF_KEYUP; + } + + // BRAKE + if (*ffbOffset4 >= 5) + { + vkey = 0x57; // W key (qwerty Z) + input[3].type = INPUT_KEYBOARD; + input[3].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[3].ki.time = 0; + input[3].ki.dwExtraInfo = 0; + input[3].ki.wVk = vkey; + input[3].ki.dwFlags = 0; + } + else + { + vkey = 0x57; // W key (qwerty Z) + input[3].type = INPUT_KEYBOARD; + input[3].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + input[3].ki.time = 0; + input[3].ki.dwExtraInfo = 0; + input[3].ki.wVk = vkey; + input[3].ki.dwFlags = KEYEVENTF_KEYUP; + } + + SendInput(4, input, sizeof(INPUT)); + + //DEBUG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // info(true, "test values *ffbOffset2=0x%02X / *ffbOffset3=0x%02X / *ffbOffset4=0x%02X ", *ffbOffset2, *ffbOffset3, *ffbOffset4); + //DEBUG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Sleep(deltaTimer); + } + return 0; +} + +DWORD WINAPI WindowRT4(LPVOID lpParam) +{ + while (true) + { + // RIGHT-CLICK MINIMIZES WINDOW + if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT4 == 0) + { + hWndRT4 = FindWindowA(NULL, "Fast n Furious SuperBikes"); + } + if (hWndTMP == hWndRT4) + { + original_SetWindowPos4(hWndRT4, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE); + ShowWindow(hWndRT4, SW_MINIMIZE); + } + } + } +} + +DWORD WINAPI CreateWindowExART4(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_CreateWindowExA4(dwExStyle, lpClassName, "Fast n Furious SuperBikes", 0x96C60000, X, Y, (nWidth+16), (nHeight+39), hWndParent, hMenu, hInstance, lpParam); +} + +DWORD WINAPI SetCursorPosRT4(int X, int Y) +{ + return 1; +} + +DWORD WINAPI SetWindowPosRT4(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) +{ + return 1; +} + +static InitFunction FNFSBFunc([]() +{ + GetDesktopResolution(horizontal4, vertical4); + + // REMOVE ERROR MESSAGEBOX ON CLOSE + injector::WriteMemory((0x584AA + BaseAddress4), 0xEB, true); + + // REPLACE SPACE KEY WITH ESC TO PREVENT EXITING LEVEL PREMATURELY + injector::WriteMemory((0x4D1C5 + BaseAddress4), DIK_ESCAPE, true); + + // FIX file write on D: + injector::WriteMemoryRaw((0x125B50 + BaseAddress4), "\x2E\x5C\x65\x72\x72\x6F\x72\x6C\x6F\x67\x2E\x74\x78\x74\x00", 15, true); + + // TEST KEY FIX (uses BACKSPACE now) + injector::MakeNOP((0x4C426 + BaseAddress4), 14); + injector::WriteMemory((0x4C435 + BaseAddress4), DIK_BACK, true); + + CreateThread(NULL, 0, InputRT4, NULL, 0, NULL); + + if (ToBool(config["General"]["Windowed"])) + { + // CURSOR NOT HIDDEN + injector::WriteMemory((0x576CF + BaseAddress4), 0x01, true); + + CreateThread(NULL, 0, WindowRT4, NULL, 0, NULL); + + MH_Initialize(); + MH_CreateHookApi(L"user32.dll", "CreateWindowExA", &CreateWindowExART4, (void**)&original_CreateWindowExA4); + MH_CreateHookApi(L"user32.dll", "SetCursorPos", &SetCursorPosRT4, NULL); + MH_CreateHookApi(L"user32.dll", "SetWindowPos", &SetWindowPosRT4, (void**)&original_SetWindowPos4); + MH_CreateHookApi(L"user32.dll", "DefWindowProcA", &DefWindowProcART4, (void**)&original_DefWindowProcA4); + MH_EnableHook(MH_ALL_HOOKS); + } + +}, GameID::FNFSB); diff --git a/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp index 5e49efd..8442c64 100644 --- a/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp +++ b/OpenParrot/src/Functions/Games/TypeX2/DirectInputWrapper.cpp @@ -384,6 +384,8 @@ static InitFunction initFunc([]() return; if (GameDetect::currentGame == GameID::FNF) return; + if (GameDetect::currentGame == GameID::FNFSB) + return; MH_Initialize(); MH_CreateHookApi(L"DINPUT8.dll", "DirectInput8Create", &Hook_DirectInput8Create, (void**)&__DirectInput8Create); diff --git a/OpenParrot/src/Utility/GameDetect.cpp b/OpenParrot/src/Utility/GameDetect.cpp index 9b807c3..8a93a61 100644 --- a/OpenParrot/src/Utility/GameDetect.cpp +++ b/OpenParrot/src/Utility/GameDetect.cpp @@ -383,6 +383,9 @@ void GameDetect::DetectCurrentGame() case 0x93888a27: // FNF currentGame = GameID::FNF; break; + case 0x6449d9b1: // FNF SuperBikes + currentGame = GameID::FNFSB; + break; //case 0xea1984ff: // currentGame = GameID::ExBoardGeneric; // break; diff --git a/OpenParrot/src/Utility/GameID.h b/OpenParrot/src/Utility/GameID.h index c4b93c8..d1f932d 100644 --- a/OpenParrot/src/Utility/GameID.h +++ b/OpenParrot/src/Utility/GameID.h @@ -54,5 +54,6 @@ enum class GameID UltraStreetFighterIVDevExe, FNFDrift, FNFSC, - FNF + FNF, + FNFSB }; \ No newline at end of file From 607b2641fb57382966ecb4adc3a7755df28c2868 Mon Sep 17 00:00:00 2001 From: 00C0FFEE <49476850+00C0FFEE@users.noreply.github.com> Date: Sat, 18 May 2019 14:26:22 +0200 Subject: [PATCH 2/2] patch1 --- .gitignore | 3 +- .../src/Functions/Games/Other/FNFSB.cpp | 298 ++++++++---------- 2 files changed, 142 insertions(+), 159 deletions(-) diff --git a/.gitignore b/.gitignore index 7559923..b62cbf3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ TeknoParrot/TeknoParrot\.vcxproj\.user ParrotLoader/ParrotLoader\.vcxproj\.user *.user -*.aps \ No newline at end of file +*.aps +OpenParrot/src/Functions/Games/Other/FNFSB2.cpp diff --git a/OpenParrot/src/Functions/Games/Other/FNFSB.cpp b/OpenParrot/src/Functions/Games/Other/FNFSB.cpp index aa39f6b..f514865 100644 --- a/OpenParrot/src/Functions/Games/Other/FNFSB.cpp +++ b/OpenParrot/src/Functions/Games/Other/FNFSB.cpp @@ -14,6 +14,16 @@ DWORD BaseAddress4 = 0x00400000; int horizontal4 = 0; int vertical4 = 0; HWND hWndRT4 = 0; +bool movable4 = false; +bool polling4 = false; + +static bool previousLeft = false; +static bool previousRight = false; +static bool previousUp = false; +static bool previousDown = false; +static bool gaspressed = false; +static bool brakepressed = false; + // controls extern int* ffbOffset; extern int* ffbOffset2; @@ -23,41 +33,45 @@ extern int* ffbOffset4; BOOL(__stdcall *original_SetWindowPos4)(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); BOOL(__stdcall *original_CreateWindowExA4)(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_DefWindowProcA4)(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +BOOL(__stdcall *original_SetCursorPosRT4)(int X, int Y); DWORD WINAPI DefWindowProcART4(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static int xClick; static int yClick; - switch (message) + switch (message) + { + case WM_LBUTTONDOWN: + injector::WriteMemory((0x576CF + BaseAddress4), 0x01, true); + movable4 = true; + break; + + case WM_LBUTTONUP: + injector::WriteMemory((0x576CF + BaseAddress4), 0x00, true); + movable4 = false; + break; + + case WM_MOUSEMOVE: + { + if (movable4 == true) { - case WM_LBUTTONDOWN: - - SetCapture(hWnd); - xClick = LOWORD(lParam); - yClick = HIWORD(lParam); - break; - - case WM_LBUTTONUP: - ReleaseCapture(); - break; - - case WM_MOUSEMOVE: + injector::WriteMemory((0x576CF + BaseAddress4), 0x01, true); + return 0; + } + else { - if (GetCapture() == hWnd) + if (polling4 == false) { - 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_SetWindowPos4(hWnd, HWND_TOP, xWindow, yWindow, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + return 0; + } + if (polling4 == true) + { + break; } - break; - } - } + } + } return original_DefWindowProcA4(hWnd, message, wParam, lParam); } @@ -88,7 +102,7 @@ DWORD WINAPI InputRT4(LPVOID lpParam) // TEST if (*ffbOffset & 0x01) { - injector::WriteMemory((0x41599 + BaseAddress4), 0xEB, true); + injector::WriteMemory((0x4C424 + BaseAddress4), 0xEB, true); } // NITRO ( = START too) if (*ffbOffset & 0x100) @@ -96,34 +110,7 @@ DWORD WINAPI InputRT4(LPVOID lpParam) injector::WriteMemory((keyboardBuffer + DIK_N), 2, true); injector::WriteMemory((keyboardBuffer + DIK_SPACE), 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) { @@ -150,8 +137,10 @@ DWORD WINAPI InputRT4(LPVOID lpParam) injector::WriteMemory((keyboardBuffer + DIK_LEFT), 2, true); previousLeft = true; } - - else + } + else + { + if (previousLeft == true) { previousLeft = false; } @@ -164,142 +153,134 @@ DWORD WINAPI InputRT4(LPVOID lpParam) injector::WriteMemory((keyboardBuffer + DIK_RIGHT), 2, true); previousRight = true; } - - else + } + else + { + if (previousRight == true) { previousRight = false; } } - INPUT input[4]; - WORD vkey; + RECT rect; + GetWindowRect(hWndRT4, &rect); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + int windowcenterx = (rect.left + (width * 0.5)); + int windowcentery = (rect.top + (height * 0.5)); // WHEEL - if (*ffbOffset2 >= 0x85) // RIGHT - { - vkey = 0x66; // NUMPAD6 key down - input[0].type = INPUT_KEYBOARD; - input[0].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[0].ki.time = 0; - input[0].ki.dwExtraInfo = 0; - input[0].ki.wVk = vkey; - input[0].ki.dwFlags = 0; - vkey = 0x64; // NUMPAD4 key up - input[1].type = INPUT_KEYBOARD; - input[1].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[1].ki.time = 0; - input[1].ki.dwExtraInfo = 0; - input[1].ki.wVk = vkey; - input[1].ki.dwFlags = KEYEVENTF_KEYUP; - } - else if (*ffbOffset2 <= 0x75) // LEFT - { - vkey = 0x66; // NUMPAD6 key up - input[0].type = INPUT_KEYBOARD; - input[0].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[0].ki.time = 0; - input[0].ki.dwExtraInfo = 0; - input[0].ki.wVk = vkey; - input[0].ki.dwFlags = KEYEVENTF_KEYUP; - vkey = 0x64; // NUMPAD4 key down - input[1].type = INPUT_KEYBOARD; - input[1].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[1].ki.time = 0; - input[1].ki.dwExtraInfo = 0; - input[1].ki.wVk = vkey; - input[1].ki.dwFlags = 0; + int iWheel0 = (((float)*ffbOffset2) - 128); + float wheel = (iWheel0 * 0.0078125f); + int iWheel = (int)((width - 20) * 0.5 * wheel); + double fx = (float)((0 + wheel) * (65535.0f / horizontal4)); + double fy = (float)((0) *(65535.0f / vertical4)); - } - else // CENTER + if (movable4 == false) // then poll ugly mouse input { - vkey = 0x66; // NUMPAD6 key up - input[0].type = INPUT_KEYBOARD; - input[0].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[0].ki.time = 0; - input[0].ki.dwExtraInfo = 0; - input[0].ki.wVk = vkey; - input[0].ki.dwFlags = KEYEVENTF_KEYUP; - vkey = 0x64; // NUMPAD4 key up - input[1].type = INPUT_KEYBOARD; - input[1].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[1].ki.time = 0; - input[1].ki.dwExtraInfo = 0; - input[1].ki.wVk = vkey; - input[1].ki.dwFlags = KEYEVENTF_KEYUP; + polling4 = true; + mouse_event(MOUSEEVENTF_MOVE, fx, 0, 0, 0); + polling4 = false; } + WORD vkey; // GAS + vkey = 0x51; // Q key (qwerty A) if (*ffbOffset3 >= 5) { - vkey = 0x51; // Q key (qwerty A) - input[2].type = INPUT_KEYBOARD; - input[2].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[2].ki.time = 0; - input[2].ki.dwExtraInfo = 0; - input[2].ki.wVk = vkey; - input[2].ki.dwFlags = 0; + if (gaspressed == false) + { + keybd_event(vkey, MapVirtualKey(vkey, MAPVK_VK_TO_VSC), 0, 0); + gaspressed = true; + } } else { - vkey = 0x51; // Q key (qwerty A) - input[2].type = INPUT_KEYBOARD; - input[2].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[2].ki.time = 0; - input[2].ki.dwExtraInfo = 0; - input[2].ki.wVk = vkey; - input[2].ki.dwFlags = KEYEVENTF_KEYUP; + if (gaspressed == true) + { + keybd_event(vkey, MapVirtualKey(vkey, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0); + gaspressed = false; + } } - + // BRAKE + vkey = 0x57; // W key (qwerty Z) if (*ffbOffset4 >= 5) { - vkey = 0x57; // W key (qwerty Z) - input[3].type = INPUT_KEYBOARD; - input[3].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[3].ki.time = 0; - input[3].ki.dwExtraInfo = 0; - input[3].ki.wVk = vkey; - input[3].ki.dwFlags = 0; + if (brakepressed == false) + { + keybd_event(vkey, MapVirtualKey(vkey, MAPVK_VK_TO_VSC), 0, 0); + brakepressed = true; + } } else { - vkey = 0x57; // W key (qwerty Z) - input[3].type = INPUT_KEYBOARD; - input[3].ki.wScan = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - input[3].ki.time = 0; - input[3].ki.dwExtraInfo = 0; - input[3].ki.wVk = vkey; - input[3].ki.dwFlags = KEYEVENTF_KEYUP; + if (brakepressed == true) + { + keybd_event(vkey, MapVirtualKey(vkey, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0); + brakepressed = false; + } } - SendInput(4, input, sizeof(INPUT)); - //DEBUG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // info(true, "test values *ffbOffset2=0x%02X / *ffbOffset3=0x%02X / *ffbOffset4=0x%02X ", *ffbOffset2, *ffbOffset3, *ffbOffset4); + // info(true, "test values *ffbOffset2=0x%02X / *iWheel=%d / *wheel=%f ", *ffbOffset2, iWheel, fx); //DEBUG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Sleep(deltaTimer); - } + } return 0; } + DWORD WINAPI WindowRT4(LPVOID lpParam) { while (true) { - // RIGHT-CLICK MINIMIZES WINDOW - if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) + // RIGHT-CLICK MINIMIZES WINDOW + if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT4 == 0) { - HWND hWndTMP = GetForegroundWindow(); - if (hWndRT4 == 0) - { - hWndRT4 = FindWindowA(NULL, "Fast n Furious SuperBikes"); - } - if (hWndTMP == hWndRT4) - { - original_SetWindowPos4(hWndRT4, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE); - ShowWindow(hWndRT4, SW_MINIMIZE); - } + hWndRT4 = FindWindowA(NULL, "Fast n Furious SuperBikes"); } + if (hWndTMP == hWndRT4) + { + injector::WriteMemory((0x576CF + BaseAddress4), 0x01, true); + movable4 = true; + original_SetWindowPos4(hWndRT4, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE); + ShowWindow(hWndRT4, SW_MINIMIZE); + } + } + // LEFT-CLICK MOVES WINDOW FROM TOP-LEFT CORNER + if (GetAsyncKeyState(VK_LBUTTON) & 0x8000) + { + HWND hWndTMP = GetForegroundWindow(); + if (hWndRT4 == 0) + { + hWndRT4 = FindWindowA(NULL, "Fast n Furious SuperBikes"); + } + if (hWndTMP == hWndRT4) + { + injector::WriteMemory((0x576CF + BaseAddress4), 0x01, true); + movable4 = true; + POINT point; + GetCursorPos(&point); + RECT rect; + GetWindowRect(hWndRT4, &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); + original_SetWindowPos4(hWndRT4, HWND_TOP, xClick, yClick, width, height, SWP_NOSIZE); + SetForegroundWindow(hWndRT4); + } + } + else + { + injector::WriteMemory((0x576CF + BaseAddress4), 0x00, true); + movable4 = false; + } } } @@ -310,7 +291,7 @@ DWORD WINAPI CreateWindowExART4(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWi DWORD WINAPI SetCursorPosRT4(int X, int Y) { - return 1; + return 0; } DWORD WINAPI SetWindowPosRT4(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) @@ -330,25 +311,26 @@ static InitFunction FNFSBFunc([]() // FIX file write on D: injector::WriteMemoryRaw((0x125B50 + BaseAddress4), "\x2E\x5C\x65\x72\x72\x6F\x72\x6C\x6F\x67\x2E\x74\x78\x74\x00", 15, true); + injector::WriteMemoryRaw((0x11FAD4 + BaseAddress4), "\x2E\x5C\x76\x65\x72\x73\x69\x6F\x6E\x2E\x74\x78\x74\x00", 14, true); // TEST KEY FIX (uses BACKSPACE now) injector::MakeNOP((0x4C426 + BaseAddress4), 14); injector::WriteMemory((0x4C435 + BaseAddress4), DIK_BACK, true); + MH_Initialize(); + MH_CreateHookApi(L"user32.dll", "SetCursorPos", &SetCursorPosRT4, (void**)&original_SetCursorPosRT4); + MH_CreateHookApi(L"user32.dll", "DefWindowProcA", &DefWindowProcART4, (void**)&original_DefWindowProcA4); + MH_EnableHook(MH_ALL_HOOKS); + CreateThread(NULL, 0, InputRT4, NULL, 0, NULL); if (ToBool(config["General"]["Windowed"])) { - // CURSOR NOT HIDDEN - injector::WriteMemory((0x576CF + BaseAddress4), 0x01, true); - CreateThread(NULL, 0, WindowRT4, NULL, 0, NULL); MH_Initialize(); MH_CreateHookApi(L"user32.dll", "CreateWindowExA", &CreateWindowExART4, (void**)&original_CreateWindowExA4); - MH_CreateHookApi(L"user32.dll", "SetCursorPos", &SetCursorPosRT4, NULL); MH_CreateHookApi(L"user32.dll", "SetWindowPos", &SetWindowPosRT4, (void**)&original_SetWindowPos4); - MH_CreateHookApi(L"user32.dll", "DefWindowProcA", &DefWindowProcART4, (void**)&original_DefWindowProcA4); MH_EnableHook(MH_ALL_HOOKS); }