commit
57e8d5bc01
@ -10,6 +10,70 @@ int __stdcall Sr3FfbFunc(DWORD device, DWORD data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD(__stdcall* GetPrivateProfileIntAOri)(LPCSTR lpAppName, LPCSTR lpKeyName, INT nDefault, LPCSTR lpFileName);
|
||||
|
||||
DWORD WINAPI GetPrivateProfileIntAHook(LPCSTR lpAppName, LPCSTR lpKeyName, INT nDefault, LPCSTR lpFileName)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
info(true, "GetPrivateProfileIntAHook %s", lpKeyName);
|
||||
#endif
|
||||
|
||||
if (_stricmp(lpKeyName, "HorizontalResolution") == 0)
|
||||
return FetchDwordInformation("General", "ResolutionWidth", 1280);
|
||||
else if (_stricmp(lpKeyName, "VerticalResolution") == 0)
|
||||
return FetchDwordInformation("General", "ResolutionHeight", 720);
|
||||
else if (_stricmp(lpKeyName, "Freeplay") == 0)
|
||||
return (DWORD)ToBool(config["General"]["FreePlay"]);
|
||||
else
|
||||
return GetPrivateProfileIntAOri(lpAppName, lpKeyName, nDefault, lpFileName);
|
||||
}
|
||||
|
||||
DWORD(__stdcall* GetPrivateProfileStringAOri)(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, DWORD nSize, LPCSTR lpFileName);
|
||||
|
||||
DWORD WINAPI GetPrivateProfileStringAHook(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, DWORD nSize, LPCSTR lpFileName)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
info(true, "GetPrivateProfileStringAHook %s", lpKeyName);
|
||||
#endif
|
||||
|
||||
if (_stricmp(lpKeyName, "LANGUAGE") == 0)
|
||||
{
|
||||
strcpy(lpReturnedString, config["General"]["Language"].c_str());
|
||||
return nSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetPrivateProfileStringAOri(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, lpFileName);
|
||||
}
|
||||
}
|
||||
|
||||
HWND(__stdcall* CreateWindowExAOrg)(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
|
||||
|
||||
static HWND WINAPI CreateWindowExAHook(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
|
||||
{
|
||||
if (nWidth == 0 || nHeight == 0)
|
||||
{
|
||||
nWidth = FetchDwordInformation("General", "ResolutionWidth", 1280);
|
||||
nHeight = FetchDwordInformation("General", "ResolutionHeight", 720);
|
||||
}
|
||||
|
||||
return CreateWindowExAOrg(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
||||
}
|
||||
|
||||
static BOOL(__stdcall* ClipCursorOrg)(const RECT* lpRect);
|
||||
|
||||
static BOOL WINAPI ClipCursorHook(const RECT* lpRect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static BOOL(__stdcall* GetClipCursorOrg)(LPRECT lpRect);
|
||||
|
||||
static BOOL WINAPI GetClipCursorHook(LPRECT lpRect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static InitFunction sr3Func([]()
|
||||
{
|
||||
DWORD oldprot = 0;
|
||||
@ -31,12 +95,35 @@ static InitFunction sr3Func([]()
|
||||
// Give our own pointer to the FFB func
|
||||
injector::WriteMemory<uint8_t>(0x006582A8, 0xB8, true);
|
||||
injector::WriteMemory<DWORD>(0x006582A9, (DWORD)Sr3FfbFunc, true);
|
||||
//
|
||||
|
||||
// ReadFile call
|
||||
static DWORD source = (DWORD)(LPVOID)&ReadFileHooked;
|
||||
*(DWORD *)0x57B696 = (DWORD)(LPVOID)&source;
|
||||
VirtualProtect((LPVOID)0x401000, 0x273000, oldprot, &oldprot2);
|
||||
|
||||
// skip minimum resolution check
|
||||
injector::WriteMemory<BYTE>(0x588755, 0xEB, true); // width
|
||||
injector::WriteMemory<BYTE>(0x588762, 0xEB, true); // height
|
||||
|
||||
MH_Initialize();
|
||||
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
// don't hide cursor
|
||||
injector::MakeNOP(0x591106, 8, true);
|
||||
|
||||
// don't clip cursor
|
||||
MH_CreateHookApi(L"User32.dll", "ClipCursor", &ClipCursorHook, (void**)&ClipCursorOrg);
|
||||
MH_CreateHookApi(L"User32.dll", "GetClipCursor", &GetClipCursorHook, (void**)&GetClipCursorOrg);
|
||||
injector::MakeNOP(0x591189, 8, true);
|
||||
injector::MakeNOP(0x5910FE, 8, true);
|
||||
|
||||
MH_CreateHookApi(L"User32.dll", "CreateWindowExA", &CreateWindowExAHook, (void**)&CreateWindowExAOrg);
|
||||
}
|
||||
|
||||
MH_CreateHookApi(L"kernel32.dll", "GetPrivateProfileIntA", &GetPrivateProfileIntAHook, (void**)&GetPrivateProfileIntAOri);
|
||||
MH_CreateHookApi(L"kernel32.dll", "GetPrivateProfileStringA", &GetPrivateProfileStringAHook, (void**)&GetPrivateProfileStringAOri);
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
|
||||
}, GameID::SR3);
|
||||
#endif
|
@ -7,6 +7,7 @@
|
||||
#include "Functions/Nesica_Libs/NesysEmu.h"
|
||||
#include "Functions/Nesica_Libs/RegHooks.h"
|
||||
#include "Utility/Hooking.Patterns.h"
|
||||
#include <Functions/Global.h>
|
||||
|
||||
static InitFunction initFunction([]()
|
||||
{
|
||||
@ -45,33 +46,33 @@ static InitFunction initFunction_GC2([]()
|
||||
init_RegHooks();
|
||||
init_NesysEmu();
|
||||
|
||||
// Patch D: references
|
||||
//D:
|
||||
injector::WriteMemoryRaw(imageBase + 0x33D344, ".", 2, true);
|
||||
// D:/garbage%d.txt
|
||||
injector::WriteMemoryRaw(imageBase + 0x2B6B08, "./garbage%d.txt", 16, true);
|
||||
// D:/country.dat
|
||||
injector::WriteMemoryRaw(imageBase + 0x2B4B68, "./country.dat", 14, true);
|
||||
injector::WriteMemoryRaw(imageBase + 0x2B4B54, "./country.dat", 14, true);
|
||||
// D:/NesysQueue_Error_%04d_%02d_%02d_%02d_%02d_%02d.txt
|
||||
injector::WriteMemoryRaw(imageBase + 0x2B205C, "./NesysQueue_Error_%04d_%02d_%02d_%02d_%02d_%02d.txt", 53, true);
|
||||
// D:/count.csv
|
||||
injector::WriteMemoryRaw(imageBase + 0x2B1024, "./count.csv", 12, true);
|
||||
injector::WriteMemoryRaw(imageBase + 0x2B0F40, "./count.csv", 12, true);
|
||||
// D:\\%s/
|
||||
injector::WriteMemoryRaw(imageBase + 0x27AD80, "./%s/", 6, true);
|
||||
// D:\\%s/*
|
||||
injector::WriteMemoryRaw(imageBase + 0x27AD78, "./%s/*", 7, true);
|
||||
// "D:\\%s/%s"
|
||||
injector::WriteMemoryRaw(imageBase + 0x27AD6C, "./%s/%s", 8, true);
|
||||
// "D:\\"
|
||||
injector::WriteMemoryRaw(imageBase + 0x27AC44, "./", 3, true);
|
||||
// D:\\%s%04d%02d%02d_%02d%02d%02d_
|
||||
injector::WriteMemoryRaw(imageBase + 0x27AC00, "./%s%04d%02d%02d_%02d%02d%02d_", 31, true);
|
||||
// D:\\%s/%s/*
|
||||
injector::WriteMemoryRaw(imageBase + 0x27AD60, "./%s/%s/*", 10, true);
|
||||
// D:/PlayData/
|
||||
injector::WriteMemoryRaw(imageBase + 0x2A9CB8, "./PlayData/", 12, true);
|
||||
//// Patch D: references
|
||||
////D:
|
||||
//injector::WriteMemoryRaw(imageBase + 0x33D344, ".", 2, true);
|
||||
//// D:/garbage%d.txt
|
||||
//injector::WriteMemoryRaw(imageBase + 0x2B6B08, "./garbage%d.txt", 16, true);
|
||||
//// D:/country.dat
|
||||
//injector::WriteMemoryRaw(imageBase + 0x2B4B68, "./country.dat", 14, true);
|
||||
//injector::WriteMemoryRaw(imageBase + 0x2B4B54, "./country.dat", 14, true);
|
||||
//// D:/NesysQueue_Error_%04d_%02d_%02d_%02d_%02d_%02d.txt
|
||||
//injector::WriteMemoryRaw(imageBase + 0x2B205C, "./NesysQueue_Error_%04d_%02d_%02d_%02d_%02d_%02d.txt", 53, true);
|
||||
//// D:/count.csv
|
||||
//injector::WriteMemoryRaw(imageBase + 0x2B1024, "./count.csv", 12, true);
|
||||
//injector::WriteMemoryRaw(imageBase + 0x2B0F40, "./count.csv", 12, true);
|
||||
//// D:\\%s/
|
||||
//injector::WriteMemoryRaw(imageBase + 0x27AD80, "./%s/", 6, true);
|
||||
//// D:\\%s/*
|
||||
//injector::WriteMemoryRaw(imageBase + 0x27AD78, "./%s/*", 7, true);
|
||||
//// "D:\\%s/%s"
|
||||
//injector::WriteMemoryRaw(imageBase + 0x27AD6C, "./%s/%s", 8, true);
|
||||
//// "D:\\"
|
||||
//injector::WriteMemoryRaw(imageBase + 0x27AC44, "./", 3, true);
|
||||
//// D:\\%s%04d%02d%02d_%02d%02d%02d_
|
||||
//injector::WriteMemoryRaw(imageBase + 0x27AC00, "./%s%04d%02d%02d_%02d%02d%02d_", 31, true);
|
||||
//// D:\\%s/%s/*
|
||||
//injector::WriteMemoryRaw(imageBase + 0x27AD60, "./%s/%s/*", 10, true);
|
||||
//// D:/PlayData/
|
||||
//injector::WriteMemoryRaw(imageBase + 0x2A9CB8, "./PlayData/", 12, true);
|
||||
|
||||
// C:\\TypeXZEROTemp.dat check
|
||||
safeJMP(imageBase + 0xF81B0, ReturnTrue);
|
||||
@ -136,7 +137,7 @@ static InitFunction initFunction_DariusBurst116([]()
|
||||
// NOTE: This could be cause for the non-working TEST MODE. No time to analyze since dump was released and we want to give instant support.
|
||||
//injector::WriteMemory<BYTE>(imageBase + 0x302743, 0xEB, true);
|
||||
|
||||
// D:
|
||||
//// D:
|
||||
injector::WriteMemoryRaw(imageBase + 0x4EEF68, "\x2E\x5C\x44", 3, true); // D:\%s%04d%02d%02d_%02d%02d%02d_
|
||||
injector::WriteMemoryRaw(imageBase + 0x4EF0D0, "\x2E\x5C\x44", 3, true); // D:\%s/%s/*
|
||||
injector::WriteMemoryRaw(imageBase + 0x4EF0DC, "\x2E\x5C\x44", 3, true); // D:\%s/%s
|
||||
@ -453,6 +454,82 @@ static InitFunction initFunction_BlazBlueCF201([]()
|
||||
|
||||
}, GameID::BlazBlueCF201);
|
||||
|
||||
static InitFunction initFunction_DarkAwake([]()
|
||||
{
|
||||
uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0);
|
||||
DWORD oldPageProtection = 0;
|
||||
init_FastIoEmu();
|
||||
init_RfidEmu();
|
||||
init_RegHooks();
|
||||
if (GameDetect::enableNesysEmu)
|
||||
init_NesysEmu();
|
||||
#if _M_IX86
|
||||
init_CryptoPipe(GameDetect::NesicaKey);
|
||||
#endif
|
||||
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
// force windowed mode
|
||||
injector::MakeNOP(imageBase + 0x169BF, 2, true);
|
||||
|
||||
VirtualProtect((LPVOID)(imageBase + 0x601CC), 64, PAGE_EXECUTE_READWRITE, &oldPageProtection);
|
||||
windowHooks hooks = { 0 };
|
||||
hooks.createWindowExA = imageBase + 0x601E8;
|
||||
hooks.setWindowPos = imageBase + 0x601F0;
|
||||
init_windowHooks(&hooks);
|
||||
VirtualProtect((LPVOID)(imageBase + 0x601CC), 64, oldPageProtection, &oldPageProtection);
|
||||
|
||||
// change window name
|
||||
static const char* title = "OpenParrot - Dark Awake";
|
||||
injector::WriteMemory<DWORD>(imageBase + 0x16736, (DWORD)title, true);
|
||||
|
||||
// don't resize to current work area
|
||||
injector::MakeNOP(imageBase + 0x377F2, 15, true);
|
||||
|
||||
// show cursor
|
||||
injector::WriteMemory<BYTE>(imageBase + 0x165D9, 0x01, true);
|
||||
}
|
||||
|
||||
}, GameID::DarkAwake);
|
||||
|
||||
static InitFunction initFunction_ChaosBreakerNXL([]()
|
||||
{
|
||||
uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0);
|
||||
DWORD oldPageProtection = 0;
|
||||
init_FastIoEmu();
|
||||
init_RfidEmu();
|
||||
init_RegHooks();
|
||||
if (GameDetect::enableNesysEmu)
|
||||
init_NesysEmu();
|
||||
#if _M_IX86
|
||||
init_CryptoPipe(GameDetect::NesicaKey);
|
||||
#endif
|
||||
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
// force windowed mode
|
||||
injector::MakeNOP(imageBase + 0x169AF, 2, true);
|
||||
|
||||
VirtualProtect((LPVOID)(imageBase + 0x601CC), 64, PAGE_EXECUTE_READWRITE, &oldPageProtection);
|
||||
windowHooks hooks = { 0 };
|
||||
hooks.createWindowExA = imageBase + 0x601E8;
|
||||
hooks.setWindowPos = imageBase + 0x601F0;
|
||||
init_windowHooks(&hooks);
|
||||
VirtualProtect((LPVOID)(imageBase + 0x601CC), 64, oldPageProtection, &oldPageProtection);
|
||||
|
||||
// change window name
|
||||
static const char* title = "OpenParrot - Chaos Breaker";
|
||||
injector::WriteMemory<DWORD>(imageBase + 0x16726, (DWORD)title, true);
|
||||
|
||||
// don't resize to current work area
|
||||
injector::MakeNOP(imageBase + 0x37452, 15, true);
|
||||
|
||||
// show cursor
|
||||
injector::WriteMemory<BYTE>(imageBase + 0x165C9, 0x01, true);
|
||||
}
|
||||
|
||||
}, GameID::ChaosBreakerNXL);
|
||||
|
||||
static InitFunction initFunction_Theatrhythm([]()
|
||||
{
|
||||
uintptr_t imageBase = (uintptr_t)GetModuleHandleA(0);
|
||||
|
@ -11,6 +11,7 @@ extern int* ffbOffset;
|
||||
extern int* ffbOffset2;
|
||||
extern int* ffbOffset3;
|
||||
extern int* ffbOffset4;
|
||||
int FFBDeadzoneMaxMin;
|
||||
bool daytonaPressStart = false;
|
||||
uintptr_t imageBase;
|
||||
bool shiftup = false;
|
||||
@ -20,6 +21,26 @@ static bool keybdleft = false;
|
||||
static bool keybdright = false;
|
||||
static bool keybdup = false;
|
||||
|
||||
float Cubic(const float x, const float weight)
|
||||
{
|
||||
return weight * x * x * x + (1.0 - weight) * x;
|
||||
}
|
||||
|
||||
float joystickCubicScaledDeadband(const float x)
|
||||
{
|
||||
const float deadbandCutoff = 0.2f;
|
||||
const float weight = 0.5f;
|
||||
|
||||
if (fabs(x) < deadbandCutoff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (Cubic(x, weight) - (fabs(x) / x) * Cubic(deadbandCutoff, weight)) / (1.0 - Cubic(deadbandCutoff, weight));
|
||||
}
|
||||
}
|
||||
|
||||
void ShiftUp(BYTE shift)
|
||||
{
|
||||
*(BYTE*)(imageBase + 0x15B468C) = shift + 1;
|
||||
@ -30,9 +51,8 @@ void ShiftDown(BYTE shift)
|
||||
*(BYTE*)(imageBase + 0x15B468C) = shift - 1;
|
||||
}
|
||||
|
||||
static void InjectKeys()
|
||||
static int ThreadLoop()
|
||||
{
|
||||
|
||||
DWORD buttons2 = *wheelSection;
|
||||
DWORD buttons = *ffbOffset;
|
||||
BYTE wheel = *ffbOffset2;
|
||||
@ -48,6 +68,15 @@ static void InjectKeys()
|
||||
|
||||
HWND hWnd = FindWindowA(0, ("Daytona Championship USA"));
|
||||
|
||||
if (ToBool(config["General"]["Cubic Scaled Deadband"]))
|
||||
{
|
||||
float joycubicdeadband = joystickCubicScaledDeadband((*ffbOffset2 - 128) / 128.0);
|
||||
wheel = 128 + (joycubicdeadband * 128.0);
|
||||
|
||||
if (wheel >= 251)
|
||||
wheel = 255;
|
||||
}
|
||||
|
||||
//Menu Movement & Game Initial Screen
|
||||
if (gamestate == 18 || gamestate == 30)
|
||||
{
|
||||
@ -275,15 +304,16 @@ static void InjectKeys()
|
||||
*(DWORD*)(imageBase + 0x15B5DB0) = 0x03;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int(__stdcall* g_origControlsFunction)();
|
||||
|
||||
int __stdcall ControlsFunction()
|
||||
static DWORD WINAPI RunningLoop(LPVOID lpParam)
|
||||
{
|
||||
int result = g_origControlsFunction();
|
||||
InjectKeys();
|
||||
return result;
|
||||
while (true)
|
||||
{
|
||||
ThreadLoop();
|
||||
Sleep(16);
|
||||
}
|
||||
}
|
||||
|
||||
static InitFunction Daytona3Func([]()
|
||||
@ -299,17 +329,22 @@ static InitFunction Daytona3Func([]()
|
||||
injector::MakeNOP(imageBase + 0x1DE10D, 6);
|
||||
injector::MakeNOP(imageBase + 0x29B481, 3);
|
||||
injector::MakeNOP(imageBase + 0x29B513, 4);
|
||||
|
||||
if (ToBool(config["General"]["MSAA4X Disable"]))
|
||||
{
|
||||
injector::WriteMemoryRaw(imageBase + 0x17CD3D, "\x00", 1, true);
|
||||
}
|
||||
|
||||
if (ToBool(config["General"]["Hide Cursor"]))
|
||||
{
|
||||
SetCursorPos(20000, 20000);
|
||||
}
|
||||
MH_Initialize();
|
||||
MH_CreateHook((void*)(imageBase + 0x1E9280), ControlsFunction, (void**)&g_origControlsFunction);
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
|
||||
std::string FFBDeadzoneString = config["General"]["FFB Deadzone Percent"];
|
||||
int FFBDeadzone = std::stoi(FFBDeadzoneString);
|
||||
FFBDeadzoneMaxMin = (128 * FFBDeadzone) / 100.0;
|
||||
|
||||
CreateThread(NULL, 0, RunningLoop, NULL, 0, NULL);
|
||||
|
||||
}, GameID::Daytona3);
|
||||
#endif
|
@ -35,7 +35,10 @@ static bool STARTpressed = false;
|
||||
static bool TESTpressed = false;
|
||||
static bool SERVICEpressed = false;
|
||||
static bool previousVolMin = false;
|
||||
static bool previousVolMax = false;
|
||||
static bool previousVolMax = false;
|
||||
static bool MenuHack = false;
|
||||
static bool RiptideHack = false;
|
||||
static bool MenuHackStopWriting = false;
|
||||
|
||||
// controls
|
||||
extern int* ffbOffset;
|
||||
@ -83,7 +86,7 @@ void __stdcall ServiceControlsPatch()
|
||||
}
|
||||
}
|
||||
// VOL+
|
||||
if ((GetAsyncKeyState(VK_UP) & 0x8000) || (*ffbOffset & 0x1000))
|
||||
if (*ffbOffset & 0x1000)
|
||||
{
|
||||
if (previousVolMax == false)
|
||||
{
|
||||
@ -100,7 +103,7 @@ void __stdcall ServiceControlsPatch()
|
||||
}
|
||||
}
|
||||
// VOL-
|
||||
if ((GetAsyncKeyState(VK_DOWN) & 0x8000) || (*ffbOffset & 0x2000))
|
||||
if (*ffbOffset & 0x2000)
|
||||
{
|
||||
if (previousVolMin == false)
|
||||
{
|
||||
@ -126,6 +129,101 @@ DWORD WINAPI InputRT9(LPVOID lpParam)
|
||||
|
||||
while (true)
|
||||
{
|
||||
BYTE GameState = *(BYTE*)(0x570190 + BaseAddress9);
|
||||
BYTE Chosen = *(BYTE*)(0x5705E8 + BaseAddress9);
|
||||
|
||||
if (GameState == 0x05)
|
||||
{
|
||||
if (!MenuHack)
|
||||
{
|
||||
MenuHack = true;
|
||||
injector::MakeNOP((0x78A27 + BaseAddress9), 6, true);
|
||||
}
|
||||
}
|
||||
else if (GameState == 0x06 || GameState == 0x08 || GameState == 0x12)
|
||||
{
|
||||
if (MenuHack)
|
||||
{
|
||||
MenuHack = false;
|
||||
MenuHackStopWriting = false;
|
||||
|
||||
injector::WriteMemory((0x78A27 + BaseAddress9), 0x03448689, true);
|
||||
injector::WriteMemory((0x78A2B + BaseAddress9), 0x8E890000, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (MenuHack)
|
||||
{
|
||||
if (Chosen == 0x01)
|
||||
{
|
||||
MenuHackStopWriting = true;
|
||||
}
|
||||
|
||||
if (!MenuHackStopWriting)
|
||||
{
|
||||
if (*ffbOffset2 >= 0xEE)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x0A;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0xDD)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x0C;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0xCC)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x08;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0xBB)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x0D;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0xAA)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x0E;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x99)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x09;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x88)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x0B;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x77)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x02;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x66)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x00;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x55)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x04;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x44)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x06;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x33)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x05;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x22)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x03;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x11)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x01;
|
||||
}
|
||||
else if (*ffbOffset2 >= 0x00)
|
||||
{
|
||||
*(BYTE*)(0x570234 + BaseAddress9) = 0x10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
if (hWndRT9 == 0)
|
||||
@ -211,9 +309,27 @@ DWORD WINAPI InputRT9(LPVOID lpParam)
|
||||
}
|
||||
|
||||
// WHEEL
|
||||
int iWheel = (((float)*ffbOffset2) - 128);
|
||||
float wheel = (iWheel * 0.0078125f);
|
||||
injector::WriteMemory<float>((0x4AD0FC + BaseAddress9), wheel, true);
|
||||
if ((GameState == 0x06) && (*ffbOffset2 > 0x60 && *ffbOffset2 < 0x70))
|
||||
{
|
||||
if (!RiptideHack)
|
||||
{
|
||||
RiptideHack = true;
|
||||
*(BYTE*)(0x44BAD0 + BaseAddress9) = 0x08;
|
||||
injector::WriteMemory<float>((0x4AD0FC + BaseAddress9), -1.0f, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (RiptideHack)
|
||||
{
|
||||
RiptideHack = false;
|
||||
*(BYTE*)(0x44BAD0 + BaseAddress9) = 0x0B;
|
||||
}
|
||||
|
||||
int iWheel = (((float)*ffbOffset2) - 128);
|
||||
float wheel = (iWheel * 0.0078125f);
|
||||
injector::WriteMemory<float>((0x4AD0FC + BaseAddress9), wheel, true);
|
||||
}
|
||||
//// GAS
|
||||
float gas = (float)*ffbOffset3 / 255.0f;
|
||||
float brake = (float)*ffbOffset4 / 255.0f;
|
||||
|
@ -14,7 +14,7 @@ using namespace std;
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
DWORD BaseAddress6 = 0x00400000;
|
||||
static uintptr_t imageBase;
|
||||
int horizontal6 = 0;
|
||||
int vertical6 = 0;
|
||||
HWND hWndRT6 = 0;
|
||||
@ -22,6 +22,26 @@ HWND hWndRT6 = 0;
|
||||
extern int* ffbOffset;
|
||||
extern int* ffbOffset3;
|
||||
extern int* ffbOffset4;
|
||||
extern XINPUT_GAMEPAD gamepadState;
|
||||
|
||||
static bool GHAStart;
|
||||
static bool GHAStart2;
|
||||
static bool GHAUP;
|
||||
static bool GHADOWN;
|
||||
static bool GHALEFT;
|
||||
static bool GHARIGHT;
|
||||
static bool GHAUP2;
|
||||
static bool GHADOWN2;
|
||||
static bool GHALEFT2;
|
||||
static bool GHARIGHT2;
|
||||
static bool GHAA;
|
||||
static bool GHAB;
|
||||
static bool GHAX;
|
||||
static bool GHAY;
|
||||
static bool GHALB;
|
||||
static bool GHARB;
|
||||
|
||||
static bool init;
|
||||
|
||||
// hooks ori
|
||||
BOOL(__stdcall *original_SetWindowPos6)(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
|
||||
@ -72,6 +92,262 @@ DWORD WINAPI WindowRT6(LPVOID lpParam)
|
||||
}
|
||||
}
|
||||
|
||||
void GHAInputs()
|
||||
{
|
||||
if (!init)
|
||||
{
|
||||
BYTE Modify = *(BYTE*)(imageBase + 0x13B3DC4);
|
||||
|
||||
if (Modify)
|
||||
{
|
||||
init = true;
|
||||
*(BYTE*)(imageBase + 0x857AE0) = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
BYTE Active = *(BYTE*)(imageBase + 0x857AE0);
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_START) // START KEY MACRO (When not playing song)
|
||||
{
|
||||
if (!GHAStart)
|
||||
{
|
||||
GHAStart = true;
|
||||
GHAStart2 = true;
|
||||
if (!Active)
|
||||
{
|
||||
gamepadState.wButtons += 0xF000;
|
||||
gamepadState.bLeftTrigger += 0xFF;
|
||||
gamepadState.bRightTrigger += 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAStart2)
|
||||
{
|
||||
GHAStart2 = false;
|
||||
if (!Active)
|
||||
{
|
||||
gamepadState.wButtons -= 0xF000;
|
||||
gamepadState.bLeftTrigger -= 0xFF;
|
||||
gamepadState.bRightTrigger -= 0xFF;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAStart)
|
||||
{
|
||||
GHAStart = false;
|
||||
|
||||
if (Active)
|
||||
{
|
||||
if (gamepadState.wButtons == 0xF000 && gamepadState.bLeftTrigger == 0xFF && gamepadState.bRightTrigger == 0xFF)
|
||||
{
|
||||
gamepadState.wButtons -= 0xF000;
|
||||
gamepadState.bLeftTrigger -= 0xFF;
|
||||
gamepadState.bRightTrigger -= 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_X) // GREEN KEY MACRO
|
||||
{
|
||||
if (!GHAX)
|
||||
{
|
||||
GHAX = true;
|
||||
gamepadState.bLeftTrigger += 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAX)
|
||||
{
|
||||
GHAX = false;
|
||||
gamepadState.bLeftTrigger -= 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_Y) // BLUE KEY MACRO
|
||||
{
|
||||
if (!GHAY)
|
||||
{
|
||||
GHAY = true;
|
||||
gamepadState.bRightTrigger += 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAY)
|
||||
{
|
||||
GHAY = false;
|
||||
gamepadState.bRightTrigger -= 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_A)
|
||||
{
|
||||
if (!GHAA)
|
||||
{
|
||||
GHAA = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_A;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAA)
|
||||
{
|
||||
GHAA = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_A;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_B)
|
||||
{
|
||||
if (!GHAB)
|
||||
{
|
||||
GHAB = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_B;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAB)
|
||||
{
|
||||
GHAB = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_B;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_DPAD_UP)
|
||||
{
|
||||
if (!GHAUP)
|
||||
{
|
||||
GHAUP = true;
|
||||
GHAUP2 = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_DPAD_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAUP2)
|
||||
{
|
||||
GHAUP2 = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_DPAD_UP;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHAUP)
|
||||
GHAUP = false;
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||
{
|
||||
if (!GHADOWN)
|
||||
{
|
||||
GHADOWN = true;
|
||||
GHADOWN2 = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_DPAD_DOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHADOWN2)
|
||||
{
|
||||
GHADOWN2 = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_DPAD_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHADOWN)
|
||||
GHADOWN = false;
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||
{
|
||||
if (!GHALEFT)
|
||||
{
|
||||
GHALEFT = true;
|
||||
GHALEFT2 = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_DPAD_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHALEFT2)
|
||||
{
|
||||
GHALEFT2 = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_DPAD_LEFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHALEFT)
|
||||
GHALEFT = false;
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||
{
|
||||
if (!GHARIGHT)
|
||||
{
|
||||
GHARIGHT = true;
|
||||
GHARIGHT2 = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_DPAD_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHARIGHT2)
|
||||
{
|
||||
GHARIGHT2 = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_DPAD_RIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHARIGHT)
|
||||
GHARIGHT = false;
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_LEFT_SHOULDER)
|
||||
{
|
||||
if (!GHALB)
|
||||
{
|
||||
GHALB = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_LEFT_SHOULDER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHALB)
|
||||
{
|
||||
GHALB = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_LEFT_SHOULDER;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ffbOffset & XINPUT_GAMEPAD_RIGHT_SHOULDER)
|
||||
{
|
||||
if (!GHARB)
|
||||
{
|
||||
GHARB = true;
|
||||
gamepadState.wButtons += XINPUT_GAMEPAD_RIGHT_SHOULDER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GHARB)
|
||||
{
|
||||
GHARB = false;
|
||||
gamepadState.wButtons -= XINPUT_GAMEPAD_RIGHT_SHOULDER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI DefWindowProcART6(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static int xClick;
|
||||
@ -134,6 +410,8 @@ DWORD WINAPI SetWindowTextWRT6(HWND hWnd, LPCWSTR lpString)
|
||||
|
||||
static InitFunction GHAFunc([]()
|
||||
{
|
||||
imageBase = (uintptr_t)GetModuleHandleA(0);
|
||||
|
||||
init_GlobalRegHooks();
|
||||
GetDesktopResolution(horizontal6, vertical6);
|
||||
|
||||
|
@ -13,9 +13,6 @@ typedef unsigned int U32;
|
||||
typedef unsigned char U8;
|
||||
|
||||
DWORD BaseAddress7 = 0x00400000;
|
||||
int horizontal7 = 0;
|
||||
int vertical7 = 0;
|
||||
HWND hWndRT7 = 0;
|
||||
|
||||
static bool previousLeft = false;
|
||||
static bool previousRight = false;
|
||||
@ -43,9 +40,6 @@ extern int* ffbOffset;
|
||||
extern int* ffbOffset2;
|
||||
extern int* ffbOffset3;
|
||||
extern int* ffbOffset4;
|
||||
// hooks ori
|
||||
BOOL(__stdcall* original_SetWindowPos7)(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
|
||||
BOOL(__stdcall* original_CreateWindowExA7)(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 InputRT7(LPVOID lpParam)
|
||||
{
|
||||
@ -55,198 +49,184 @@ DWORD WINAPI InputRT7(LPVOID lpParam)
|
||||
|
||||
while (true)
|
||||
{
|
||||
// ESCAPE QUITS GAME
|
||||
if (GetAsyncKeyState(VK_ESCAPE) & 0x8000)
|
||||
if (GetAsyncKeyState(VK_NUMPAD1) & 0x0001)
|
||||
{
|
||||
HWND hWndTMP = GetForegroundWindow();
|
||||
if (hWndRT7 == 0)
|
||||
if (NUMpressed1 == false)
|
||||
{
|
||||
hWndRT7 = FindWindowA(NULL, "X-Games SnoCross");
|
||||
}
|
||||
if (hWndTMP == hWndRT7)
|
||||
{
|
||||
exit(0);
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x01\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(VK_NUMPAD1) & 0x0001)
|
||||
{
|
||||
if (NUMpressed1 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x01\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed1 = true;
|
||||
if (NUMpressed1 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed1 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed1 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD2) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed1 = false;
|
||||
if (NUMpressed2 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x02\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD2) & 0x0001)
|
||||
{
|
||||
if (NUMpressed2 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x02\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed2 = true;
|
||||
if (NUMpressed2 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed2 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed2 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD3) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed2 = false;
|
||||
if (NUMpressed3 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x03\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed3 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD3) & 0x0001)
|
||||
{
|
||||
if (NUMpressed3 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x03\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed3 = true;
|
||||
if (NUMpressed3 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed3 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed3 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD4) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed3 = false;
|
||||
if (NUMpressed4 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x04\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed4 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD4) & 0x0001)
|
||||
{
|
||||
if (NUMpressed4 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x04\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed4 = true;
|
||||
if (NUMpressed4 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed4 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed4 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD5) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed4 = false;
|
||||
if (NUMpressed5 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x05\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed5 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD5) & 0x0001)
|
||||
{
|
||||
if (NUMpressed5 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x05\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed5 = true;
|
||||
if (NUMpressed5 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed5 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed5 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD6) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed5 = false;
|
||||
if (NUMpressed6 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x06\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed6 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD6) & 0x0001)
|
||||
{
|
||||
if (NUMpressed6 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x06\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed6 = true;
|
||||
if (NUMpressed6 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed6 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed6 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD7) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed6 = false;
|
||||
if (NUMpressed7 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x07\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed7 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD7) & 0x0001)
|
||||
{
|
||||
if (NUMpressed7 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x07\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed7 = true;
|
||||
if (NUMpressed7 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed7 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed7 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD8) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed7 = false;
|
||||
if (NUMpressed8 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x08\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed8 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD8) & 0x0001)
|
||||
{
|
||||
if (NUMpressed8 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x08\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed8 = true;
|
||||
if (NUMpressed8 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed8 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed8 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD9) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed8 = false;
|
||||
if (NUMpressed9 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x09\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed9 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD9) & 0x0001)
|
||||
{
|
||||
if (NUMpressed9 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x09\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed9 = true;
|
||||
if (NUMpressed9 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed9 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed9 == true)
|
||||
if (GetAsyncKeyState(VK_NUMPAD0) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed9 = false;
|
||||
if (NUMpressed0 == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x00\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed0 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_NUMPAD0) & 0x0001)
|
||||
{
|
||||
if (NUMpressed0 == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x00\x00\x00\x00\x90", 6, true);
|
||||
NUMpressed0 = true;
|
||||
if (NUMpressed0 == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed0 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed0 == true)
|
||||
if (GetAsyncKeyState(VK_RETURN) & 0x0001)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
NUMpressed0 = false;
|
||||
if (NUMpressed == false)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x0A\x00\x00\x00\x90", 6, true);
|
||||
injector::WriteMemoryRaw((0x1A77D + BaseAddress7), "\x90\x90", 2, true);
|
||||
NUMpressed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GetAsyncKeyState(VK_RETURN) & 0x0001)
|
||||
{
|
||||
if (NUMpressed == false)
|
||||
else
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x0A\x00\x00\x00\x90", 6, true);
|
||||
injector::WriteMemoryRaw((0x1A77D + BaseAddress7), "\x90\x90", 2, true);
|
||||
NUMpressed = true;
|
||||
if (NUMpressed == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
injector::WriteMemoryRaw((0x1A77D + BaseAddress7), "\x7C\x49", 2, true);
|
||||
NUMpressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
injector::WriteMemoryRaw((0x1A77D + BaseAddress7), "\x7C\x49", 2, true);
|
||||
NUMpressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
// buttons see bitwise values in TPui//RawThrills.cs
|
||||
// START
|
||||
@ -254,21 +234,21 @@ DWORD WINAPI InputRT7(LPVOID lpParam)
|
||||
{
|
||||
injector::WriteMemory<BYTE>((keyboardBuffer + 4 * 0x00), 2, true);
|
||||
if (NUMpressed == false)
|
||||
{
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\xB8\x0A\x00\x00\x00\x90", 6, true);
|
||||
injector::WriteMemoryRaw((0x1A77D + BaseAddress7), "\x90\x90", 2, true);
|
||||
NUMpressed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NUMpressed == true)
|
||||
{
|
||||
if (NUMpressed == true)
|
||||
{
|
||||
injector::WriteMemoryRaw((0x1A634 + BaseAddress7), "\x8D\x87\x80\xFF\xFE\xFF", 6, true);
|
||||
injector::WriteMemoryRaw((0x1A77D + BaseAddress7), "\x7C\x49", 2, true);
|
||||
NUMpressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST
|
||||
if (*ffbOffset & 0x01)
|
||||
{
|
||||
@ -346,11 +326,11 @@ DWORD WINAPI InputRT7(LPVOID lpParam)
|
||||
injector::WriteMemoryRaw((0x26614 + BaseAddress7), "\x90\x90", 2, true);
|
||||
injector::WriteMemoryRaw((0x2661F + BaseAddress7), "\x90\x90", 2, true);
|
||||
injector::WriteMemoryRaw((0x26638 + BaseAddress7), "\x90\x90", 2, true);
|
||||
|
||||
|
||||
injector::WriteMemoryRaw((0x28BE2 + BaseAddress7), "\x90\x90", 2, true);
|
||||
injector::WriteMemoryRaw((0x28BED + BaseAddress7), "\x90\x90", 2, true);
|
||||
injector::WriteMemoryRaw((0x28C08 + BaseAddress7), "\x90\x90", 2, true);
|
||||
|
||||
|
||||
injector::WriteMemoryRaw((0x2A5A4 + BaseAddress7), "\x90\x90", 2, true);
|
||||
injector::WriteMemoryRaw((0x2A5AF + BaseAddress7), "\x90\x90", 2, true);
|
||||
injector::WriteMemoryRaw((0x2A5C8 + BaseAddress7), "\x90\x90", 2, true);
|
||||
@ -409,16 +389,16 @@ DWORD WINAPI InputRT7(LPVOID lpParam)
|
||||
}
|
||||
|
||||
// WHEEL
|
||||
int iWheel0 = (((float)* ffbOffset2) - 128);
|
||||
int iWheel0 = (((float)*ffbOffset2) - 128);
|
||||
float wheel = (iWheel0 * 0.0078125f);
|
||||
int iWheel = (int)(2047.5 + 2047.5 * wheel);
|
||||
injector::WriteMemory<INT32>(((0x5CA300 + BaseAddress7) + 4 * 0x20), iWheel, true);
|
||||
//// GAS
|
||||
float gas = (float)* ffbOffset3 / 255.0f;
|
||||
float gas = (float)*ffbOffset3 / 255.0f;
|
||||
int iGas = (int)(gas * 4095);
|
||||
injector::WriteMemory<INT32>(((0x5CA300 + BaseAddress7) + 4 * 0x21), iGas, true);
|
||||
//// BRAKE
|
||||
float brake = (float)* ffbOffset4 / 255.0f;
|
||||
float brake = (float)*ffbOffset4 / 255.0f;
|
||||
int iBrake = (int)(brake * 4095);
|
||||
injector::WriteMemory<INT32>(((0x5CA300 + BaseAddress7) + 4 * 0x22), iBrake, true);
|
||||
|
||||
@ -432,103 +412,8 @@ DWORD WINAPI InputRT7(LPVOID lpParam)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI WindowRT7(LPVOID lpParam)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// RIGHT-CLICK MINIMIZES WINDOW
|
||||
if (GetAsyncKeyState(VK_RBUTTON) & 0x8000)
|
||||
{
|
||||
HWND hWndTMP = GetForegroundWindow();
|
||||
if (hWndRT7 == 0)
|
||||
{
|
||||
hWndRT7 = FindWindowA(NULL, "X-Games SnoCross");
|
||||
}
|
||||
if (hWndTMP == hWndRT7)
|
||||
{
|
||||
RECT rect;
|
||||
GetWindowRect(hWndRT7, &rect);
|
||||
int currentwidth = rect.right - rect.left;
|
||||
int currentheight = rect.bottom - rect.top;
|
||||
original_SetWindowPos7(hWndRT7, HWND_BOTTOM, 0, 0, 1366, 768, SWP_NOSIZE);
|
||||
ShowWindow(hWndRT7, SW_MINIMIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL(__stdcall* original_DefWindowProcA7)(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
DWORD WINAPI DefWindowProcART7(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;
|
||||
if (xWindow >= (horizontal7 - 100))
|
||||
xWindow = 0;
|
||||
if (yWindow >= (vertical7 - 100))
|
||||
yWindow = 0;
|
||||
original_SetWindowPos7(hWnd, NULL, xWindow, yWindow, 1366, 768, SWP_NOSIZE | SWP_NOZORDER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return original_DefWindowProcA7(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
DWORD WINAPI CreateWindowExART7(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_CreateWindowExA7(dwExStyle, lpClassName, "X-Games SnoCross", 0x94000000, 0, 0, 1366, 768, hWndParent, hMenu, hInstance, lpParam);
|
||||
}
|
||||
|
||||
DWORD WINAPI SetCursorPosRT7(int X, int Y)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
DWORD WINAPI SetWindowPosRT7(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool windowed = false;
|
||||
|
||||
static InitFunction SnoCrossFunc([]()
|
||||
{
|
||||
MH_Initialize();
|
||||
MH_CreateHookApi(L"user32.dll", "CreateWindowExA", CreateWindowExART7, (void**)& original_CreateWindowExA7);
|
||||
MH_CreateHookApi(L"user32.dll", "SetWindowPos", SetWindowPosRT7, (void**)& original_SetWindowPos7);
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
windowed = true;
|
||||
MH_CreateHookApi(L"user32.dll", "DefWindowProcA", DefWindowProcART7, (void**)& original_DefWindowProcA7);
|
||||
MH_CreateHookApi(L"user32.dll", "SetCursorPos", SetCursorPosRT7, NULL);
|
||||
}
|
||||
|
||||
GetDesktopResolution(horizontal7, vertical7);
|
||||
|
||||
// PATCHING EXE AT RUNTIME (reboots, network, filepath, config, CRC...36DF3D
|
||||
injector::WriteMemoryRaw((0x36DF3D + BaseAddress7), "\x75\x0D", 2, true);
|
||||
injector::WriteMemoryRaw((0x6C7EB + BaseAddress7), "\xF0", 1, true);
|
||||
@ -539,11 +424,30 @@ static InitFunction SnoCrossFunc([]()
|
||||
injector::WriteMemoryRaw((0x70DE0 + BaseAddress7), "\x90\x90", 2, true);
|
||||
injector::WriteMemoryRaw((0x71499 + BaseAddress7), "\xE9\x9A\x00\x00\x00\x90", 6, true);
|
||||
injector::WriteMemoryRaw((0x3783AD + BaseAddress7), "\x31\xC0\x40", 3, true);
|
||||
injector::WriteMemoryRaw((0x3A8F90 + BaseAddress7), "\x2E\x5C\x63\x6F\x70\x73\x32\x2E\x68\x73\x74\x00", 12, true);
|
||||
injector::WriteMemoryRaw((0x3A9D48 + BaseAddress7), "\x2E\x5C\x61\x75\x64\x62\x61\x6B\x00\x00\x00\x00\x61\x75\x64\x69\x74\x73\x00\x00\x2E\x5C\x61\x75\x64\x69\x74\x73\x00", 29, true);
|
||||
injector::WriteMemoryRaw((0x3A9D5C + BaseAddress7), "\x2E\x5C\x41\x75\x64\x69\x74\x4C\x6F\x67\x30\x30\x30\x2E\x74\x78\x74\x00\x00", 19, true);
|
||||
injector::WriteMemoryRaw((0x3ACE14 + BaseAddress7), "\x2E\x5C\x70\x72\x65\x66\x73\x62\x61\x6B\x00\x00\x70\x72\x65\x66\x73\x00\x00\x00\x2E\x5C\x70\x72\x65\x66\x73\x00", 28, true);
|
||||
injector::WriteMemoryRaw((0x3AF5C8 + BaseAddress7), "\x2E\x5C\x6D\x70\x2E\x70\x64\x74\x00", 9, true);
|
||||
injector::WriteMemoryRaw(0x3A8F90 + BaseAddress7, ".\\cops2.hst\0", 12, true);
|
||||
injector::WriteMemoryRaw(0x3A9D48 + BaseAddress7, ".\\audbak\0", 9, true);
|
||||
injector::WriteMemoryRaw(0x3A9D5C + BaseAddress7, ".\\audits\0", 9, true);
|
||||
injector::WriteMemoryRaw(0x3AA054 + BaseAddress7, ".\\AuditLog%.3d.txt\0", 19, true);
|
||||
injector::WriteMemoryRaw(0x3ACE14 + BaseAddress7, ".\\prefsbak\0", 11, true);
|
||||
injector::WriteMemoryRaw(0x3ACE28 + BaseAddress7, ".\\prefs\0", 8, true);
|
||||
injector::WriteMemoryRaw(0x3AF5C8 + BaseAddress7, ".\\mp.pdt\0", 9, true);
|
||||
injector::WriteMemoryRaw(0x3AAB00 + BaseAddress7, ".\\\0", 3, true); // C:\rawart
|
||||
injector::WriteMemoryRaw(0x3AE224 + BaseAddress7, ".\\erlg0000.txt\0", 15, true);
|
||||
injector::WriteMemoryRaw(0x3AE294 + BaseAddress7, ".\\HighScores.html\0", 18, true);
|
||||
injector::WriteMemoryRaw(0x3AAAF0 + BaseAddress7, ".\\version.txt\0", 14, true);
|
||||
injector::WriteMemoryRaw(0x3AB6C0 + BaseAddress7, ".\\1stboot.txt\0", 14, true);
|
||||
injector::WriteMemoryRaw(0x3AE200 + BaseAddress7, ".\\errorlog.txt\0", 15, true);
|
||||
injector::WriteMemoryRaw(0x3AE210 + BaseAddress7, ".\\Minidump_%d.dmp\0", 18, true);
|
||||
injector::WriteMemoryRaw(0x3B03A4 + BaseAddress7, ".\\Minidump\0", 11, true);
|
||||
injector::WriteMemoryRaw(0x3AE268 + BaseAddress7, "%c\\AuditLog%04i.txt\0", 20, true);
|
||||
injector::WriteMemoryRaw(0x3AE23C + BaseAddress7, "%c\\erlg%.4d.txt\0", 16, true);
|
||||
injector::WriteMemoryRaw(0x3AE2B0 + BaseAddress7, "%c\\scores%04i.html\0", 19, true);
|
||||
injector::WriteMemoryRaw(0x3AE280 + BaseAddress7, "%c\\audit%04i.txt\0", 17, true);
|
||||
|
||||
// some %c string fix
|
||||
injector::WriteMemory<BYTE>(0xA2A6A + BaseAddress7, 0x2E, true);
|
||||
injector::WriteMemory<BYTE>(0xA298A + BaseAddress7, 0x2E, true);
|
||||
injector::WriteMemory<BYTE>(0xA2BEA + BaseAddress7, 0x2E, true);
|
||||
|
||||
// REPLACE SPACE KEY WITH ESC TO PREVENT EXITING LEVEL PREMATURELY
|
||||
injector::WriteMemory<BYTE>((0x77328 + BaseAddress7), DIK_ESCAPE, true);
|
||||
@ -553,12 +457,23 @@ static InitFunction SnoCrossFunc([]()
|
||||
|
||||
CreateThread(NULL, 0, InputRT7, NULL, 0, NULL);
|
||||
|
||||
if (windowed)
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
{
|
||||
// NO HIDE CURSOR
|
||||
injector::WriteMemory<BYTE>((0x14A9F + BaseAddress7), 0x01, true);
|
||||
injector::MakeNOP(BaseAddress7 + 0x14B44, 8, true);
|
||||
|
||||
CreateThread(NULL, 0, WindowRT7, NULL, 0, NULL);
|
||||
static const char* title = "OpenParrot - X-Games SnoCross";
|
||||
injector::WriteMemory<DWORD>(BaseAddress7 + 0x14DC5, (DWORD)title, true);
|
||||
|
||||
windowHooks hooks = { 0 };
|
||||
hooks.createWindowExA = BaseAddress7 + 0x3A32F4;
|
||||
hooks.adjustWindowRect = BaseAddress7 + 0x3A332C;
|
||||
hooks.adjustWindowRectEx = BaseAddress7 + 0x3A32F8;
|
||||
hooks.setWindowPos = BaseAddress7 + 0x3A3328;
|
||||
hooks.setCursorPos = BaseAddress7 + 0x3A3300;
|
||||
|
||||
init_windowHooks(&hooks);
|
||||
}
|
||||
|
||||
// MACHINE ID setting
|
||||
@ -601,13 +516,9 @@ static InitFunction SnoCrossFunc([]()
|
||||
// redirect messages.txt
|
||||
injector::WriteMemoryRaw(BaseAddress7 + 0x4A9EF4, "./messages.txt", 14, true);
|
||||
|
||||
// redirect auditlog.txt
|
||||
injector::WriteMemoryRaw(BaseAddress7 + 0x3AA054, ".//AuditLog%.3d.txt", 19, true);
|
||||
|
||||
//graphics crashfix
|
||||
injector::WriteMemory<BYTE>(BaseAddress7 + 0xC7FE2, 0xEB, true);
|
||||
injector::MakeNOP(BaseAddress7 + 0xC7FDB, 2, true);
|
||||
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
}, GameID::SnoCross);
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,9 @@
|
||||
#include "Global.h"
|
||||
#include "Utility/GameDetect.h"
|
||||
#include "Utility/Hooking.Patterns.h"
|
||||
#include <shlwapi.h>
|
||||
|
||||
#pragma comment(lib,"shlwapi.lib")
|
||||
|
||||
#pragma optimize("", off)
|
||||
void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3)
|
||||
@ -66,20 +69,6 @@ DWORD WINAPI QuitGameThread(__in LPVOID lpParameter)
|
||||
|
||||
Sleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI OutputsThread(__in LPVOID lpParameter)
|
||||
{
|
||||
blaster = LoadLibraryA("OutputBlaster.dll");
|
||||
if (blaster)
|
||||
{
|
||||
printf("OutputBlaster loaded!");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Failed to Load OutputBlaster!");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* WINDOW HOOKS */
|
||||
@ -104,8 +93,16 @@ HWND WINAPI CreateWindowExAHk(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWind
|
||||
{
|
||||
dwStyle = g_windowStyle;
|
||||
}
|
||||
if (lpWindowName == NULL)
|
||||
{
|
||||
lpWindowName = lpClassName;
|
||||
dwStyle = g_windowStyle;
|
||||
}
|
||||
// Make window pos centered
|
||||
g_x = (GetSystemMetrics(SM_CXSCREEN) - nWidth) / 2;
|
||||
g_y = (GetSystemMetrics(SM_CYSCREEN) - nHeight) / 2;
|
||||
|
||||
HWND thisWindow = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, g_x, g_y, g_width, g_height, hWndParent, hMenu, hInstance, lpParam);
|
||||
HWND thisWindow = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, g_x, g_y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
||||
|
||||
if (lpWindowName)
|
||||
{
|
||||
@ -120,12 +117,32 @@ HWND WINAPI CreateWindowExWHk(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWi
|
||||
#ifdef _DEBUG
|
||||
info(true, "CreateWindowExWHk called");
|
||||
#endif
|
||||
// Calculate window pos centered
|
||||
g_x = (GetSystemMetrics(SM_CXSCREEN) - nWidth) / 2;
|
||||
g_y = (GetSystemMetrics(SM_CYSCREEN) - nHeight) / 2;
|
||||
|
||||
|
||||
if (GameDetect::currentGame == GameID::SF4 && x != 0 && y != 0)
|
||||
{
|
||||
dwStyle = g_windowStyle;
|
||||
return CreateWindowExW(dwExStyle, lpClassName, L"OpenParrot - Street Fighter IV", dwStyle, x, y, 1280, 720, hWndParent, hMenu, hInstance, lpParam);
|
||||
}
|
||||
else if (GameDetect::currentGame == GameID::SF4 && x == 0 && y == 0)
|
||||
{
|
||||
return CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
||||
}
|
||||
|
||||
if (lpWindowName)
|
||||
{
|
||||
dwStyle = g_windowStyle;
|
||||
}
|
||||
if (lpWindowName == NULL)
|
||||
{
|
||||
lpWindowName = lpClassName;
|
||||
dwStyle = g_windowStyle;
|
||||
}
|
||||
|
||||
HWND thisWindow = CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, g_x, g_y, g_width, g_height, hWndParent, hMenu, hInstance, lpParam);
|
||||
HWND thisWindow = CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, g_x, g_y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
||||
|
||||
if (lpWindowName)
|
||||
{
|
||||
@ -145,15 +162,34 @@ BOOL WINAPI AdjustWindowRectHk(LPRECT lpRect, DWORD dwStyle, BOOL bMenu)
|
||||
return AdjustWindowRect(lpRect, dwStyle, bMenu);
|
||||
}
|
||||
|
||||
BOOL WINAPI AdjustWindowRectExHk(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
info(true, "AdjustWindowRectExHk called");
|
||||
#endif
|
||||
dwStyle = g_windowStyle;
|
||||
dwExStyle = 0;
|
||||
|
||||
return AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
|
||||
}
|
||||
|
||||
BOOL WINAPI SetWindowPosHk(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
info(true, "SetWindowPosHk called");
|
||||
#endif
|
||||
// Make window pos centered
|
||||
int xPos = (GetSystemMetrics(SM_CXSCREEN) - cx) / 2;
|
||||
int yPos = (GetSystemMetrics(SM_CYSCREEN) - cy) / 2;
|
||||
|
||||
if (hwndWindowA == hWnd || hwndWindowW == hWnd)
|
||||
{
|
||||
X = g_x;
|
||||
Y = g_y;
|
||||
X = xPos;
|
||||
Y = yPos;
|
||||
}
|
||||
if (hWndInsertAfter == HWND_TOPMOST)
|
||||
{
|
||||
hWndInsertAfter = HWND_TOP;
|
||||
}
|
||||
|
||||
return SetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
|
||||
@ -169,11 +205,31 @@ LONG __stdcall ChangeDisplaySettingsHk(DEVMODEA *lpDevMode, DWORD dwFlags)
|
||||
return ChangeDisplaySettingsA(lpDevMode, dwFlags);
|
||||
}
|
||||
|
||||
LONG __stdcall ChangeDisplaySettingsExWHk(LPCWSTR lpszDeviceName, DEVMODEW* lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
info(true, "ChangeDisplaySettingsExWHk called");
|
||||
#endif
|
||||
lpDevMode = NULL; // retain original changes instead of applying modified values
|
||||
|
||||
return ChangeDisplaySettingsExW(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam);
|
||||
}
|
||||
|
||||
BOOL WINAPI UpdateWindowHk(HWND hWnd)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL WINAPI ClipCursorHk(const RECT* lpRect)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL WINAPI SetCursorPosHk(int X, int Y)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void init_windowHooks(windowHooks* data)
|
||||
{
|
||||
g_windowStyle = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
|
||||
@ -199,6 +255,11 @@ void init_windowHooks(windowHooks* data)
|
||||
*(BOOL*)data->adjustWindowRect = (BOOL)AdjustWindowRectHk;
|
||||
}
|
||||
|
||||
if (data->adjustWindowRectEx != NULL)
|
||||
{
|
||||
*(BOOL*)data->adjustWindowRectEx = (BOOL)AdjustWindowRectExHk;
|
||||
}
|
||||
|
||||
if (data->setWindowPos != NULL)
|
||||
{
|
||||
*(BOOL*)data->setWindowPos = (BOOL)SetWindowPosHk;
|
||||
@ -209,20 +270,93 @@ void init_windowHooks(windowHooks* data)
|
||||
*(LONG*)data->changeDisplaySettings = (LONG)ChangeDisplaySettingsHk;
|
||||
}
|
||||
|
||||
if (data->changeDisplaySettingsExW != NULL)
|
||||
{
|
||||
*(LONG*)data->changeDisplaySettingsExW = (LONG)ChangeDisplaySettingsExWHk;
|
||||
}
|
||||
|
||||
if (data->updateWindow != NULL)
|
||||
{
|
||||
*(BOOL*)data->updateWindow = (BOOL)UpdateWindowHk;
|
||||
}
|
||||
|
||||
if (data->clipCursor != NULL)
|
||||
{
|
||||
*(BOOL*)data->clipCursor = (BOOL)ClipCursorHk;
|
||||
}
|
||||
|
||||
if (data->setCursorPos != NULL)
|
||||
{
|
||||
*(BOOL*)data->setCursorPos = (BOOL)SetCursorPosHk;
|
||||
}
|
||||
}
|
||||
/* END WINDOW HOOKS */
|
||||
|
||||
DWORD FetchDwordInformation(const char* setting, const char* subkey, DWORD defaultValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
int value = atol(config[setting][subkey].c_str());
|
||||
|
||||
if (value == NULL)
|
||||
return defaultValue;
|
||||
|
||||
return value;
|
||||
}
|
||||
catch (int e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
static InitFunction globalFunc([]()
|
||||
{
|
||||
hook::pattern::InitializeHints();
|
||||
CreateThread(NULL, 0, QuitGameThread, NULL, 0, NULL);
|
||||
if (ToBool(config["General"]["Enable Outputs"]))
|
||||
{
|
||||
CreateThread(NULL, 0, OutputsThread, NULL, 0, NULL);
|
||||
{
|
||||
blaster = LoadLibraryA("OutputBlaster.dll");
|
||||
if (blaster)
|
||||
{
|
||||
printf("OutputBlaster loaded!");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Failed to Load OutputBlaster!");
|
||||
}
|
||||
}
|
||||
|
||||
if (ToBool(config["Score"]["Enable Submission (Patreon Only)"]))
|
||||
{
|
||||
static char buf[MAX_PATH];
|
||||
HMODULE hMod;
|
||||
#if defined(_M_IX86)
|
||||
hMod = LoadLibrary(L"OpenParrot.dll");
|
||||
#else
|
||||
hMod = LoadLibrary(L"OpenParrot64.dll");
|
||||
#endif
|
||||
GetModuleFileNameA(hMod, buf, MAX_PATH);
|
||||
PathRemoveFileSpecA(buf);
|
||||
PathAppendA(buf, (".."));
|
||||
#if defined(_M_IX86)
|
||||
strcat(buf, "\\TeknoParrot\\ScoreSubmission.dll");
|
||||
#else
|
||||
strcat(buf, "\\TeknoParrot\\ScoreSubmission64.dll");
|
||||
#endif
|
||||
HMODULE hModA = LoadLibraryA(buf);
|
||||
|
||||
if (hModA)
|
||||
{
|
||||
printf("Score Submission loaded!");
|
||||
void(*fn)() = (void(*)())GetProcAddress(hModA, "Score_Submit_Init");
|
||||
fn();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Failed to load Score Submission!");
|
||||
}
|
||||
}
|
||||
}, GameID::Global);
|
||||
#pragma optimize("", on)
|
@ -2,15 +2,20 @@
|
||||
|
||||
BOOL WINAPI ReadFileHooked(_In_ HANDLE hFile, _Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead, _Inout_opt_ LPOVERLAPPED lpOverlapped);
|
||||
void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3);
|
||||
DWORD FetchDwordInformation(const char* setting, const char* subkey, DWORD defaultValue);
|
||||
|
||||
struct windowHooks
|
||||
{
|
||||
int createWindowExA;
|
||||
int createWindowExW;
|
||||
int adjustWindowRect;
|
||||
int adjustWindowRectEx;
|
||||
int setWindowPos;
|
||||
int changeDisplaySettings;
|
||||
int changeDisplaySettingsExW;
|
||||
int updateWindow;
|
||||
int clipCursor;
|
||||
int setCursorPos;
|
||||
};
|
||||
|
||||
void init_windowHooks(windowHooks* data);
|
||||
|
@ -775,278 +775,29 @@ BOOL __stdcall CloseHandleWrap(HANDLE hObject)
|
||||
static char moveBuf[256];
|
||||
LPCSTR ParseFileNamesA(LPCSTR lpFileName)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::HyperStreetFighterII)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\3", 4))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[3] == '3')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::StreetFigherZero3)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\c", 4))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[3] == 'c')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::StreetFighter3rdStrike)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\9", 4))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[3] == '9')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::RumbleFish2)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\eb342", 8))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[3] == 'e')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::KOF98Nesica)
|
||||
{
|
||||
if (!strncmp(lpFileName, "d:/SettingKOF98UM", 17) || !strncmp(lpFileName, "d:/RankingKOF98UM", 17) || !strncmp(lpFileName, "d:/CoinFileKOF98UM", 18))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
if (!strncmp(lpFileName, "SettingKOF98UM*.txt", 19) || !strncmp(lpFileName, "RankingKOF98UM*.txt", 19) || !strncmp(lpFileName, "CoinFileKOF98UM*.txt", 20))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName);
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::CrimzonClover)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\save\\*.dat", 13) || !strncmp(lpFileName, "D:\\save", 7) || !strncmp(lpFileName, "D:\\save\\config", 14) || !strncmp(lpFileName, "D:\\save\\bkeep", 13) || !strncmp(lpFileName, "D:\\save\\score", 13))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::VampireSavior)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\0343d7a98baf803c268e7ed73239464b", 35))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[3] == '0')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::ChaosCode)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:/ChaosCode/save/TYPEX2_RECORD.rcd", 35) || !strncmp(lpFileName, "D:/ChaosCode/save/TYPEX2_SETTING.rcd", 36) || !strncmp(lpFileName, "D:/ChaosCode/save/", 18) || !strncmp(lpFileName, "D:/ChaosCode/", 14))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::RaidenIVNesica)
|
||||
{
|
||||
if (!strncmp(lpFileName, "d:\\income.log", 13) || !strncmp(lpFileName, "D:\\setting.dat", 14) || !strncmp(lpFileName, "D:\\hiscore.dat", 14))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::SenkoNoRondeDuoNesica)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\0bd4d39aff8d7219f92f72451f642c2f", 35))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[4] == 'b')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::SkullGirls)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\sg_conf_", 11))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::TroubleWitchesNesica)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\Save", 7))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::Yatagarasu)
|
||||
{
|
||||
if (!strncmp(lpFileName, "D:\\b2cfd825e375395ce05629616d881045", 35))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::Exception)
|
||||
{
|
||||
if (!strncmp(lpFileName, "d:\\game0000.ini", 15) || !strncmp(lpFileName, "d:/ranking", 10) || !strncmp(lpFileName, "d:/log", 6))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
if (!strncmp(lpFileName, "stdout.txt", 10) || !strncmp(lpFileName, "stderr.txt", 10))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (!strncmp(lpFileName, "stdout.txt", 10))
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", "stdout.txt");
|
||||
}
|
||||
if (!strncmp(lpFileName, "stderr.txt", 10))
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", "stderr.txt");
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::KOF2002)
|
||||
{
|
||||
if (!strncmp(lpFileName, "d:/Setting", 10) || !strncmp(lpFileName, "d:/CoinFile", 11) || !strncmp(lpFileName, "d:/Ranking", 11))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
if (!strncmp(lpFileName, "Setting*.txt", 12) || !strncmp(lpFileName, "Ranking*.txt", 12) || !strncmp(lpFileName, "CoinFile*.txt", 13))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName);
|
||||
|
||||
return moveBuf;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (!strncmp(lpFileName, "D:", 2) || !strncmp(lpFileName, "d:", 2))
|
||||
{
|
||||
memset(moveBuf, 0, 256);
|
||||
if(lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
char pathRoot[MAX_PATH];
|
||||
GetModuleFileNameA(GetModuleHandle(nullptr), pathRoot, _countof(pathRoot));
|
||||
strrchr(pathRoot, '\\')[0] = '\0';
|
||||
|
||||
sprintf(moveBuf, ".\\OpenParrot\\%s", lpFileName + 3);
|
||||
#ifdef _DEBUG
|
||||
info(true, "PathRoot: %s", pathRoot);
|
||||
info(true, "ParseFileNamesA: %s", lpFileName + 3);
|
||||
info(true, "ParseFileNamesA movBuf: %s", moveBuf);
|
||||
#endif
|
||||
|
||||
if(!strncmp(moveBuf + 13, pathRoot + 3, 5))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
info(true, "!!!!!!!!!!!NO REDIRECT!!!!!!!!!!!!");
|
||||
#endif
|
||||
return lpFileName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1062,277 +813,31 @@ LPCSTR ParseFileNamesA(LPCSTR lpFileName)
|
||||
static wchar_t moveBufW[256];
|
||||
LPCWSTR ParseFileNamesW(LPCWSTR lpFileName)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::HyperStreetFighterII)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\3", 4))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[3] == '3')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::StreetFigherZero3)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\c", 4))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[3] == 'c')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::StreetFighter3rdStrike)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\9", 4))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[3] == '9')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::RumbleFish2)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\eb342", 8))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[3] == 'e')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::KOF98Nesica)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"d:/SettingKOF98UM", 17) || !wcsncmp(lpFileName, L"d:/RankingKOF98UM", 17) || !wcsncmp(lpFileName, L"d:/CoinFileKOF98UM", 18))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
if (!wcsncmp(lpFileName, L"SettingKOF98UM*.txt", 19) || !wcsncmp(lpFileName, L"RankingKOF98UM*.txt", 19) || !wcsncmp(lpFileName, L"CoinFileKOF98UM*.txt", 20))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName);
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::CrimzonClover)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\save\\*.dat", 13) || !wcsncmp(lpFileName, L"D:\\save", 7) || !wcsncmp(lpFileName, L"D:\\save\\config", 14) || !wcsncmp(lpFileName, L"D:\\save\\bkeep", 13) || !wcsncmp(lpFileName, L"D:\\save\\score", 13))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::VampireSavior)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\0343d7a98baf803c268e7ed73239464b", 35))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[3] == '0')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::ChaosCode)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:/ChaosCode/save/TYPEX2_RECORD.rcd", 35) || !wcsncmp(lpFileName, L"D:/ChaosCode/save/TYPEX2_SETTING.rcd", 36) || !wcsncmp(lpFileName, L"D:/ChaosCode/save/TYPEX2_SETTING.rcd", 36) || !wcsncmp(lpFileName, L"D:/ChaosCode/save/", 18) || !wcsncmp(lpFileName, L"D:/ChaosCode/", 14))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::RaidenIVNesica)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"d:\\income.log", 13) || !wcsncmp(lpFileName, L"D:\\setting.dat", 14) || !wcsncmp(lpFileName, L"D:\\hiscore.dat", 14))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::SenkoNoRondeDuoNesica)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\0bd4d39aff8d7219f92f72451f642c2f", 35))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[4] == 'b')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::SkullGirls)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\sg_conf_", 11))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::TroubleWitchesNesica)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\Save", 7))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::Yatagarasu)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"D:\\b2cfd825e375395ce05629616d881045", 35))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::Exception)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"d:\\game0000.ini", 15) || !wcsncmp(lpFileName, L"d:/ranking", 10) || !wcsncmp(lpFileName, L"d:/log", 6))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
if (!wcsncmp(lpFileName, L"stdout.txt", 10) || !wcsncmp(lpFileName, L"stderr.txt", 10))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (!wcsncmp(lpFileName, L"stdout.txt", 10))
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", L"stdout.txt");
|
||||
}
|
||||
if (!wcsncmp(lpFileName, L"stderr.txt", 10))
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", L"stderr.txt");
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::KOF2002)
|
||||
{
|
||||
if (!wcsncmp(lpFileName, L"d:/Setting", 10) || !wcsncmp(lpFileName, L"d:/CoinFile", 11) || !wcsncmp(lpFileName, L"d:/Ranking", 10))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName + 3);
|
||||
}
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
if (!wcsncmp(lpFileName, L"Setting*.txt", 12) || !wcsncmp(lpFileName, L"Ranking*.txt", 12) || !wcsncmp(lpFileName, L"CoinFile*.txt", 13))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%s", lpFileName);
|
||||
|
||||
return moveBufW;
|
||||
}
|
||||
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
if (!wcsncmp(lpFileName, L"D:", 2) || !wcsncmp(lpFileName, L"d:", 2))
|
||||
{
|
||||
memset(moveBufW, 0, 256);
|
||||
if (lpFileName[2] == '\\' || lpFileName[2] == '/')
|
||||
{
|
||||
wchar_t pathRootW[MAX_PATH];
|
||||
GetModuleFileNameW(GetModuleHandle(nullptr), pathRootW, _countof(pathRootW));
|
||||
|
||||
wcsrchr(pathRootW, L'\\')[0] = L'\0';
|
||||
|
||||
swprintf(moveBufW, L".\\OpenParrot\\%ls", lpFileName + 3);
|
||||
|
||||
#ifdef _DEBUG
|
||||
info(true, "PathRootW: %ls", pathRootW);
|
||||
info(true, "ParseFileNamesW: %ls", lpFileName + 3);
|
||||
info(true, "ParseFileNamesW movBufW: %ls", moveBufW);
|
||||
#endif
|
||||
|
||||
if (!wcsncmp(moveBufW + 13, pathRootW + 3, 5))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
info(true, "!!!!!!!!!!!NO REDIRECT_W!!!!!!!!!!!!");
|
||||
#endif
|
||||
return lpFileName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1370,16 +875,16 @@ HANDLE __stdcall CreateFileAWrap(LPCSTR lpFileName,
|
||||
return hConnection;
|
||||
}
|
||||
|
||||
if(GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
{
|
||||
return g_origCreateFileA(lpFileName,
|
||||
dwDesiredAccess,
|
||||
dwShareMode,
|
||||
lpSecurityAttributes,
|
||||
dwCreationDisposition,
|
||||
dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
}
|
||||
//if(GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
//{
|
||||
// return g_origCreateFileA(lpFileName,
|
||||
// dwDesiredAccess,
|
||||
// dwShareMode,
|
||||
// lpSecurityAttributes,
|
||||
// dwCreationDisposition,
|
||||
// dwFlagsAndAttributes,
|
||||
// hTemplateFile);
|
||||
//}
|
||||
|
||||
return g_origCreateFileA(ParseFileNamesA(lpFileName),
|
||||
dwDesiredAccess,
|
||||
@ -1414,16 +919,16 @@ HANDLE __stdcall CreateFileWWrap(LPCWSTR lpFileName,
|
||||
return hConnection;
|
||||
}
|
||||
|
||||
if (GameDetect::currentGame == GameID::GrooveCoaster2 || GameDetect::currentGame == GameID::KOFXIIIClimax)
|
||||
{
|
||||
return g_origCreateFileW(lpFileName,
|
||||
dwDesiredAccess,
|
||||
dwShareMode,
|
||||
lpSecurityAttributes,
|
||||
dwCreationDisposition,
|
||||
dwFlagsAndAttributes,
|
||||
hTemplateFile);
|
||||
}
|
||||
//if (GameDetect::currentGame == GameID::GrooveCoaster2 || GameDetect::currentGame == GameID::KOFXIIIClimax)
|
||||
//{
|
||||
// return g_origCreateFileW(lpFileName,
|
||||
// dwDesiredAccess,
|
||||
// dwShareMode,
|
||||
// lpSecurityAttributes,
|
||||
// dwCreationDisposition,
|
||||
// dwFlagsAndAttributes,
|
||||
// hTemplateFile);
|
||||
//}
|
||||
|
||||
return g_origCreateFileW(ParseFileNamesW(lpFileName),
|
||||
dwDesiredAccess,
|
||||
@ -1437,10 +942,10 @@ HANDLE __stdcall CreateFileWWrap(LPCWSTR lpFileName,
|
||||
static DWORD(__stdcall *g_origGetFileAttributesA)(LPCSTR lpFileName);
|
||||
static DWORD __stdcall GetFileAttributesAWrap(LPCSTR lpFileName)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
{
|
||||
return g_origGetFileAttributesA(lpFileName);
|
||||
}
|
||||
//if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
//{
|
||||
// return g_origGetFileAttributesA(lpFileName);
|
||||
//}
|
||||
|
||||
return g_origGetFileAttributesA(ParseFileNamesA(lpFileName));
|
||||
}
|
||||
@ -1448,10 +953,10 @@ static DWORD __stdcall GetFileAttributesAWrap(LPCSTR lpFileName)
|
||||
static DWORD(__stdcall *g_origGetFileAttributesW)(LPCWSTR lpFileName);
|
||||
static DWORD __stdcall GetFileAttributesWWrap(LPCWSTR lpFileName)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
{
|
||||
return g_origGetFileAttributesW(lpFileName);
|
||||
}
|
||||
//if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
//{
|
||||
// return g_origGetFileAttributesW(lpFileName);
|
||||
//}
|
||||
|
||||
return g_origGetFileAttributesW(ParseFileNamesW(lpFileName));
|
||||
}
|
||||
@ -1462,10 +967,10 @@ static BOOL __stdcall CreateDirectoryAWrap(
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes
|
||||
)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
{
|
||||
return g_origCreateDirectoryA(lpPathName, lpSecurityAttributes);
|
||||
}
|
||||
//if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
//{
|
||||
// return g_origCreateDirectoryA(lpPathName, lpSecurityAttributes);
|
||||
//}
|
||||
|
||||
return g_origCreateDirectoryA(ParseFileNamesA(lpPathName), lpSecurityAttributes);
|
||||
}
|
||||
@ -1476,10 +981,10 @@ static BOOL __stdcall CreateDirectoryWWrap(
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes
|
||||
)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
{
|
||||
return g_origCreateDirectoryW(lpPathName, lpSecurityAttributes);
|
||||
}
|
||||
//if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
//{
|
||||
// return g_origCreateDirectoryW(lpPathName, lpSecurityAttributes);
|
||||
//}
|
||||
|
||||
return g_origCreateDirectoryW(ParseFileNamesW(lpPathName), lpSecurityAttributes);
|
||||
}
|
||||
@ -1490,10 +995,10 @@ static HANDLE __stdcall FindFirstFileAWrap(
|
||||
LPWIN32_FIND_DATAA lpFindFileData
|
||||
)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
{
|
||||
return g_origFindFirstFileA(lpFileName, lpFindFileData);
|
||||
}
|
||||
//if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
//{
|
||||
// return g_origFindFirstFileA(lpFileName, lpFindFileData);
|
||||
//}
|
||||
|
||||
return g_origFindFirstFileA(ParseFileNamesA(lpFileName), lpFindFileData);
|
||||
}
|
||||
@ -1504,10 +1009,10 @@ static HANDLE __stdcall FindFirstFileWWrap(
|
||||
LPWIN32_FIND_DATAA lpFindFileData
|
||||
)
|
||||
{
|
||||
if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
{
|
||||
return g_origFindFirstFileW(lpFileName, lpFindFileData);
|
||||
}
|
||||
//if (GameDetect::currentGame == GameID::GrooveCoaster2)
|
||||
//{
|
||||
// return g_origFindFirstFileW(lpFileName, lpFindFileData);
|
||||
//}
|
||||
|
||||
return g_origFindFirstFileW(ParseFileNamesW(lpFileName), lpFindFileData);
|
||||
}
|
||||
|
@ -13,4 +13,5 @@ enum class X2Type {
|
||||
MB4,
|
||||
Wontertainment,
|
||||
BG4_Eng,
|
||||
BlazBlue
|
||||
};
|
@ -24,6 +24,72 @@ T HookVtableFunction(T* functionPtr, T target)
|
||||
return old;
|
||||
}
|
||||
|
||||
static HRESULT(WINAPI* g_oldPresent)(IDirect3DDevice8* self, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion);
|
||||
|
||||
HRESULT WINAPI PresentWrap(IDirect3DDevice8* self, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
|
||||
{
|
||||
if (ToBool(config["General"]["Framelimiter"]))
|
||||
{
|
||||
// https://github.com/ThirteenAG/d3d9-wrapper/blob/master/source/d3d9.cpp
|
||||
float fFPSLimit = 60.0;
|
||||
static LARGE_INTEGER PerformanceCount1;
|
||||
static LARGE_INTEGER PerformanceCount2;
|
||||
static bool bOnce1 = false;
|
||||
static double targetFrameTime = 1000.0 / fFPSLimit;
|
||||
static double t = 0.0;
|
||||
static DWORD i = 0;
|
||||
|
||||
if (!bOnce1)
|
||||
{
|
||||
bOnce1 = true;
|
||||
QueryPerformanceCounter(&PerformanceCount1);
|
||||
PerformanceCount1.QuadPart = PerformanceCount1.QuadPart >> i;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
QueryPerformanceCounter(&PerformanceCount2);
|
||||
if (t == 0.0)
|
||||
{
|
||||
LARGE_INTEGER PerformanceCount3;
|
||||
static bool bOnce2 = false;
|
||||
|
||||
if (!bOnce2)
|
||||
{
|
||||
bOnce2 = true;
|
||||
QueryPerformanceFrequency(&PerformanceCount3);
|
||||
i = 0;
|
||||
t = 1000.0 / (double)PerformanceCount3.QuadPart;
|
||||
auto v = t * 2147483648.0;
|
||||
if (60000.0 > v)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
++i;
|
||||
v *= 2.0;
|
||||
t *= 2.0;
|
||||
if (60000.0 <= v)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SleepEx(0, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (((double)((PerformanceCount2.QuadPart >> i) - PerformanceCount1.QuadPart) * t) >= targetFrameTime)
|
||||
break;
|
||||
|
||||
SleepEx(0, 1);
|
||||
}
|
||||
QueryPerformanceCounter(&PerformanceCount2);
|
||||
PerformanceCount1.QuadPart = PerformanceCount2.QuadPart >> i;
|
||||
return g_oldPresent(self, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
|
||||
}
|
||||
else
|
||||
return g_oldPresent(self, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
|
||||
}
|
||||
|
||||
static HRESULT(WINAPI* g_oldReset)(IDirect3DDevice8* self, D3DPRESENT_PARAMETERS* pPresentationParameters);
|
||||
|
||||
HRESULT WINAPI ResetWrap(IDirect3DDevice8* self, D3DPRESENT_PARAMETERS* pPresentationParameters)
|
||||
@ -58,12 +124,16 @@ HRESULT WINAPI CreateDeviceWrap(IDirect3D8* self, UINT Adapter, D3DDEVTYPE Devic
|
||||
}
|
||||
if (swShaderHack)
|
||||
BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||||
|
||||
HRESULT hr = g_oldCreateDevice(self, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
|
||||
|
||||
if (*ppReturnedDeviceInterface)
|
||||
{
|
||||
auto old = HookVtableFunction(&(*ppReturnedDeviceInterface)->lpVtbl->Reset, ResetWrap);
|
||||
g_oldReset = (old) ? old : g_oldReset;
|
||||
|
||||
auto old2 = HookVtableFunction(&(*ppReturnedDeviceInterface)->lpVtbl->Present, PresentWrap);
|
||||
g_oldPresent = (old2) ? old2 : g_oldPresent;
|
||||
}
|
||||
|
||||
return hr;
|
||||
@ -104,7 +174,7 @@ static InitFunction initFunc([]()
|
||||
if (swShaderHack)
|
||||
InitD3D8WindowHook();
|
||||
}
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
if (ToBool(config["General"]["Windowed"]) || ToBool(config["General"]["Framelimiter"]))
|
||||
{
|
||||
InitD3D8WindowHook();
|
||||
}
|
||||
|
@ -21,6 +21,72 @@ T HookVtableFunction(T* functionPtr, T target)
|
||||
return old;
|
||||
}
|
||||
|
||||
static HRESULT(WINAPI* g_oldPresent)(IDirect3DDevice9* self, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion);
|
||||
|
||||
HRESULT WINAPI PresentWrap(IDirect3DDevice9* self, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
|
||||
{
|
||||
if (ToBool(config["General"]["Framelimiter"]))
|
||||
{
|
||||
// https://github.com/ThirteenAG/d3d9-wrapper/blob/master/source/d3d9.cpp
|
||||
float fFPSLimit = 60.0;
|
||||
static LARGE_INTEGER PerformanceCount1;
|
||||
static LARGE_INTEGER PerformanceCount2;
|
||||
static bool bOnce1 = false;
|
||||
static double targetFrameTime = 1000.0 / fFPSLimit;
|
||||
static double t = 0.0;
|
||||
static DWORD i = 0;
|
||||
|
||||
if (!bOnce1)
|
||||
{
|
||||
bOnce1 = true;
|
||||
QueryPerformanceCounter(&PerformanceCount1);
|
||||
PerformanceCount1.QuadPart = PerformanceCount1.QuadPart >> i;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
QueryPerformanceCounter(&PerformanceCount2);
|
||||
if (t == 0.0)
|
||||
{
|
||||
LARGE_INTEGER PerformanceCount3;
|
||||
static bool bOnce2 = false;
|
||||
|
||||
if (!bOnce2)
|
||||
{
|
||||
bOnce2 = true;
|
||||
QueryPerformanceFrequency(&PerformanceCount3);
|
||||
i = 0;
|
||||
t = 1000.0 / (double)PerformanceCount3.QuadPart;
|
||||
auto v = t * 2147483648.0;
|
||||
if (60000.0 > v)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
++i;
|
||||
v *= 2.0;
|
||||
t *= 2.0;
|
||||
if (60000.0 <= v)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SleepEx(0, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (((double)((PerformanceCount2.QuadPart >> i) - PerformanceCount1.QuadPart) * t) >= targetFrameTime)
|
||||
break;
|
||||
|
||||
SleepEx(0, 1);
|
||||
}
|
||||
QueryPerformanceCounter(&PerformanceCount2);
|
||||
PerformanceCount1.QuadPart = PerformanceCount2.QuadPart >> i;
|
||||
return g_oldPresent(self, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
|
||||
}
|
||||
else
|
||||
return g_oldPresent(self, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
|
||||
}
|
||||
|
||||
static HRESULT(WINAPI* g_oldReset)(IDirect3DDevice9* self, D3DPRESENT_PARAMETERS* pPresentationParameters);
|
||||
|
||||
HRESULT WINAPI ResetWrap(IDirect3DDevice9* self, D3DPRESENT_PARAMETERS* pPresentationParameters)
|
||||
@ -58,6 +124,9 @@ HRESULT WINAPI CreateDeviceWrap(IDirect3D9* self, UINT Adapter, D3DDEVTYPE Devic
|
||||
{
|
||||
auto old = HookVtableFunction(&(*ppReturnedDeviceInterface)->lpVtbl->Reset, ResetWrap);
|
||||
g_oldReset = (old) ? old : g_oldReset;
|
||||
|
||||
auto old2 = HookVtableFunction(&(*ppReturnedDeviceInterface)->lpVtbl->Present, PresentWrap);
|
||||
g_oldPresent = (old2) ? old2 : g_oldPresent;
|
||||
}
|
||||
|
||||
return hr;
|
||||
@ -90,7 +159,7 @@ static InitFunction initFunc([]()
|
||||
{
|
||||
InitD3D9WindowHook();
|
||||
}
|
||||
if (ToBool(config["General"]["Windowed"]))
|
||||
if (ToBool(config["General"]["Windowed"]) || ToBool(config["General"]["Framelimiter"]))
|
||||
{
|
||||
InitD3D9WindowHook();
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ int iround(double num) {
|
||||
return (num > 0.0) ? (int)floor(num + 0.5) : (int)ceil(num - 0.5);
|
||||
}
|
||||
|
||||
extern void GHAInputs();
|
||||
|
||||
extern int* ffbOffset;
|
||||
extern int* ffbOffset2;
|
||||
extern int* ffbOffset3;
|
||||
@ -63,6 +65,10 @@ extern int* ffbOffset4;
|
||||
extern int* ffbOffset5;
|
||||
extern int* ffbOffset6;
|
||||
|
||||
extern int FFBDeadzoneMaxMin;
|
||||
|
||||
XINPUT_GAMEPAD gamepadState = { 0 };
|
||||
|
||||
DWORD WINAPI XInputGetState
|
||||
(
|
||||
__in DWORD dwUserIndex, // Index of the gamer associated with the device
|
||||
@ -75,42 +81,13 @@ DWORD WINAPI XInputGetState
|
||||
}
|
||||
if (controllerInit && dwUserIndex == 0)
|
||||
{
|
||||
XINPUT_GAMEPAD gamepadState = { 0 };
|
||||
|
||||
if (GameDetect::currentGame == GameID::Daytona3 || GameDetect::currentGame == GameID::PokkenTournament)
|
||||
{
|
||||
gamepadState.wButtons |= *ffbOffset;
|
||||
}
|
||||
else if (GameDetect::currentGame == GameID::GHA)
|
||||
{
|
||||
gamepadState.wButtons = 0;
|
||||
gamepadState.bLeftTrigger = 0;
|
||||
gamepadState.bRightTrigger = 0;
|
||||
// START KEY MACRO (only on ATTRACT SCREEN)
|
||||
if (*ffbOffset == XINPUT_GAMEPAD_START)
|
||||
{
|
||||
gamepadState.wButtons = 0xF000;
|
||||
gamepadState.bLeftTrigger = 255;
|
||||
gamepadState.bRightTrigger = 255;
|
||||
}
|
||||
// GREEN KEY MACRO
|
||||
if (*ffbOffset == XINPUT_GAMEPAD_X)
|
||||
{
|
||||
gamepadState.bLeftTrigger = 255;
|
||||
}
|
||||
else gamepadState.bLeftTrigger = 0;
|
||||
// BLUE KEY MACRO
|
||||
if (*ffbOffset == XINPUT_GAMEPAD_Y)
|
||||
{
|
||||
gamepadState.bRightTrigger = 255;
|
||||
}
|
||||
else gamepadState.bRightTrigger = 0;
|
||||
// OTHER KEYs PASSTHROUGH
|
||||
if (*ffbOffset == XINPUT_GAMEPAD_DPAD_UP || *ffbOffset == XINPUT_GAMEPAD_DPAD_DOWN || *ffbOffset == XINPUT_GAMEPAD_DPAD_LEFT || *ffbOffset == XINPUT_GAMEPAD_DPAD_RIGHT || *ffbOffset == XINPUT_GAMEPAD_LEFT_SHOULDER || *ffbOffset == XINPUT_GAMEPAD_RIGHT_SHOULDER || *ffbOffset == XINPUT_GAMEPAD_A || *ffbOffset == XINPUT_GAMEPAD_B)
|
||||
{
|
||||
gamepadState.wButtons |= *ffbOffset;
|
||||
}
|
||||
else gamepadState.wButtons = 0;
|
||||
GHAInputs();
|
||||
}
|
||||
else if (GameDetect::currentGame == GameID::JLeague)
|
||||
{
|
||||
@ -164,11 +141,12 @@ DWORD WINAPI XInputGetState
|
||||
if (GameDetect::currentGame == GameID::Daytona3)
|
||||
{
|
||||
gamepadState.bRightTrigger = daytonaPressStart ? 0xFF : 0x00;
|
||||
|
||||
if (*ffbOffset2 < 1)
|
||||
{
|
||||
gamepadState.sThumbLX |= 257 - (-(32767 - *ffbOffset2) * 257);
|
||||
}
|
||||
else if ((*ffbOffset2 >= 121) && (*ffbOffset2 <= 133)) //Deadzone for FFB
|
||||
else if ((*ffbOffset2 >= (128 - FFBDeadzoneMaxMin)) && (*ffbOffset2 <= 128 + FFBDeadzoneMaxMin)) //Deadzone for FFB
|
||||
{
|
||||
gamepadState.sThumbLX == 32768;
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ void GameDetect::DetectCurrentGame()
|
||||
break;
|
||||
case 0xf9297ecb: // BlazBlue
|
||||
currentGame = GameID::BlazBlue;
|
||||
X2Type = X2Type::Generic;
|
||||
X2Type = X2Type::BlazBlue;
|
||||
break;
|
||||
case 0xee568daa: // BlazBlue Continuum Shift II
|
||||
currentGame = GameID::BlazBlueCS2;
|
||||
@ -518,7 +518,7 @@ void GameDetect::DetectCurrentGame()
|
||||
isNesica = true;
|
||||
break;
|
||||
case 0x1046a695: //Spica Adventure for NXL (honestly no difference i can find from OG version, X2 emu works fine for it)
|
||||
currentGame = GameID::SpicaAdventure;
|
||||
currentGame = GameID::SpicaAdventureNXL;
|
||||
X2Type = X2Type::Generic;
|
||||
break;
|
||||
case 0xbd516d7b: // KOFXIII Climax
|
||||
@ -562,6 +562,7 @@ void GameDetect::DetectCurrentGame()
|
||||
currentGame = GameID::DirtyDrivin;
|
||||
break;
|
||||
case 0x4D91A27A:
|
||||
case 0x31a4f2d0:
|
||||
currentGame = GameID::SnoCross;
|
||||
break;
|
||||
case 0xbd8c984d: // Battle Gear 4 English Ver (2.03)
|
||||
@ -576,13 +577,13 @@ void GameDetect::DetectCurrentGame()
|
||||
currentGame = GameID::PowerInstinctV;
|
||||
X2Type = X2Type::Generic;
|
||||
break;
|
||||
case 0x6f913049: // Chaos Breaker for NesicaxLive
|
||||
currentGame = GameID::Nesica;
|
||||
case 0xee586431: // Chaos Breaker for NesicaxLive
|
||||
currentGame = GameID::ChaosBreakerNXL;
|
||||
NesicaKey = NesicaKey::None;
|
||||
isNesica = true;
|
||||
break;
|
||||
case 0x486e885c: // Dark Awake - The King Has No Name
|
||||
currentGame = GameID::Nesica;
|
||||
currentGame = GameID::DarkAwake;
|
||||
NesicaKey = NesicaKey::None;
|
||||
isNesica = true;
|
||||
break;
|
||||
|
@ -91,5 +91,8 @@ enum class GameID
|
||||
Exception,
|
||||
KOF2002,
|
||||
BlazBlueCF201,
|
||||
SpicaAdventureNXL,
|
||||
DarkAwake,
|
||||
ChaosBreakerNXL,
|
||||
LinuxEmulation
|
||||
};
|
14
appveyor.yml
14
appveyor.yml
@ -3,6 +3,13 @@ image: Visual Studio 2017
|
||||
configuration: Release
|
||||
# Do not build on tags (GitHub only)
|
||||
skip_tags: true
|
||||
environment:
|
||||
pwe:
|
||||
secure: tIA3WoMvSPVbwjUMlWSdfA==
|
||||
senc:
|
||||
secure: FYTNTbS57pKEMR13yExGybKLsI0YUzT7RsL/+pce4uGABr01RRglP3XN3tB4r/fmHuaW6SjJA4ZnmqK6irnmxQ==
|
||||
cenc:
|
||||
secure: 16yzBwIyf9D/P3WTZnqqL9iZ3kP9WQ0mL1StAbp8Kls=
|
||||
platform:
|
||||
- x64
|
||||
- Win32
|
||||
@ -11,7 +18,10 @@ assembly_info:
|
||||
file: '**\AssemblyInfo.*'
|
||||
assembly_version: '{version}'
|
||||
assembly_file_version: '{version}'
|
||||
assembly_informational_version: '{version}'
|
||||
assembly_informational_version: '{version}'
|
||||
install:
|
||||
- ps: iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1'))
|
||||
- cmd: if "%pwe%" NEQ "" (appveyor-tools\secure-file -decrypt cert.enc -secret %pwe% -salt %senc%)
|
||||
before_build:
|
||||
- cmd: premake5.exe vs2017
|
||||
- ps: >-
|
||||
@ -21,6 +31,8 @@ before_build:
|
||||
|
||||
mv .\OpenParrot\src\OpenParrot2.rc .\OpenParrot\src\OpenParrot.rc
|
||||
|
||||
after_build:
|
||||
- cmd: sign.bat
|
||||
build:
|
||||
project: OpenParrot.sln
|
||||
verbosity: minimal
|
||||
|
16
sign.bat
Normal file
16
sign.bat
Normal file
@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
if "%cenc%"=="" goto end
|
||||
|
||||
IF %PLATFORM%==Win32 (
|
||||
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /t http://timestamp.digicert.com/?alg=sha1 /f "cert" /p %cenc% /d .\build\bin\release\output\OpenParrot.dll .\build\bin\release\output\OpenParrot.dll
|
||||
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /t http://timestamp.digicert.com/?alg=sha1 /f "cert" /p %cenc% /d .\build\bin\release\output\OpenParrotLoader.exe .\build\bin\release\output\OpenParrotLoader.exe
|
||||
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /t http://timestamp.digicert.com/?alg=sha1 /f "cert" /p %cenc% /d .\build\bin\release\output\OpenParrotKonamiLoader.exe .\build\bin\release\output\OpenParrotKonamiLoader.exe) ELSE (IF %PLATFORM%==x64 (
|
||||
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /t http://timestamp.digicert.com/?alg=sha1 /f "cert" /p %cenc% /d .\build\bin\release\output\OpenParrot64.dll .\build\bin\release\output\OpenParrot64.dll
|
||||
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /t http://timestamp.digicert.com/?alg=sha1 /f "cert" /p %cenc% /d .\build\bin\release\output\OpenParrotLoader64.exe .\build\bin\release\output\OpenParrotLoader64.exe
|
||||
)
|
||||
)
|
||||
exit
|
||||
|
||||
:end
|
||||
echo Pull Request
|
||||
exit
|
Loading…
x
Reference in New Issue
Block a user