diff --git a/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp b/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp index 68d1ebe..416c364 100644 --- a/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp +++ b/OpenParrot/src/Functions/Games/TypeX2/TypeX2Generic.cpp @@ -5,6 +5,34 @@ #include "Functions/Global.h" #if _M_IX86 using namespace std::string_literals; +extern int* wheelSection; +extern int* ffbOffset; +extern int* ffbOffset3; +extern int* ffbOffset4; +extern int* ffbOffset5; + +static bool CoinPressed = false; +static bool TestPressed = false; +static bool ServicePressed = false; +static bool TimeStartPressed = false; +static bool StartPressed = false; +static bool ViewPressed = false; +static bool HazardPressed = false; +static bool OverTakePressed = false; +static bool ShiftLeftPressed = false; +static bool ShiftRightPressed = false; +static bool SideBrakePressed = false; +static bool SeatSwitch1Pressed = false; +static bool SeatSwitch2Pressed = false; +static bool Gear1Pressed = false; +static bool Gear2Pressed = false; +static bool Gear3Pressed = false; +static bool Gear4Pressed = false; +static bool Gear5Pressed = false; +static bool Gear6Pressed = false; +static bool KeyPressed = false; +static bool init = false; +static bool MenuHack = false; void AddCommOverride(HANDLE hFile); @@ -101,8 +129,6 @@ static DWORD __stdcall GetFileAttributesAWrapTx2(LPCSTR lpFileName) return GetFileAttributesA(lpFileName); } -extern int* wheelSection; - BOOL __stdcall WriteFileWrapTx2(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToWrite, @@ -159,6 +185,479 @@ BOOL __stdcall WriteFileWrapTx2(HANDLE hFile, return WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); } +static DWORD WINAPI ChangeValues(LPVOID lpParam) +{ + Sleep(10000); + + DWORD imageBase = (DWORD)GetModuleHandleA(0); + + *(BYTE*)(imageBase + 0x42E296) = 0x01; + *(BYTE*)(imageBase + 0x42E295) = 0x80; + injector::MakeNOP(imageBase + 0x27400, 6); + return 0; +} + +static int BG4ThreadLoop() +{ + DWORD imageBase = (DWORD)GetModuleHandleA(0); + + if (!init) + { + init = true; + CreateThread(NULL, 0, ChangeValues, NULL, 0, NULL); + } + + //Hack to allow us to select Manual and Manual with Clutch + INT_PTR MenuTimerBase = *(INT_PTR*)(imageBase + 0x4E2970); + if (MenuTimerBase != NULL) + { + INT_PTR MenuTimerBaseA = *(INT_PTR*)(MenuTimerBase + 0x200); + if (MenuTimerBaseA != NULL) + { + INT_PTR MenuTimerBaseB = *(INT_PTR*)(MenuTimerBaseA + 0x14C); + if (MenuTimerBaseB != NULL) + { + INT_PTR MenuTimerBaseC = *(INT_PTR*)(MenuTimerBaseB + 0x7A4); + if (MenuTimerBaseC != NULL); + { + INT_PTR MenuTime = *(INT_PTR*)(MenuTimerBaseC + 0x45C); + if (MenuTime != NULL); + { + if (MenuTime == 0x1194) + { + MenuHack = true; + } + + if (MenuTime == 0x00) + { + MenuHack = false; + } + } + } + } + } + } + + if (MenuHack) + { + INT_PTR MenuBase = *(INT_PTR*)(imageBase + 0x4DA06C); + if (MenuBase != NULL) + { + INT_PTR MenuBaseA = *(INT_PTR*)(MenuBase + 0x614); + if (MenuBaseA != NULL) + { + INT_PTR MenuBaseB = *(INT_PTR*)(MenuBaseA + 0x54); + if (MenuBaseB != NULL) + { + INT_PTR MenuBaseC = *(INT_PTR*)(MenuBaseB + 0x90); + if (MenuBaseC != NULL); + { + INT_PTR MenuBaseD = *(INT_PTR*)(MenuBaseC + 0x6E4); + if (MenuBaseD != NULL); + { + *(BYTE*)(MenuBaseD + 0x454) = 0x04; + + BYTE MenuBaseE = *(INT_PTR*)(MenuBaseD + 0x44C); + if (MenuBaseE != NULL) + { + if (MenuBaseE == 0x02) + { + *(BYTE*)(imageBase + 0x42E341) = 0xD0; //Set Shift SEN 2 to ON or error + } + else if (MenuBaseE == 0x03) + { + *(BYTE*)(imageBase + 0x42E341) = 0xE0; //Set Shift SEN 1 to ON or error + } + } + } + } + } + } + } + } + + if (*ffbOffset & 0x100) //Test + { + if (!TestPressed) + { + TestPressed = true; + *(BYTE*)(imageBase + 0x42E297) += 0x80; + } + } + else + { + if (TestPressed) + { + TestPressed = false; + *(BYTE*)(imageBase + 0x42E297) -= 0x80; + } + } + + if (*ffbOffset & 0x200) //Service + { + if (!ServicePressed) + { + ServicePressed = true; + *(BYTE*)(imageBase + 0x42E296) += 0x40; + } + } + else + { + if (ServicePressed) + { + ServicePressed = false; + *(BYTE*)(imageBase + 0x42E296) -= 0x40; + } + } + + if (*ffbOffset & 0x800) //Shift Left + { + if (!ShiftLeftPressed) + { + ShiftLeftPressed = true; + *(BYTE*)(imageBase + 0x42E341) -= 0x80; + } + } + else + { + if (ShiftLeftPressed) + { + ShiftLeftPressed = false; + *(BYTE*)(imageBase + 0x42E341) += 0x80; + } + } + + if (*ffbOffset & 0x4000) //Shift Right + { + if (!ShiftRightPressed) + { + ShiftRightPressed = true; + *(BYTE*)(imageBase + 0x42E341) -= 0x40; + } + } + else + { + if (ShiftRightPressed) + { + ShiftRightPressed = false; + *(BYTE*)(imageBase + 0x42E341) += 0x40; + } + } + + if (*ffbOffset & 0x40) //Start + { + if (!StartPressed) + { + StartPressed = true; + *(BYTE*)(imageBase + 0x42E296) += 0x80; + } + } + else + { + if (StartPressed) + { + StartPressed = false; + *(BYTE*)(imageBase + 0x42E296) -= 0x80; + } + } + + if (*ffbOffset & 0x8000) //View + { + if (!ViewPressed) + { + ViewPressed = true; + *(BYTE*)(imageBase + 0x42E296) += 0x20; + } + } + else + { + if (ViewPressed) + { + ViewPressed = false; + *(BYTE*)(imageBase + 0x42E296) -= 0x20; + } + } + + if (*ffbOffset & 0x01) //Hazard + { + if (!HazardPressed) + { + HazardPressed = true; + *(BYTE*)(imageBase + 0x42E296) += 0x10; + } + } + else + { + if (HazardPressed) + { + HazardPressed = false; + *(BYTE*)(imageBase + 0x42E296) -= 0x10; + } + } + + if (*ffbOffset & 0x20) //Overtake + { + if (!OverTakePressed) + { + OverTakePressed = true; + *(BYTE*)(imageBase + 0x42E296) += 0x08; + } + } + else + { + if (OverTakePressed) + { + OverTakePressed = false; + *(BYTE*)(imageBase + 0x42E296) -= 0x08; + } + } + + if (*ffbOffset & 0x02) //SideBrake + { + if (!SideBrakePressed) + { + SideBrakePressed = true; + *(BYTE*)(imageBase + 0x42E296) += 0x02; + } + } + else + { + if (SideBrakePressed) + { + SideBrakePressed = false; + *(BYTE*)(imageBase + 0x42E296) -= 0x02; + } + } + + if (*ffbOffset & 0x10000) //Timer Start + { + if (!TimeStartPressed) + { + TimeStartPressed = true; + *(BYTE*)(imageBase + 0x42E295) += 0x01; + } + } + else + { + if (TimeStartPressed) + { + TimeStartPressed = false; + *(BYTE*)(imageBase + 0x42E295) -= 0x01; + } + } + + if (*ffbOffset & 0x20000) //Seat Switch 1 + { + if (!SeatSwitch1Pressed) + { + SeatSwitch1Pressed = true; + *(BYTE*)(imageBase + 0x42E295) += 0x04; + } + } + else + { + if (SeatSwitch1Pressed) + { + SeatSwitch1Pressed = false; + *(BYTE*)(imageBase + 0x42E295) -= 0x04; + } + } + + if (*ffbOffset & 0x40000) //Seat Switch 2 + { + if (!SeatSwitch2Pressed) + { + SeatSwitch2Pressed = true; + *(BYTE*)(imageBase + 0x42E295) += 0x02; + } + } + else + { + if (SeatSwitch2Pressed) + { + SeatSwitch2Pressed = false; + *(BYTE*)(imageBase + 0x42E295) -= 0x02; + } + } + + if (*ffbOffset & 0x400) //Coin Chute 1 + { + if (!CoinPressed) + { + CoinPressed = true; + INT_PTR CoinBase = *(INT_PTR*)(imageBase + 0x4E2970); + if (CoinBase != NULL) + { + INT_PTR CoinBaseA = *(INT_PTR*)(CoinBase + 0x08); + if (CoinBaseA != NULL) + { + INT_PTR CoinBaseB = *(INT_PTR*)(CoinBaseA + 0x04); + if (CoinBaseB != NULL) + { + INT_PTR CoinBaseC = *(INT_PTR*)(CoinBaseB + 0x254); + if (CoinBaseC != NULL); + { + ++* (BYTE*)(CoinBaseC + 0x34); + } + } + } + } + *(BYTE*)(imageBase + 0x42E294) += 0x40; + } + } + else + { + if (CoinPressed) + { + CoinPressed = false; + *(BYTE*)(imageBase + 0x42E294) -= 0x40; + } + } + + if (*ffbOffset & 0x2000) //Key + { + if (!KeyPressed) + { + KeyPressed = true; + *(BYTE*)(imageBase + 0x42E296) += 0x04; + } + } + else + { + if (KeyPressed) + { + KeyPressed = false; + *(BYTE*)(imageBase + 0x42E296) -= 0x04; + } + } + + if (*ffbOffset & 0x100000) //Gear 1 + { + if ((!Gear1Pressed) && (!Gear2Pressed) && (!Gear3Pressed) && (!Gear4Pressed) && (!Gear5Pressed) && (!Gear6Pressed)) + { + Gear1Pressed = true; + *(BYTE*)(imageBase + 0x42E295) -= 0x80; + *(BYTE*)(imageBase + 0x42E341) -= 0x80; + } + } + else + { + if (Gear1Pressed) + { + Gear1Pressed = false; + *(BYTE*)(imageBase + 0x42E295) += 0x80; + *(BYTE*)(imageBase + 0x42E341) += 0x80; + } + } + + if (*ffbOffset & 0x200000) //Gear 2 + { + if ((!Gear2Pressed) && (!Gear1Pressed) && (!Gear3Pressed) && (!Gear4Pressed) && (!Gear5Pressed) && (!Gear6Pressed)) + { + Gear2Pressed = true; + *(BYTE*)(imageBase + 0x42E296) -= 0x01; + *(BYTE*)(imageBase + 0x42E341) -= 0x80; + } + } + else + { + if (Gear2Pressed) + { + Gear2Pressed = false; + *(BYTE*)(imageBase + 0x42E296) += 0x01; + *(BYTE*)(imageBase + 0x42E341) += 0x80; + } + } + + if (*ffbOffset & 0x08) //Gear 3 / Shift Up + { + if ((!Gear3Pressed) && (!Gear2Pressed) && (!Gear1Pressed) && (!Gear4Pressed) && (!Gear5Pressed) && (!Gear6Pressed)) + { + Gear3Pressed = true; + *(BYTE*)(imageBase + 0x42E296) -= 0x01; + } + } + else + { + if (Gear3Pressed) + { + Gear3Pressed = false; + *(BYTE*)(imageBase + 0x42E296) += 0x01; + } + } + + if (*ffbOffset & 0x04) //Gear 4 / Shift Down + { + if ((!Gear4Pressed) && (!Gear2Pressed) && (!Gear3Pressed) && (!Gear1Pressed) && (!Gear5Pressed) && (!Gear6Pressed)) + { + Gear4Pressed = true; + *(BYTE*)(imageBase + 0x42E295) -= 0x80; + } + } + else + { + if (Gear4Pressed) + { + Gear4Pressed = false; + *(BYTE*)(imageBase + 0x42E295) += 0x80; + } + } + + if (*ffbOffset & 0x1000000) //Gear 5 + { + if ((!Gear5Pressed) && (!Gear2Pressed) && (!Gear3Pressed) && (!Gear4Pressed) && (!Gear1Pressed) && (!Gear6Pressed)) + { + Gear5Pressed = true; + *(BYTE*)(imageBase + 0x42E295) -= 0x80; + *(BYTE*)(imageBase + 0x42E341) -= 0x40; + } + } + else + { + if (Gear5Pressed) + { + Gear5Pressed = false; + *(BYTE*)(imageBase + 0x42E295) += 0x80; + *(BYTE*)(imageBase + 0x42E341) += 0x40; + } + } + + if (*ffbOffset & 0x2000000) //Gear 6/Reverse + { + if ((!Gear6Pressed) && (!Gear2Pressed) && (!Gear3Pressed) && (!Gear4Pressed) && (!Gear5Pressed) && (!Gear1Pressed)) + { + Gear6Pressed = true; + *(BYTE*)(imageBase + 0x42E296) -= 0x01; + *(BYTE*)(imageBase + 0x42E341) -= 0x40; + } + } + else + { + if (Gear6Pressed) + { + Gear6Pressed = false; + *(BYTE*)(imageBase + 0x42E296) += 0x01; + *(BYTE*)(imageBase + 0x42E341) += 0x40; + } + } + + *(float*)(imageBase + 0x42D994) = (*wheelSection - 128) / 128.0; // Steering + *(float*)(imageBase + 0x42D998) = (*ffbOffset3) / 255.0; // Gas + *(float*)(imageBase + 0x42D99C) = (*ffbOffset4) / 255.0; // Brake + *(float*)(imageBase + 0x42D9A0) = (*ffbOffset5) / 255.0; // Clutch + + return 0; +} + +static DWORD WINAPI BG4RunningLoop(LPVOID lpParam) +{ + while (true) + { + BG4ThreadLoop(); + Sleep(16); + } +} + static InitFunction initFunction([]() { DWORD imageBase = (DWORD)GetModuleHandleA(0); @@ -222,6 +721,26 @@ static InitFunction initFunction([]() injector::MakeRET(0x5F21B0, 4); } + if (ToBool(config["General"]["Professional Edition Enable"])) + { + injector::MakeNOP(imageBase + 0x1E7AB, 6); + injector::MakeNOP(imageBase + 0x1E7DC, 6); + injector::MakeNOP(imageBase + 0x1E7A5, 6); + injector::MakeNOP(imageBase + 0x1E82B, 6); + injector::MakeNOP(imageBase + 0x1E79F, 6); + injector::MakeNOP(imageBase + 0x1E858, 6); + injector::MakeNOP(imageBase + 0x1E799, 6); + injector::MakeNOP(imageBase + 0x1E880, 6); + injector::MakeNOP(imageBase + 0x27447, 3); + + if (ToBool(config["General"]["Professional Edition Hold Gear"])) + { + injector::MakeNOP(imageBase + 0x8ADFF, 10); + } + + CreateThread(NULL, 0, BG4RunningLoop, NULL, 0, NULL); + } + iatHook("kernel32.dll", ReadFileWrapTx2, "ReadFile"); iatHook("kernel32.dll", WriteFileWrapTx2, "WriteFile"); iatHook("kernel32.dll", GetFileAttributesAWrapTx2, "GetFileAttributesA");