Open source GRID and GTI Club 3
Open source GRID and GTI Club 3
This commit is contained in:
parent
251ee88cdb
commit
f9f3e40e3a
147
OpenParrot/src/Functions/Games/Europa-R/GRID.cpp
Normal file
147
OpenParrot/src/Functions/Games/Europa-R/GRID.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include <StdInc.h>
|
||||
#include "Utility/InitFunction.h"
|
||||
#include "Functions/Global.h"
|
||||
#include "Utility\Hooking.Patterns.h"
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#ifndef _M_AMD64
|
||||
extern int* wheelSection;
|
||||
extern int* ffbOffset;
|
||||
extern int* ffbOffset2;
|
||||
extern int* ffbOffset3;
|
||||
extern int* ffbOffset4;
|
||||
|
||||
DWORD jOffset = 0x0081D64E;
|
||||
DWORD myPointer = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD *SomeAddress;
|
||||
float ControlValue;
|
||||
} ControlStruct, *PControlStruct;
|
||||
|
||||
void __declspec(naked) FixMissingData()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov ebx, [edx]
|
||||
cmp ebx, 0xFFFFFFFF
|
||||
jne skip
|
||||
mov ebx, 0
|
||||
skip:
|
||||
mov[ecx], ebx
|
||||
sub eax, 1
|
||||
jmp jOffset
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) GetControlOffset()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
CMP myPointer, 0
|
||||
JNE skip
|
||||
CMP[ECX - 0x1C], 0x580
|
||||
JNE skip
|
||||
mov myPointer, ecx
|
||||
sub myPointer, 0x18
|
||||
skip:
|
||||
RET 4
|
||||
}
|
||||
}
|
||||
|
||||
bool inputInitialized = false;
|
||||
|
||||
float toFloatGRID(uint8_t x)
|
||||
{
|
||||
return x / 255.0;
|
||||
}
|
||||
|
||||
void SetButton(DWORD address, bool pressed)
|
||||
{
|
||||
if (pressed)
|
||||
*(DWORD*)address = 0x3F800000;
|
||||
else
|
||||
*(DWORD*)address = 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI XInputGetStateGRID
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
__out DWORD* pState // Receives the current state
|
||||
)
|
||||
{
|
||||
if (myPointer != 0)
|
||||
{
|
||||
// Write control injector here
|
||||
if (!inputInitialized)
|
||||
{
|
||||
//info(true, "The Page is at: %08X", myPointer);
|
||||
inputInitialized = true;
|
||||
}
|
||||
|
||||
DWORD buttons2 = *wheelSection;
|
||||
DWORD buttons = *ffbOffset;
|
||||
BYTE wheel = *ffbOffset2;
|
||||
BYTE gas = *ffbOffset3;
|
||||
BYTE brake = *ffbOffset4;
|
||||
|
||||
float wheelFloat = toFloatGRID(wheel);
|
||||
float gasFloat = toFloatGRID(gas);
|
||||
float brakeFloat = toFloatGRID(brake);
|
||||
|
||||
// Wheel Float
|
||||
memcpy((void *)(myPointer + 0x484), &wheelFloat, 4);
|
||||
|
||||
// Gas Float
|
||||
memcpy((void *)(myPointer + 0x49C), &gasFloat, 4);
|
||||
|
||||
// Brake Float
|
||||
memcpy((void *)(myPointer + 0x494), &brakeFloat, 4);
|
||||
|
||||
SetButton(myPointer + 0x4, buttons & 0x1);
|
||||
SetButton(myPointer + 0x1C, buttons & 0x2);
|
||||
SetButton(myPointer + 0x24, buttons & 0x4);
|
||||
|
||||
SetButton(myPointer + 0xC, buttons2 & 0x1);
|
||||
SetButton(myPointer + 0x14, buttons2 & 0x2);
|
||||
SetButton(myPointer + 0x4C, buttons2 & 0x4);
|
||||
SetButton(myPointer + 0x414, buttons2 & 0x8);
|
||||
SetButton(myPointer + 0x404, buttons2 & 0x10);
|
||||
SetButton(myPointer + 0x3C, buttons2 & 0x20);
|
||||
SetButton(myPointer + 0x34, buttons2 & 0x40);
|
||||
SetButton(myPointer + 0x40c, buttons2 & 0x80);
|
||||
}
|
||||
|
||||
return ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
static InitFunction GRIDFunc([]()
|
||||
{
|
||||
// Crash fix
|
||||
injector::MakeNOP(0x005AB9E5, 2);
|
||||
|
||||
// Fix stupid "let's put 0xFFFFFFFF in stuff we miss to cause crashes"
|
||||
injector::MakeJMP(0x0081D647, FixMissingData, true);
|
||||
injector::WriteMemory<DWORD>(0x00AEA6DD, 0x00000000, true);
|
||||
|
||||
// Get Control Offset
|
||||
injector::MakeJMP(0x00A878E0, GetControlOffset, true);
|
||||
|
||||
// Button mashing on
|
||||
injector::WriteMemory<BYTE>(0xEAF304, 0x01, true);
|
||||
|
||||
// Prevent overwriting of button mashing by xml
|
||||
injector::MakeNOP(0x005F44B8, 6);
|
||||
injector::MakeNOP(0x00AEC695, 5);
|
||||
|
||||
// Force button mashing on
|
||||
injector::MakeNOP(0x00B76560, 6);
|
||||
|
||||
// Hook XInput to send our controls
|
||||
MH_Initialize();
|
||||
MH_CreateHookApi(L"xinput1_3.dll", "XInputGetState", &XInputGetStateGRID, NULL);
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
|
||||
}, GameID::GRID);
|
||||
#endif
|
120
OpenParrot/src/Functions/Games/TypeX2/GTIClub3.cpp
Normal file
120
OpenParrot/src/Functions/Games/TypeX2/GTIClub3.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include <StdInc.h>
|
||||
#include "Utility/InitFunction.h"
|
||||
#include "Functions/Global.h"
|
||||
#if _M_IX86
|
||||
DWORD mainModuleBase;
|
||||
int __cdecl IgnoreFunc(int a1, int a2)
|
||||
{
|
||||
int result; // eax
|
||||
|
||||
result = a2;
|
||||
*(BYTE *)(a2 + 8) = 1;
|
||||
|
||||
// Enable Input
|
||||
*(BYTE *)(mainModuleBase + 0x67E75B) = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
extern int* ffbOffset;
|
||||
extern int* ffbOffset2;
|
||||
extern int* ffbOffset3;
|
||||
extern int* ffbOffset4;
|
||||
|
||||
|
||||
float toFloat(uint8_t x)
|
||||
{
|
||||
return x / 255.0;
|
||||
}
|
||||
|
||||
float toFloatWheel(uint8_t x)
|
||||
{
|
||||
return x / 255.0 * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
static int InjectKeys()
|
||||
{
|
||||
int notButtons = ~*(WORD *)(mainModuleBase + 0x67E784);
|
||||
int buttons = *ffbOffset;
|
||||
DWORD wheel = *ffbOffset2;
|
||||
DWORD gas = *ffbOffset3;
|
||||
DWORD brake = *ffbOffset4;
|
||||
|
||||
BYTE wheelVal = (wheel - 0xFF) / 0x100;
|
||||
BYTE gasVal = (gas - 0xFF) / 0x100;
|
||||
BYTE brakeVal = (brake - 0xFF) / 0x100;
|
||||
|
||||
float wheelFloat = toFloatWheel(wheelVal);
|
||||
float gasFloat = toFloat(gasVal);
|
||||
float brakeFloat = toFloat(brakeVal);
|
||||
|
||||
if (wheelVal < 0x60)
|
||||
buttons |= 0x200;
|
||||
|
||||
if (wheelVal > 0xA0)
|
||||
buttons |= 0x400;
|
||||
|
||||
if (gasVal > 0xA0)
|
||||
buttons |= 0x20;
|
||||
|
||||
if (brakeVal > 0xA0)
|
||||
buttons |= 0x40;
|
||||
|
||||
// Digital Inputs
|
||||
*(WORD *)(mainModuleBase + 0x67E784) = buttons;
|
||||
|
||||
// Wheel Test Menu
|
||||
*(WORD *)(mainModuleBase + 0x518C8C) = *ffbOffset2;
|
||||
|
||||
// Gas Test Menu
|
||||
*(WORD *)(mainModuleBase + 0x518C90) = *ffbOffset3;
|
||||
|
||||
// Brake Test Menu
|
||||
*(WORD *)(mainModuleBase + 0x518C94) = *ffbOffset4;
|
||||
|
||||
// Wheel Float
|
||||
memcpy((void *)(mainModuleBase + 0x518C80), &wheelFloat, 4);
|
||||
|
||||
// Gas Float
|
||||
memcpy((void *)(mainModuleBase + 0x518C84), &gasFloat, 4);
|
||||
|
||||
// Brake Float
|
||||
memcpy((void *)(mainModuleBase + 0x518C88), &brakeFloat, 4);
|
||||
|
||||
*(DWORD*)0xA7E788 = buttons & notButtons;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int(*g_origac_io_hbhi_COMUNICATE)();
|
||||
|
||||
signed int __cdecl ac_io_hbhi_COMUNICATE()
|
||||
{
|
||||
InjectKeys();
|
||||
|
||||
return g_origac_io_hbhi_COMUNICATE();
|
||||
}
|
||||
|
||||
static InitFunction GtiClub3Func([]()
|
||||
{
|
||||
|
||||
mainModuleBase = (DWORD)GetModuleHandle(0);
|
||||
|
||||
DWORD funcPtr = (DWORD)(void *)IgnoreFunc;
|
||||
|
||||
CreateDirectoryA("EUP", nullptr);
|
||||
CreateDirectoryA("FUP", nullptr);
|
||||
|
||||
injector::WriteMemory<DWORD>(mainModuleBase + 0x4C0E0C, funcPtr, true);
|
||||
injector::WriteMemory<DWORD>(mainModuleBase + 0x4C0E14, funcPtr, true);
|
||||
injector::WriteMemory<DWORD>(mainModuleBase + 0x4C0E1C, funcPtr, true);
|
||||
injector::WriteMemory<DWORD>(mainModuleBase + 0x4C0E3C, funcPtr, true);
|
||||
|
||||
injector::WriteMemory<DWORD>(mainModuleBase + 0x357CB4, 0x55465C2E, true);
|
||||
injector::WriteMemory<DWORD>(mainModuleBase + 0x357C80, 0x55455C2E, true);
|
||||
|
||||
MH_Initialize();
|
||||
MH_CreateHook((void*)(mainModuleBase + 0x409C0), ac_io_hbhi_COMUNICATE, (void**)&g_origac_io_hbhi_COMUNICATE); // ?
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
|
||||
}, GameID::GTIClub3);
|
||||
#endif
|
@ -10,5 +10,5 @@ enum class X2Type {
|
||||
Generic,
|
||||
GaiaAttack4,
|
||||
BattleFantasia,
|
||||
MB4
|
||||
MB4,
|
||||
};
|
@ -360,6 +360,12 @@ void GameDetect::DetectCurrentGame()
|
||||
case 0xbb359a1a: // Suggoi! Arcana Heart 2
|
||||
currentGame = GameID::ExBoardGeneric;
|
||||
break;
|
||||
case 0x4966e11b:
|
||||
currentGame = GameID::GRID;
|
||||
break;
|
||||
case 0x326ebcd6:
|
||||
currentGame = GameID::GTIClub3;
|
||||
break;
|
||||
//case 0xea1984ff:
|
||||
// currentGame = GameID::ExBoardGeneric;
|
||||
// break;
|
||||
|
@ -46,5 +46,7 @@ enum class GameID
|
||||
MagicalBeat,
|
||||
CrimzonClover,
|
||||
Daytona3,
|
||||
MB4
|
||||
MB4,
|
||||
GTIClub3,
|
||||
GRID
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user