From c2d97a8923c8e0b8c71d7fa087a190106ce1a66c Mon Sep 17 00:00:00 2001 From: Mike Waye Date: Sun, 7 Apr 2024 10:59:56 +0100 Subject: [PATCH 1/6] FnF Added --- DllMain.cpp | 25 ++++++++++++ Game Files/FnF.cpp | 80 +++++++++++++++++++++++++++++++++++++ Game Files/FnF.h | 20 ++++++++++ Game Files/FnFDrift.cpp | 79 ++++++++++++++++++++++++++++++++++++ Game Files/FnFDrift.h | 21 ++++++++++ Game Files/FnFSuperCars.cpp | 72 +++++++++++++++++++++++++++++++++ Game Files/FnFSuperCars.h | 22 ++++++++++ 7 files changed, 319 insertions(+) create mode 100644 Game Files/FnF.cpp create mode 100644 Game Files/FnF.h create mode 100644 Game Files/FnFDrift.cpp create mode 100644 Game Files/FnFDrift.h create mode 100644 Game Files/FnFSuperCars.cpp create mode 100644 Game Files/FnFSuperCars.h diff --git a/DllMain.cpp b/DllMain.cpp index b3196aa..f3e2a6c 100644 --- a/DllMain.cpp +++ b/DllMain.cpp @@ -37,12 +37,16 @@ along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. #include "Game Files/BG4JP.h" #include "Game Files/ChaseHQ2.h" #include "Game Files/CrazyTaxi.h" +#include "Game Files/CruisnBlast.h" #include "Game Files/D1GP.h" #include "Game Files/Daytona3.h" #include "Game Files/Daytona3NSE.h" #include "Game Files/DeadHeat.h" #include "Game Files/DeadHeatRiders.h" #include "Game Files/DirtyDrivin.h" +#include "Game Files/FnF.h" +#include "Game Files/FnFDrift.h" +#include "Game Files/FnFSuperCars.h" #include "Game Files/FordRacing.h" #include "Game Files/FordRacingOther.h" #include "Game Files/GaelcoTuningRace.h" @@ -68,6 +72,7 @@ along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. #include "Game Files/MAMESupermodel.h" #include "Game Files/OutRun2Fake.h" #include "Game Files/OutRun2Real.h" +#include "Game Files/SegaRaceTV.h" #include "Game Files/SegaRacingClassic.h" #include "Game Files/SegaRally3.h" #include "Game Files/SegaRally3Other.h" @@ -1068,6 +1073,11 @@ const int MARIO_KART_GPDX_118_CUSTOM = 72; const int SEGA_SHOWDOWN = 73; const int SPRING_EFFECT = 74; const int ARCTIC_THUNDER = 75; +const int CRUISN_BLAST = 76; +const int FNF = 77; +const int FNF_DRIFT = 78; +const int FNF_SUPERCARS = 79; +const int SEGA_RACE_TV = 80; HINSTANCE Get_hInstance() { @@ -2595,6 +2605,21 @@ DWORD WINAPI FFBLoop(LPVOID lpParam) case ARCTIC_THUNDER: game = new ArcticThunder; break; + case CRUISN_BLAST: + game = new CruisnBlast; + break; + case FNF: + game = new FnF; + break; + case FNF_DRIFT: + game = new FnFDrift; + break; + case FNF_SUPERCARS: + game = new FnFSuperCars; + break; + case SEGA_RACE_TV: + game = new SegaRaceTV; + break; case TEST_GAME_CONST: case TEST_GAME_FRICTION: case TEST_GAME_SINE: diff --git a/Game Files/FnF.cpp b/Game Files/FnF.cpp new file mode 100644 index 0000000..4f9b7f8 --- /dev/null +++ b/Game Files/FnF.cpp @@ -0,0 +1,80 @@ + +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#include +#include "FnF.h" + +static bool init; +static EffectTriggers* myTriggers; +static EffectConstants* myConstants; +static Helpers* myHelpers; +extern int EnableDamper; +extern int DamperStrength; + +static int(__cdecl* FnFSendToLptOrig)(uint16_t addr, uint8_t FFB); +static int __cdecl FnFSendToLpt(uint16_t addr, uint8_t FFB) +{ + if (addr == 0x378) + { + bool isLeft = FFB < 0x80; + float percentForce; + if (isLeft) { + + percentForce = static_cast(FFB) / 0x7F; + myTriggers->Rumble(0, percentForce, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_RIGHT, percentForce); + } + else { + + percentForce = static_cast(FFB - 0x80) / 0x7F; + myTriggers->Rumble(0, percentForce, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_LEFT, percentForce); + } + } + + return 0; +} + +static void(__cdecl* FnFIgnoreLPTOrig)(); +static void __cdecl FnFignoreLPT() { + return; +} + + +void FnF::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) { + if (!init) + { + //enable IO calls + myHelpers->WriteIntPtr(0x05b2ed4, 1, false); + + MH_Initialize(); + MH_CreateHook((LPVOID)0x046da10, FnFSendToLpt, (LPVOID*)&FnFSendToLptOrig); + //null all the other functions IO functions + MH_CreateHook((LPVOID)0x046dd60, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x046dda0, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x046dec0, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x046df70, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + + MH_EnableHook(MH_ALL_HOOKS); + + init = true; + } + + if (EnableDamper) + triggers->Damper(DamperStrength / 100.0); + + myTriggers = triggers; + myConstants = constants; + myHelpers = helpers; +} \ No newline at end of file diff --git a/Game Files/FnF.h b/Game Files/FnF.h new file mode 100644 index 0000000..db4efdf --- /dev/null +++ b/Game Files/FnF.h @@ -0,0 +1,20 @@ +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#pragma once +#include "../Common Files/Game.h" +class FnF : public Game { + +public: + void FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers); +}; \ No newline at end of file diff --git a/Game Files/FnFDrift.cpp b/Game Files/FnFDrift.cpp new file mode 100644 index 0000000..a27c931 --- /dev/null +++ b/Game Files/FnFDrift.cpp @@ -0,0 +1,79 @@ + +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#include +#include "FnFDrift.h" + + +static bool init; +static EffectTriggers* myTriggers; +static EffectConstants* myConstants; +static Helpers* myHelpers; +extern int EnableDamper; +extern int DamperStrength; + +static int(__cdecl* FnFSendToLptOrig)(uint16_t addr, uint8_t FFB); +static int __cdecl FnFSendToLpt(uint16_t addr, uint8_t FFB) +{ + if (addr == 0x378) + { + bool isLeft = FFB < 0x80; + float percentForce; + if (isLeft) { + + percentForce = static_cast(FFB) / 0x7F; + myTriggers->Rumble(0, percentForce, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_RIGHT, percentForce); + } + else { + + percentForce = static_cast(FFB - 0x80) / 0x7F; + myTriggers->Rumble(0, percentForce, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_LEFT, percentForce); + } + } + + return 0; + +} + + +static void(__cdecl* FnFIgnoreLPTOrig)(); +static void __cdecl FnFignoreLPT() { + return; +} + +void FnFDrift::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) { + if (!init) + { + //enable IO calls + myHelpers->WriteIntPtr(0x05a3ca4, 1, false); + MH_Initialize(); + MH_CreateHook((LPVOID)0x048a410, FnFSendToLpt, (LPVOID*)&FnFSendToLptOrig); + + MH_CreateHook((LPVOID)0x048a760, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x048a7b0, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x048a8f0, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x048aa20, FnFignoreLPT, (LPVOID*)&FnFIgnoreLPTOrig); + MH_EnableHook(MH_ALL_HOOKS); + init = true; + } + + if (EnableDamper) + triggers->Damper(DamperStrength / 100.0); + + myTriggers = triggers; + myConstants = constants; + myHelpers = helpers; +} \ No newline at end of file diff --git a/Game Files/FnFDrift.h b/Game Files/FnFDrift.h new file mode 100644 index 0000000..545a8de --- /dev/null +++ b/Game Files/FnFDrift.h @@ -0,0 +1,21 @@ +#pragma once +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#pragma once +#include "../Common Files/Game.h" +class FnFDrift : public Game { + +public: + void FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers); +}; \ No newline at end of file diff --git a/Game Files/FnFSuperCars.cpp b/Game Files/FnFSuperCars.cpp new file mode 100644 index 0000000..da28577 --- /dev/null +++ b/Game Files/FnFSuperCars.cpp @@ -0,0 +1,72 @@ + +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#include "FnFSuperCars.h" + +static bool init; +static EffectTriggers* myTriggers; +static EffectConstants* myConstants; +static Helpers* myHelpers; +extern int EnableDamper; +extern int DamperStrength; + +static void(__cdecl* FUN_00402cf0Orig)(float param_1); +static void __cdecl FUN_00402cf0(float param_1) { + + + if (param_1 >= 0) { + + myTriggers->Rumble(0, param_1, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_RIGHT, param_1 ); + } + if (param_1 <= 0) { + myTriggers->Rumble(0, param_1 * -1, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_LEFT, param_1 * -1); + } + return; +} + + + +static void(__cdecl* FnFSCIgnoreLPTOrig)(); +static void __cdecl FnFSCignoreLPT() { + return ; +} + +void FnFSuperCars::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) { + if (!init) + { + OutputDebugStringA("FnFSuperCars::FFBLoop"); + + + MH_Initialize(); + MH_CreateHook((LPVOID)0x0402cf0, FUN_00402cf0, (LPVOID*)&FUN_00402cf0Orig); + + //remove unwanted instances + MH_CreateHook((LPVOID)0x0402ca0, FnFSCignoreLPT, (LPVOID*)&FnFSCIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x0402c50, FnFSCignoreLPT, (LPVOID*)&FnFSCIgnoreLPTOrig); + MH_CreateHook((LPVOID)0x0402bc0, FnFSCignoreLPT, (LPVOID*)&FnFSCIgnoreLPTOrig); + MH_EnableHook(MH_ALL_HOOKS); + + init = true; + } + + if (EnableDamper) + triggers->Damper(DamperStrength / 100.0); + + myTriggers = triggers; + myConstants = constants; + myHelpers = helpers; + +} \ No newline at end of file diff --git a/Game Files/FnFSuperCars.h b/Game Files/FnFSuperCars.h new file mode 100644 index 0000000..2278915 --- /dev/null +++ b/Game Files/FnFSuperCars.h @@ -0,0 +1,22 @@ +#pragma once +#pragma once +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#pragma once +#include "../Common Files/Game.h" +class FnFSuperCars : public Game { + +public: + void FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers); +}; \ No newline at end of file From 93f1dab9db08da3aaf2e498c9844185434fefd54 Mon Sep 17 00:00:00 2001 From: Mike Waye Date: Sun, 7 Apr 2024 11:02:02 +0100 Subject: [PATCH 2/6] Crusin + Sega RAce TV WIP --- Game Files/CruisnBlast.cpp | 242 +++++++++++++++++++++++++++++++++++++ Game Files/CruisnBlast.h | 22 ++++ Game Files/SegaRaceTV.cpp | 63 ++++++++++ Game Files/SegaRaceTV.h | 20 +++ 4 files changed, 347 insertions(+) create mode 100644 Game Files/CruisnBlast.cpp create mode 100644 Game Files/CruisnBlast.h create mode 100644 Game Files/SegaRaceTV.cpp create mode 100644 Game Files/SegaRaceTV.h diff --git a/Game Files/CruisnBlast.cpp b/Game Files/CruisnBlast.cpp new file mode 100644 index 0000000..df14575 --- /dev/null +++ b/Game Files/CruisnBlast.cpp @@ -0,0 +1,242 @@ +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#include +#include "CruisnBlast.h" +#include s +#include +static bool init; + +static EffectTriggers* myTriggers; +static EffectConstants* myConstants; +static Helpers* myHelpers; +extern int EnableDamper; +extern int DamperStrength; + +static float lastFF; +static int(__fastcall* Wheel_SetHookOrig)(DWORD thisPtr, DWORD *edx); +static int __fastcall Wheel_SetHook(DWORD thisPtr, DWORD *edx) +{ + //OutputDebugStringA("Wheel_SetHook"); + + float stackValue; + __asm { + mov eax, [esp + 4] + mov stackValue, eax + } + + //std::stringstream ss; + //ss << "Wheel_SetHook: " << stackValue; + //OutputDebugStringA(ss.str().c_str()); + + std::stringstream ss; + ss << "Wheel_SetHook: " << thisPtr; + OutputDebugStringA(ss.str().c_str()); + + //float ff = myHelpers->ReadFloat32(*edx, true); + //output the ff value + //std::stringstream ss2; + //ss2 << ff; + //OutputDebugStringA(ss2.str().c_str()); + + //output thisPtr + //std::stringstream ss2; + //ss2 << "thisPtr: " << thisPtr; + //OutputDebugStringA(ss2.str().c_str()); + + //output edx + //std::stringstream ss3; + //ss3 << "edx: " << edx; + //OutputDebugStringA(ss3.str().c_str()); + + + return Wheel_SetHookOrig(thisPtr, edx); +} + +static int(__fastcall* GameWheel_initOrig)(); +static int __fastcall GameWheel_init() +{ + //OutputDebugStringA("GameWheel_init"); + return GameWheel_initOrig(); +} + +static int(__fastcall* Wheel_InitOrig)(); +static int __fastcall Wheel_Init() +{ + OutputDebugStringA("Wheel_Init"); + myHelpers->WriteByte(0x8bab744, 1, false); + return 1; +} + +static int(__fastcall* Game_diaginitOrig)(); +static int __fastcall Game_diaginit() +{ + OutputDebugStringA("Game_diaginit"); + return Game_diaginitOrig(); +} + +static int(__stdcall* Game_adjInitORig)(); +static int __stdcall Game_adjInit() +{ + OutputDebugStringA("Game_adjInit"); + + //set wheel command line i think + myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); + //write assembly here to jmp to a function + _asm { + mov eax, 0x8192960 + jmp eax + } + + + return 1; +} + +static int(__fastcall* DefaultCommandLineArgsOrig)(); +static int __fastcall DefaultCommandLineArgs() +{ + OutputDebugStringA("DefaultCommandLineArgs"); + myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); + return DefaultCommandLineArgsOrig(); +} +static int(__fastcall* PlayerDataTblInitOrig)(); +static int __fastcall PlayerDataTblInit() +{ + OutputDebugStringA("PlayerDataTblInit"); + return PlayerDataTblInitOrig(); +} + +static int(__fastcall* GameInitDongleOrig)(); +static int __fastcall GameInitDongle() +{ + OutputDebugStringA("GameInitDongle"); + myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); + return GameInitDongleOrig(); +} + +//void FUN_08136610(void) +static int(__fastcall* FUN_08136610Orig)(); +static int __fastcall FUN_08136610() +{ + OutputDebugStringA("FUN_08136610"); + myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); + return FUN_08136610Orig(); +} +void CruisnBlast::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) { + if (!init) + { + + + DWORD ImageBase = (DWORD)GetModuleHandleA(0); + + + myHelpers->WriteNop(0x8151a02, 1, false); + myHelpers->WriteNop(0x8151a02, 1, false); + myHelpers->WriteNop(0x8151a0d, 1, false); + myHelpers->WriteNop(0x8151a15, 1, false); + myHelpers->WriteNop(0x8151a1d, 1, false); + myHelpers->WriteNop(0x8151a22, 1, false); + myHelpers->WriteNop(0x8151a2a, 1, false); + myHelpers->WriteNop(0x8151a32, 1, false); + myHelpers->WriteNop(0x8151a3a, 1, false); + + myHelpers->WriteNop(0x8151aa7, 1, false); + myHelpers->WriteNop(0x8151ab0, 1, false); + myHelpers->WriteNop(0x8151ab6, 1, false); + myHelpers->WriteNop(0x8151abc, 1, false); + + myHelpers->WriteNop(0x8151ad7, 1, false); + myHelpers->WriteNop(0x8151ae0, 1, false); + myHelpers->WriteNop(0x8151ae6, 1, false); + myHelpers->WriteNop(0x8151aec, 1, false); + + myHelpers->WriteNop(0x8151b07, 1, false); + myHelpers->WriteNop(0x8151b12, 1, false); + myHelpers->WriteNop(0x8151b1a, 1, false); + myHelpers->WriteNop(0x8151b22, 1, false); + myHelpers->WriteNop(0x8151b2a, 1, false); + myHelpers->WriteNop(0x8151b32, 1, false); + myHelpers->WriteNop(0x8151b3a, 1, false); + myHelpers->WriteNop(0x8151b42, 1, false); + + myHelpers->WriteNop(0x8151b87, 1, false); + myHelpers->WriteNop(0x8151b90, 1, false); + myHelpers->WriteNop(0x8151b96, 1, false); + myHelpers->WriteNop(0x8151b9c, 1, false); + + myHelpers->WriteNop(0x8151c1a, 1, false); + myHelpers->WriteNop(0x8151c25, 1, false); + myHelpers->WriteNop(0x8151c2d, 1, false); + myHelpers->WriteNop(0x8151c35, 1, false); + myHelpers->WriteNop(0x8151c3d, 1, false); + myHelpers->WriteNop(0x8151c45, 1, false); + myHelpers->WriteNop(0x8151c4d, 1, false); + myHelpers->WriteNop(0x8151c55, 1, false); + myHelpers->WriteNop(0x8151c5d, 1, false); + myHelpers->WriteNop(0x8151c65, 1, false); + myHelpers->WriteNop(0x8151c6d, 1, false); + myHelpers->WriteNop(0x8151c75, 1, false); + + myHelpers->WriteNop(0x8151c97, 1, false); + myHelpers->WriteNop(0x8151ca0, 1, false); + myHelpers->WriteNop(0x8151ca6, 1, false); + myHelpers->WriteNop(0x8151cac, 1, false); + + myHelpers->WriteNop(0x8151cca, 1, false); + myHelpers->WriteNop(0x8151cd5, 1, false); + myHelpers->WriteNop(0x8151cdd, 1, false); + myHelpers->WriteNop(0x8151ce5, 1, false); + myHelpers->WriteNop(0x8151ced, 1, false); + myHelpers->WriteNop(0x8151cf5, 1, false); + myHelpers->WriteNop(0x8151cfd, 1, false); + myHelpers->WriteNop(0x8151d05, 1, false); + + myHelpers->WriteNop(0x8151d25, 1, false); + + myHelpers->WriteNop(0x8151d4b, 1, false); + + myHelpers->WriteNop(0x8151d6f, 1, false); + + //set cab type + myHelpers->WriteByte(0xa0a7808, 4, false); + //enable wheel found + //myHelpers->WriteByte(0x8bab744, 1, false); + myHelpers->WriteByte(0x8bab748, 1, false); + + //bypass random command line + myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); + myHelpers->WriteNop(0x81ae870, 1, false); + + OutputDebugStringA("CruisnBlast FFB Loop"); + init = true; + + + MH_Initialize(); + MH_CreateHook((LPVOID)(0x8151b50), Wheel_SetHook, (LPVOID*)&Wheel_SetHookOrig); + MH_CreateHook((LPVOID)(0x81519d0), Wheel_Init, (LPVOID*)&Wheel_InitOrig); + MH_CreateHook((LPVOID)(0x8192960), GameWheel_init, (LPVOID*)&GameWheel_initOrig); + MH_CreateHook((LPVOID)(0x8196850), Game_diaginit, (LPVOID*)&Game_diaginitOrig); + MH_CreateHook((LPVOID)(0x8191e40), Game_adjInit, (LPVOID*)&Game_adjInitORig); + MH_CreateHook((LPVOID)(0x81ae4c0), DefaultCommandLineArgs, (LPVOID*)&DefaultCommandLineArgsOrig); + MH_CreateHook((LPVOID)(0x81d8240), PlayerDataTblInit, (LPVOID*)&PlayerDataTblInitOrig); + MH_CreateHook((LPVOID)(0x81af700), GameInitDongle, (LPVOID*)&GameInitDongleOrig); + MH_CreateHook((LPVOID)(0x8136610), FUN_08136610, (LPVOID*)&FUN_08136610Orig); + //MH_CreateHook((LPVOID)(0x8151b87), Wheel_SetOutHook, (LPVOID*)&Wheel_SetOutHookOrig); + + + + MH_EnableHook(MH_ALL_HOOKS); + } + + +} \ No newline at end of file diff --git a/Game Files/CruisnBlast.h b/Game Files/CruisnBlast.h new file mode 100644 index 0000000..5bb298e --- /dev/null +++ b/Game Files/CruisnBlast.h @@ -0,0 +1,22 @@ +#pragma once +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#pragma once +#include "../Common Files/TeknoParrotGame.h" + +class CruisnBlast : public TeknoParrotGame { +public: + CruisnBlast() : TeknoParrotGame() { } + void FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers); +}; \ No newline at end of file diff --git a/Game Files/SegaRaceTV.cpp b/Game Files/SegaRaceTV.cpp new file mode 100644 index 0000000..a2a3d00 --- /dev/null +++ b/Game Files/SegaRaceTV.cpp @@ -0,0 +1,63 @@ + +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#include +#include "SegaRaceTV.h" +#include + +static bool init; +extern int EnableDamper; +extern int DamperStrength; +extern int EnableForceSpringEffect; +extern int ForceSpringStrength; + +void SegaRaceTV::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) { + if (!init) + { + OutputDebugStringA("SegaRaceTV::FFBLoop"); + //enable IO calls + helpers->WriteIntPtr(0x8b3fe90, 0x1, true); + init = true; + } + + int ff = helpers->ReadInt32(0x8b44210, false); + + if (EnableDamper) + triggers->Damper(DamperStrength / 100.0); + if (EnableForceSpringEffect) + triggers->Springi(ForceSpringStrength / 100.0); + + if (ff > 0 && ff < 128) + { + double percentForce = ((128.0 - ff) / 127.0); + + std::ostringstream ss; + ss << "LEFT: " << percentForce << " FF: " << ff; + OutputDebugStringA(ss.str().c_str()); + + + + triggers->Rumble(0, percentForce, 100.0); + triggers->Constant(constants->DIRECTION_FROM_LEFT, percentForce); + } + else if (ff > 128) + { + double percentForce = ((ff - 128.0) / 127.0); + std::ostringstream ss; + ss << "RIGHT: " << percentForce << " FF: " << ff; + OutputDebugStringA(ss.str().c_str()); + triggers->Rumble(percentForce, 0, 100.0); + triggers->Constant(constants->DIRECTION_FROM_RIGHT, percentForce); + } +} \ No newline at end of file diff --git a/Game Files/SegaRaceTV.h b/Game Files/SegaRaceTV.h new file mode 100644 index 0000000..1bb39dd --- /dev/null +++ b/Game Files/SegaRaceTV.h @@ -0,0 +1,20 @@ +/*This file is part of FFB Arcade Plugin. +FFB Arcade Plugin is free software : you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +FFB Arcade Plugin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. +*/ + +#pragma once +#include "../Common Files/Game.h" +class SegaRaceTV : public Game { + +public: + void FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers); +}; \ No newline at end of file From 8fde9052d7ea82aa8ec0cfe8afb8867dae6799bc Mon Sep 17 00:00:00 2001 From: Mike Waye Date: Sun, 7 Apr 2024 11:09:49 +0100 Subject: [PATCH 3/6] AutoSetup for FNF --- AutoSetup.cmd | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/AutoSetup.cmd b/AutoSetup.cmd index 172d6e5..cdc4e54 100644 --- a/AutoSetup.cmd +++ b/AutoSetup.cmd @@ -51,6 +51,9 @@ cd.. cd Battle Gear 4 Tuned rename dinput8.dll d3d9.dll cd.. +cd Cruisn Blast +rename dinput8.dll xinput1_3.dll +cd.. cd Crazy Taxi Steam rename dinput8.dll xinput1_3.dll cd.. @@ -81,6 +84,15 @@ cd.. cd Dirty Drivin' rename dinput8.dll d3d9.dll cd.. +cd FnF +rename dinput8.dll dinput8.dll +cd.. +cd FnFDrift +rename dinput8.dll dinput8.dll +cd.. +cd FnFSuperCars +rename dinput8.dll dinput8.dll +cd.. cd H2Overdrive rename dinput8.dll d3d9.dll cd.. From df5692b1cba9da5af3f7a11142c144e880a0e214 Mon Sep 17 00:00:00 2001 From: mpzmail1 Date: Wed, 17 Apr 2024 21:33:05 +0100 Subject: [PATCH 4/6] Added Cruisn --- Dinput8Wrapper.vcxproj | 10 ++ Dinput8Wrapper.vcxproj.filters | 20 +++ Game Files/CruisnBlast.cpp | 237 +++++++-------------------------- Game Files/CruisnBlast.h | 5 +- 4 files changed, 78 insertions(+), 194 deletions(-) diff --git a/Dinput8Wrapper.vcxproj b/Dinput8Wrapper.vcxproj index d4964c7..9c883ec 100644 --- a/Dinput8Wrapper.vcxproj +++ b/Dinput8Wrapper.vcxproj @@ -27,11 +27,15 @@ + + + + @@ -64,6 +68,7 @@ + @@ -87,6 +92,7 @@ + @@ -97,6 +103,9 @@ + + + @@ -138,6 +147,7 @@ + diff --git a/Dinput8Wrapper.vcxproj.filters b/Dinput8Wrapper.vcxproj.filters index 36df76a..937b781 100644 --- a/Dinput8Wrapper.vcxproj.filters +++ b/Dinput8Wrapper.vcxproj.filters @@ -160,6 +160,11 @@ + + + + + @@ -403,6 +408,21 @@ Common Header Files + + Common Header Files + + + Common Header Files + + + Common Header Files + + + Common Header Files + + + Common Header Files + diff --git a/Game Files/CruisnBlast.cpp b/Game Files/CruisnBlast.cpp index df14575..da4e978 100644 --- a/Game Files/CruisnBlast.cpp +++ b/Game Files/CruisnBlast.cpp @@ -11,9 +11,7 @@ You should have received a copy of the GNU General Public License along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. */ -#include #include "CruisnBlast.h" -#include s #include static bool init; @@ -23,220 +21,77 @@ static Helpers* myHelpers; extern int EnableDamper; extern int DamperStrength; -static float lastFF; -static int(__fastcall* Wheel_SetHookOrig)(DWORD thisPtr, DWORD *edx); -static int __fastcall Wheel_SetHook(DWORD thisPtr, DWORD *edx) -{ - //OutputDebugStringA("Wheel_SetHook"); +static float lastFF = 0; - float stackValue; - __asm { - mov eax, [esp + 4] - mov stackValue, eax +static int(__cdecl* Wheel_SetHookOrig)(float param_1); +static int __cdecl Wheel_SetHook(float param_1) +{ + float puVar1 = myHelpers->ReadFloat32(0x8babbac, false); //menus ffb?! CHECKED COOL + float puVar2 = myHelpers->ReadByte(0x8babba8, false); //in game ffb?! //CHECKED seems to just go 0 when off the road + //int puVar3 = myHelpers->ReadFloat32(0x8babbb0, false); //ffb effects FLOAT?? + //int puVar4 = myHelpers->ReadFloat32(0x8babbb4, false); + //int puVar5 = myHelpers->ReadFloat32(0x8babbbc, false); //ffb effects + //int puVar6 = myHelpers->ReadFloat32(0x8babbb8, false); //ffb effects are running (1 at the start i think) + int puVar7 = myHelpers->ReadInt32(0x8babbc0, false); //0 menus, 1 game + + if (puVar7 == 1) + { + //in game - turn on wheel effects + myHelpers->WriteByte(0x9c28504, 1, false); + lastFF = param_1; } - - //std::stringstream ss; - //ss << "Wheel_SetHook: " << stackValue; - //OutputDebugStringA(ss.str().c_str()); - - std::stringstream ss; - ss << "Wheel_SetHook: " << thisPtr; - OutputDebugStringA(ss.str().c_str()); - - //float ff = myHelpers->ReadFloat32(*edx, true); - //output the ff value - //std::stringstream ss2; - //ss2 << ff; - //OutputDebugStringA(ss2.str().c_str()); - - //output thisPtr - //std::stringstream ss2; - //ss2 << "thisPtr: " << thisPtr; - //OutputDebugStringA(ss2.str().c_str()); - - //output edx - //std::stringstream ss3; - //ss3 << "edx: " << edx; - //OutputDebugStringA(ss3.str().c_str()); - - - return Wheel_SetHookOrig(thisPtr, edx); -} - -static int(__fastcall* GameWheel_initOrig)(); -static int __fastcall GameWheel_init() -{ - //OutputDebugStringA("GameWheel_init"); - return GameWheel_initOrig(); -} - -static int(__fastcall* Wheel_InitOrig)(); -static int __fastcall Wheel_Init() -{ - OutputDebugStringA("Wheel_Init"); - myHelpers->WriteByte(0x8bab744, 1, false); - return 1; -} - -static int(__fastcall* Game_diaginitOrig)(); -static int __fastcall Game_diaginit() -{ - OutputDebugStringA("Game_diaginit"); - return Game_diaginitOrig(); -} - -static int(__stdcall* Game_adjInitORig)(); -static int __stdcall Game_adjInit() -{ - OutputDebugStringA("Game_adjInit"); - - //set wheel command line i think - myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); - //write assembly here to jmp to a function - _asm { - mov eax, 0x8192960 - jmp eax + else + { + //not in game turn off wheel effects + myHelpers->WriteByte(0x9c28504, 0, false); + lastFF = puVar1; } - - - return 1; + if (lastFF >= 0) { + myTriggers->Rumble(0, lastFF, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_RIGHT, lastFF); + } + if (lastFF <= 0) { + myTriggers->Rumble(0, lastFF * -1, 100.0); + myTriggers->Constant(myConstants->DIRECTION_FROM_LEFT, lastFF * -1); + } + return 0; } -static int(__fastcall* DefaultCommandLineArgsOrig)(); -static int __fastcall DefaultCommandLineArgs() -{ - OutputDebugStringA("DefaultCommandLineArgs"); - myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); - return DefaultCommandLineArgsOrig(); -} -static int(__fastcall* PlayerDataTblInitOrig)(); -static int __fastcall PlayerDataTblInit() -{ - OutputDebugStringA("PlayerDataTblInit"); - return PlayerDataTblInitOrig(); -} -static int(__fastcall* GameInitDongleOrig)(); -static int __fastcall GameInitDongle() -{ - OutputDebugStringA("GameInitDongle"); - myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); - return GameInitDongleOrig(); -} -//void FUN_08136610(void) -static int(__fastcall* FUN_08136610Orig)(); -static int __fastcall FUN_08136610() -{ - OutputDebugStringA("FUN_08136610"); - myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); - return FUN_08136610Orig(); -} void CruisnBlast::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) { if (!init) { - - DWORD ImageBase = (DWORD)GetModuleHandleA(0); + if (EnableDamper) + triggers->Damper(DamperStrength / 100.0); - myHelpers->WriteNop(0x8151a02, 1, false); - myHelpers->WriteNop(0x8151a02, 1, false); - myHelpers->WriteNop(0x8151a0d, 1, false); - myHelpers->WriteNop(0x8151a15, 1, false); - myHelpers->WriteNop(0x8151a1d, 1, false); - myHelpers->WriteNop(0x8151a22, 1, false); - myHelpers->WriteNop(0x8151a2a, 1, false); - myHelpers->WriteNop(0x8151a32, 1, false); - myHelpers->WriteNop(0x8151a3a, 1, false); - - myHelpers->WriteNop(0x8151aa7, 1, false); - myHelpers->WriteNop(0x8151ab0, 1, false); - myHelpers->WriteNop(0x8151ab6, 1, false); - myHelpers->WriteNop(0x8151abc, 1, false); - - myHelpers->WriteNop(0x8151ad7, 1, false); - myHelpers->WriteNop(0x8151ae0, 1, false); - myHelpers->WriteNop(0x8151ae6, 1, false); - myHelpers->WriteNop(0x8151aec, 1, false); - - myHelpers->WriteNop(0x8151b07, 1, false); - myHelpers->WriteNop(0x8151b12, 1, false); - myHelpers->WriteNop(0x8151b1a, 1, false); - myHelpers->WriteNop(0x8151b22, 1, false); - myHelpers->WriteNop(0x8151b2a, 1, false); - myHelpers->WriteNop(0x8151b32, 1, false); - myHelpers->WriteNop(0x8151b3a, 1, false); - myHelpers->WriteNop(0x8151b42, 1, false); - - myHelpers->WriteNop(0x8151b87, 1, false); - myHelpers->WriteNop(0x8151b90, 1, false); - myHelpers->WriteNop(0x8151b96, 1, false); - myHelpers->WriteNop(0x8151b9c, 1, false); - - myHelpers->WriteNop(0x8151c1a, 1, false); - myHelpers->WriteNop(0x8151c25, 1, false); - myHelpers->WriteNop(0x8151c2d, 1, false); - myHelpers->WriteNop(0x8151c35, 1, false); - myHelpers->WriteNop(0x8151c3d, 1, false); - myHelpers->WriteNop(0x8151c45, 1, false); - myHelpers->WriteNop(0x8151c4d, 1, false); - myHelpers->WriteNop(0x8151c55, 1, false); - myHelpers->WriteNop(0x8151c5d, 1, false); - myHelpers->WriteNop(0x8151c65, 1, false); - myHelpers->WriteNop(0x8151c6d, 1, false); - myHelpers->WriteNop(0x8151c75, 1, false); - - myHelpers->WriteNop(0x8151c97, 1, false); - myHelpers->WriteNop(0x8151ca0, 1, false); - myHelpers->WriteNop(0x8151ca6, 1, false); - myHelpers->WriteNop(0x8151cac, 1, false); - - myHelpers->WriteNop(0x8151cca, 1, false); - myHelpers->WriteNop(0x8151cd5, 1, false); - myHelpers->WriteNop(0x8151cdd, 1, false); - myHelpers->WriteNop(0x8151ce5, 1, false); - myHelpers->WriteNop(0x8151ced, 1, false); - myHelpers->WriteNop(0x8151cf5, 1, false); - myHelpers->WriteNop(0x8151cfd, 1, false); - myHelpers->WriteNop(0x8151d05, 1, false); - - myHelpers->WriteNop(0x8151d25, 1, false); - - myHelpers->WriteNop(0x8151d4b, 1, false); - - myHelpers->WriteNop(0x8151d6f, 1, false); + myHelpers = helpers; + myTriggers = triggers; + myConstants = constants; //set cab type myHelpers->WriteByte(0xa0a7808, 4, false); //enable wheel found //myHelpers->WriteByte(0x8bab744, 1, false); - myHelpers->WriteByte(0x8bab748, 1, false); - - //bypass random command line - myHelpers->WriteIntPtr(0x8bdd9e8, 1, false); - myHelpers->WriteNop(0x81ae870, 1, false); - - OutputDebugStringA("CruisnBlast FFB Loop"); - init = true; + OutputDebugStringA("CruisnBlast FFB Loop"); MH_Initialize(); MH_CreateHook((LPVOID)(0x8151b50), Wheel_SetHook, (LPVOID*)&Wheel_SetHookOrig); - MH_CreateHook((LPVOID)(0x81519d0), Wheel_Init, (LPVOID*)&Wheel_InitOrig); - MH_CreateHook((LPVOID)(0x8192960), GameWheel_init, (LPVOID*)&GameWheel_initOrig); - MH_CreateHook((LPVOID)(0x8196850), Game_diaginit, (LPVOID*)&Game_diaginitOrig); - MH_CreateHook((LPVOID)(0x8191e40), Game_adjInit, (LPVOID*)&Game_adjInitORig); - MH_CreateHook((LPVOID)(0x81ae4c0), DefaultCommandLineArgs, (LPVOID*)&DefaultCommandLineArgsOrig); - MH_CreateHook((LPVOID)(0x81d8240), PlayerDataTblInit, (LPVOID*)&PlayerDataTblInitOrig); - MH_CreateHook((LPVOID)(0x81af700), GameInitDongle, (LPVOID*)&GameInitDongleOrig); - MH_CreateHook((LPVOID)(0x8136610), FUN_08136610, (LPVOID*)&FUN_08136610Orig); - //MH_CreateHook((LPVOID)(0x8151b87), Wheel_SetOutHook, (LPVOID*)&Wheel_SetOutHookOrig); - - + //remove wheel check for WHEEL_SET function + myHelpers->WriteNop(0x8151b61, 2, false); + //remove outs for WHEEL_SET function just incase we get there + myHelpers->WriteNop(0x8151b90, 1, false); + myHelpers->WriteNop(0x8151b96, 1, false); + myHelpers->WriteNop(0x8151b9c, 1, false); + myHelpers->WriteNop(0x8151b87, 1, false); MH_EnableHook(MH_ALL_HOOKS); + init = true; } + } \ No newline at end of file diff --git a/Game Files/CruisnBlast.h b/Game Files/CruisnBlast.h index 5bb298e..3fe8c96 100644 --- a/Game Files/CruisnBlast.h +++ b/Game Files/CruisnBlast.h @@ -15,8 +15,7 @@ along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>. #pragma once #include "../Common Files/TeknoParrotGame.h" -class CruisnBlast : public TeknoParrotGame { +class CruisnBlast : public Game { public: - CruisnBlast() : TeknoParrotGame() { } void FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers); -}; \ No newline at end of file +}; From 2aa65fe9ee1e915aaeb32db2116925a6bf905a1d Mon Sep 17 00:00:00 2001 From: Mike Waye Date: Wed, 17 Apr 2024 21:39:08 +0100 Subject: [PATCH 5/6] Crusin Changes --- AutoSetup.cmd | 2 +- Config/FFBPlugin.ini | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/AutoSetup.cmd b/AutoSetup.cmd index cdc4e54..5199e51 100644 --- a/AutoSetup.cmd +++ b/AutoSetup.cmd @@ -52,7 +52,7 @@ cd Battle Gear 4 Tuned rename dinput8.dll d3d9.dll cd.. cd Cruisn Blast -rename dinput8.dll xinput1_3.dll +rename dinput8.dll winmm.dll cd.. cd Crazy Taxi Steam rename dinput8.dll xinput1_3.dll diff --git a/Config/FFBPlugin.ini b/Config/FFBPlugin.ini index 1089f1f..d407635 100644 --- a/Config/FFBPlugin.ini +++ b/Config/FFBPlugin.ini @@ -348,6 +348,34 @@ DefaultCentering=15 EnableDamper=0 DamperStrength=100 +[FnF] +GameId=77 +FeedbackLength=500 +DefaultCentering=15 +EnableDamper=0 +DamperStrength=100 + +[FNFDrift] +GameId=78 +FeedbackLength=500 +DefaultCentering=15 +EnableDamper=0 +DamperStrength=100 + +[FNFSuperCars] +GameId=79 +FeedbackLength=500 +DefaultCentering=15 +EnableDamper=0 +DamperStrength=100 + +[Sega Race TV] +GameId=80 +FeedbackLength=500 +DefaultCentering=15 +EnableDamper=0 +DamperStrength=100 + [KODrive] GameId=39 PowerMode=0 @@ -788,6 +816,13 @@ PowerMode=1 EnableForceSpringEffect = 1; ForceSpringStrength = 100; +[Cruisn Blast] +GameId=76 +FeedbackLength=500 +DefaultCentering=15 +EnableDamper=0 +DamperStrength=100 + [WMMT5] GameId=9 DefaultCentering=0 From ca0bf28b42e0b3091eb86c0bc6ab411d2c377018 Mon Sep 17 00:00:00 2001 From: Mike Waye Date: Fri, 19 Apr 2024 18:58:05 +0100 Subject: [PATCH 6/6] Cruisn Blast improvements --- Game Files/CruisnBlast.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Game Files/CruisnBlast.cpp b/Game Files/CruisnBlast.cpp index da4e978..988b5c1 100644 --- a/Game Files/CruisnBlast.cpp +++ b/Game Files/CruisnBlast.cpp @@ -22,6 +22,7 @@ extern int EnableDamper; extern int DamperStrength; static float lastFF = 0; +static int currentScreen = 0; static int(__cdecl* Wheel_SetHookOrig)(float param_1); static int __cdecl Wheel_SetHook(float param_1) @@ -36,15 +37,31 @@ static int __cdecl Wheel_SetHook(float param_1) if (puVar7 == 1) { - //in game - turn on wheel effects - myHelpers->WriteByte(0x9c28504, 1, false); - lastFF = param_1; + if (currentScreen == 0) + { + //in game - turn on wheel effects + myHelpers->WriteByte(0x9c28504, 1, false); + currentScreen = 1; + lastFF = 0; + } + else + { + lastFF = param_1; + } } else { - //not in game turn off wheel effects - myHelpers->WriteByte(0x9c28504, 0, false); - lastFF = puVar1; + if (currentScreen == 1) + { + //not in game turn off wheel effects + myHelpers->WriteByte(0x9c28504, 0, false); + lastFF = 0; + currentScreen = 0; + } + else + { + lastFF = puVar1; + } } if (lastFF >= 0) { myTriggers->Rumble(0, lastFF, 100.0); @@ -58,7 +75,6 @@ static int __cdecl Wheel_SetHook(float param_1) } - void CruisnBlast::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) { if (!init) {