Add files for version 1.4.0
This commit is contained in:
parent
c470d53a9e
commit
bf87990a5f
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Context.h"
|
||||
#include "IDirect3DVertexBuffer9.h"
|
||||
#include <intrin.h>
|
||||
|
||||
void MainContext::EnableAutoFix()
|
||||
{
|
||||
|
@ -24,6 +25,7 @@ void MainContext::EnableAutoFix()
|
|||
{
|
||||
autofix = FINAL_FANTASY_XIII;
|
||||
PrintLog("AutoFix for \"Final Fantasy XIII\" enabled");
|
||||
FF13_InitializeGameAddresses();
|
||||
}
|
||||
|
||||
if (exe_name == "ffxiii2img.exe")
|
||||
|
@ -35,65 +37,6 @@ void MainContext::EnableAutoFix()
|
|||
}
|
||||
}
|
||||
|
||||
void MainContext::FF13_2_CreateSetFrameRateCodeBlock()
|
||||
{
|
||||
const int blockSize = 31;
|
||||
FF13_2_SET_FRAME_RATE_INJECTED_CODE = new byte[blockSize];
|
||||
|
||||
ChangeMemoryProtectionToReadWriteExecute(FF13_2_SET_FRAME_RATE_INJECTED_CODE, blockSize);
|
||||
|
||||
float frameRateConfigValue = (float)context.config.GetFFXIIIIngameFrameRateLimit();
|
||||
if (AreAlmostTheSame(frameRateConfigValue, -1.0F) || frameRateConfigValue > FF13_2_MAX_FRAME_CAP) {
|
||||
ff13_2_targetFrameRate = FF13_2_MAX_FRAME_CAP;
|
||||
}
|
||||
else {
|
||||
ff13_2_targetFrameRate = frameRateConfigValue;
|
||||
}
|
||||
|
||||
// movss xmm1,[&FF13_2_30_FPS]
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 0) = 0xF3;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 1) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 2) = 0x10;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 3) = 0x0D;
|
||||
*(float**)(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 4) = (float*)(&FF13_2_30_FPS);
|
||||
|
||||
// ucomiss xmm0,xmm1
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 8) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 9) = 0x2E;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 10) = 0xC1;
|
||||
|
||||
//jna SetFrameRateVar
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 11) = 0x76;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 12) = 0x08;
|
||||
|
||||
// movss xmm0,[&FF13_2_30_FPS]
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 13) = 0xF3;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 14) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 15) = 0x10;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 16) = 0x05;
|
||||
*(float**)(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 17) = (float*)(&ff13_2_targetFrameRate);
|
||||
|
||||
// movss [ecx+04],xmm0
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 21) = 0xF3;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 22) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 23) = 0x11;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 24) = 0x41;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 25) = 0x04;
|
||||
|
||||
//jmp ffxiii2img.exe + 80261B
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 26) = 0xE9;
|
||||
*(uint32_t*)(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 27) = ff13_2_set_frame_rate_address - FF13_2_SET_FRAME_RATE_INJECTED_CODE - 26;
|
||||
}
|
||||
|
||||
void MainContext::FF13_2_InitializeGameAddresses()
|
||||
{
|
||||
// FF13-2 uses address space layout randomization (ASLR) so we can't rely on fixed addresses without considering the base address
|
||||
byte* baseAddr = (byte*)GetModuleHandle(NULL);
|
||||
ff13_2_continuous_scan_instruction_address = baseAddr + 0x2A6E7F;
|
||||
ff13_2_set_frame_rate_address = baseAddr + 0x802616;
|
||||
ff13_2_frame_pacer_ptr_address = (float**)(baseAddr + 0x4D67208);
|
||||
}
|
||||
|
||||
const std::map<const MainContext::AutoFixes, const uint32_t> MainContext::behaviorflags_fixes =
|
||||
{
|
||||
{ RESIDENT_EVIL_4, D3DCREATE_SOFTWARE_VERTEXPROCESSING },
|
||||
|
@ -161,28 +104,63 @@ HRESULT APIENTRY MainContext::ApplyVertexBufferFix(IDirect3DDevice9* pIDirect3DD
|
|||
return pIDirect3DDevice9->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle);
|
||||
}
|
||||
|
||||
void MainContext::FF13_OneTimeFixes() {
|
||||
void MainContext::FF13_InitializeGameAddresses()
|
||||
{
|
||||
// FF13 always seem to use the same addresses (even if you force ASLR on the OS), but we are calculating the addresses just in case...
|
||||
byte* baseAddr = (byte*)GetModuleHandle(NULL); // Should be 400000
|
||||
PrintLog("Base Addr = %x", baseAddr);
|
||||
|
||||
bool successSoFar = true;
|
||||
// The game repeatedly sets the frame rate limit. Disable the instruction that does it.
|
||||
MainContext::FF13_AddHookIngameFrameRateLimitSetter();
|
||||
|
||||
successSoFar &= MainContext::FF13_SetFrameRateVariables();
|
||||
|
||||
if (successSoFar) {
|
||||
context.FF13_RemoveContinuousControllerScan();
|
||||
context.FF13_FixMissingEnemyScan();
|
||||
context.didOneTimeFixes = true;
|
||||
ff13_frame_pacer_ptr = (float**)(baseAddr + 0x243E34C);
|
||||
ff13_set_framerate_ingame_instruction_address = baseAddr + 0xA8D65F;
|
||||
ff13_continuous_scan_instruction_address = baseAddr + 0x420868;
|
||||
ff13_enemy_scan_box_code_address = baseAddr + 0x54C920;
|
||||
ff13_base_controller_input_address_ptr = (byte**)(baseAddr + 0x02411220);
|
||||
ff13_vibration_low_set_zero_address = baseAddr + 0x4210DF;
|
||||
ff13_vibration_high_set_zero_address = baseAddr + 0x4210F3;
|
||||
}
|
||||
|
||||
void MainContext::FF13_OneTimeFixes() {
|
||||
MainContext::FF13_NOPIngameFrameRateLimitSetter();
|
||||
MainContext::FF13_SetFrameRateVariables();
|
||||
MainContext::FF13_RemoveContinuousControllerScan();
|
||||
MainContext::FF13_FixMissingEnemyScan();
|
||||
MainContext::FF13_EnableControllerVibration();
|
||||
|
||||
PrintLog("Finished FF13 One Time Fixes");
|
||||
MainContext::didOneTimeFixes = true;
|
||||
}
|
||||
|
||||
void MainContext::FF13_EnableControllerVibration()
|
||||
{
|
||||
if (!config.GetFFXIIIEnableControllerVibration()) {
|
||||
PrintLog("Vibration should not be enabled (config file)");
|
||||
return;
|
||||
}
|
||||
PrintLog("Enabling controller vibration...");
|
||||
ChangeMemoryProtectionToReadWriteExecute(ff13_vibration_low_set_zero_address, 5);
|
||||
|
||||
*ff13_vibration_low_set_zero_address = 0x90;
|
||||
*(ff13_vibration_low_set_zero_address + 1) = 0x90;
|
||||
*(ff13_vibration_low_set_zero_address + 2) = 0x90;
|
||||
*(ff13_vibration_low_set_zero_address + 3) = 0x90;
|
||||
*(ff13_vibration_low_set_zero_address + 4) = 0x90;
|
||||
|
||||
ChangeMemoryProtectionToReadWriteExecute(ff13_vibration_high_set_zero_address, 5);
|
||||
*ff13_vibration_high_set_zero_address = 0x90;
|
||||
*(ff13_vibration_high_set_zero_address + 1) = 0x90;
|
||||
*(ff13_vibration_high_set_zero_address + 2) = 0x90;
|
||||
*(ff13_vibration_high_set_zero_address + 3) = 0x90;
|
||||
*(ff13_vibration_high_set_zero_address + 4) = 0x90;
|
||||
xinputManager = new XInputManager(ff13_base_controller_input_address_ptr);
|
||||
}
|
||||
|
||||
void MainContext::FF13_RemoveContinuousControllerScan() {
|
||||
// Disable continuous controller scanning.
|
||||
|
||||
PrintLog("Removing game slow and synchronous controller continuous controller scanning...");
|
||||
context.ChangeMemoryProtectionToReadWriteExecute(FF13_CONTINUOUS_SCAN_INSTRUCTION_ADDRESS, 1);
|
||||
context.ChangeMemoryProtectionToReadWriteExecute(ff13_continuous_scan_instruction_address, 1);
|
||||
// change a jne to jmp
|
||||
*(byte*)FF13_CONTINUOUS_SCAN_INSTRUCTION_ADDRESS = 0xEB;
|
||||
*(byte*)ff13_continuous_scan_instruction_address = 0xEB;
|
||||
}
|
||||
|
||||
void MainContext::FF13_FixMissingEnemyScan() {
|
||||
|
@ -197,37 +175,41 @@ void MainContext::FF13_FixMissingEnemyScan() {
|
|||
const uint32_t rectWidth = context.backbufferWidth;
|
||||
const uint32_t rectPosY = (uint32_t)(496.0F * resolutionFactor);
|
||||
|
||||
context.ChangeMemoryProtectionToReadWriteExecute(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS, 18);
|
||||
context.ChangeMemoryProtectionToReadWriteExecute(ff13_enemy_scan_box_code_address, 18);
|
||||
|
||||
//push boxHeight
|
||||
*(byte*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 0) = 0x68;
|
||||
*(uint32_t*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 1) = rectHeight;
|
||||
//push rectHeight
|
||||
*(byte*)(ff13_enemy_scan_box_code_address + 0) = 0x68;
|
||||
*(uint32_t*)(ff13_enemy_scan_box_code_address + 1) = rectHeight;
|
||||
|
||||
// push boxWidth
|
||||
*(byte*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 5) = 0x68;
|
||||
*(uint32_t*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 6) = rectWidth;
|
||||
// push rectWidth
|
||||
*(byte*)(ff13_enemy_scan_box_code_address + 5) = 0x68;
|
||||
*(uint32_t*)(ff13_enemy_scan_box_code_address + 6) = rectWidth;
|
||||
|
||||
// push boxPosY
|
||||
*(byte*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 10) = 0x68;
|
||||
*(uint32_t*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 11) = rectPosY;
|
||||
// push rectPosY
|
||||
*(byte*)(ff13_enemy_scan_box_code_address + 10) = 0x68;
|
||||
*(uint32_t*)(ff13_enemy_scan_box_code_address + 11) = rectPosY;
|
||||
|
||||
// NOP NOP NOP
|
||||
*(byte*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 15) = 0x90;
|
||||
*(byte*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 16) = 0x90;
|
||||
*(byte*)(FF13_ENEMY_SCAN_BOX_CODE_ADDRESS + 17) = 0x90;
|
||||
*(byte*)(ff13_enemy_scan_box_code_address + 15) = 0x90;
|
||||
*(byte*)(ff13_enemy_scan_box_code_address + 16) = 0x90;
|
||||
*(byte*)(ff13_enemy_scan_box_code_address + 17) = 0x90;
|
||||
}
|
||||
|
||||
void MainContext::FF13_AddHookIngameFrameRateLimitSetter() {
|
||||
PrintLog("Using the ingame the instruction that sets the frame rate to get the frame rate address.");
|
||||
void MainContext::FF13_NOPIngameFrameRateLimitSetter() {
|
||||
PrintLog("NOPing the in-game instruction that sets the frame rate.");
|
||||
|
||||
context.ChangeMemoryProtectionToReadWriteExecute(FF13_SET_FRAMERATE_INGAME_INSTRUCTION_ADDRESS, 5);
|
||||
context.ChangeMemoryProtectionToReadWriteExecute(ff13_set_framerate_ingame_instruction_address, 5);
|
||||
|
||||
// patching to: mov [framePacerTargetPtr], eax
|
||||
*FF13_SET_FRAMERATE_INGAME_INSTRUCTION_ADDRESS = 0xA3;
|
||||
*((uint32_t*)(FF13_SET_FRAMERATE_INGAME_INSTRUCTION_ADDRESS + 1)) = (uint32_t)(&framePacerTargetPtr);
|
||||
// patching to: NOP NOP NOP NOP
|
||||
*ff13_set_framerate_ingame_instruction_address = 0x90;
|
||||
*(ff13_set_framerate_ingame_instruction_address + 1) = 0x90;
|
||||
*(ff13_set_framerate_ingame_instruction_address + 2) = 0x90;
|
||||
*(ff13_set_framerate_ingame_instruction_address + 3) = 0x90;
|
||||
*(ff13_set_framerate_ingame_instruction_address + 4) = 0x90;
|
||||
}
|
||||
|
||||
bool MainContext::FF13_SetFrameRateVariables() {
|
||||
void MainContext::FF13_SetFrameRateVariables() {
|
||||
float* framePacerTargetPtr = *ff13_frame_pacer_ptr;
|
||||
if (framePacerTargetPtr) {
|
||||
PrintLog("Frame pacer target frame rate is at address %x", framePacerTargetPtr);
|
||||
|
||||
|
@ -255,10 +237,8 @@ bool MainContext::FF13_SetFrameRateVariables() {
|
|||
}
|
||||
}
|
||||
else {
|
||||
PrintLog("Unable to find frame rate pattern. This is normal if the game still hasn't completely started yet.");
|
||||
PrintLog("Unable to find frame pacer / frame rate address. This shouldn't happen! Report this.");
|
||||
}
|
||||
|
||||
return framePacerTargetPtr;
|
||||
}
|
||||
|
||||
void MainContext::FF13_2_OneTimeFixes() {
|
||||
|
@ -269,10 +249,51 @@ void MainContext::FF13_2_OneTimeFixes() {
|
|||
|
||||
context.FF13_2_AddHookIngameFrameRateLimitSetter();
|
||||
context.FF13_2_RemoveContinuousControllerScan();
|
||||
context.FF13_2_EnableControllerVibration();
|
||||
PrintLog("Finished FF13-2 One Time Fixes");
|
||||
context.didOneTimeFixes = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MainContext::FF13_2_EnableControllerVibration()
|
||||
{
|
||||
if (!config.GetFFXIIIEnableControllerVibration()) {
|
||||
PrintLog("Vibration should not be enabled (config file)");
|
||||
return;
|
||||
}
|
||||
PrintLog("Enabling controller vibration...");
|
||||
ChangeMemoryProtectionToReadWriteExecute(ff13_2_vibration_low_set_zero_address, 5);
|
||||
|
||||
*ff13_2_vibration_low_set_zero_address = 0x90;
|
||||
*(ff13_2_vibration_low_set_zero_address + 1) = 0x90;
|
||||
*(ff13_2_vibration_low_set_zero_address + 2) = 0x90;
|
||||
*(ff13_2_vibration_low_set_zero_address + 3) = 0x90;
|
||||
*(ff13_2_vibration_low_set_zero_address + 4) = 0x90;
|
||||
|
||||
ChangeMemoryProtectionToReadWriteExecute(ff13_2_vibration_high_set_zero_address, 5);
|
||||
*ff13_2_vibration_high_set_zero_address = 0x90;
|
||||
*(ff13_2_vibration_high_set_zero_address + 1) = 0x90;
|
||||
*(ff13_2_vibration_high_set_zero_address + 2) = 0x90;
|
||||
*(ff13_2_vibration_high_set_zero_address + 3) = 0x90;
|
||||
*(ff13_2_vibration_high_set_zero_address + 4) = 0x90;
|
||||
|
||||
xinputManager = new XInputManager(ff13_2_base_controller_input_address_ptr);
|
||||
}
|
||||
|
||||
void MainContext::FF13_2_InitializeGameAddresses()
|
||||
{
|
||||
// FF13-2 uses address space layout randomization (ASLR) so we can't rely on fixed addresses without considering the base address
|
||||
byte* baseAddr = (byte*)GetModuleHandle(NULL);
|
||||
PrintLog("Base Addr = %x", baseAddr);
|
||||
|
||||
ff13_2_continuous_scan_instruction_address = baseAddr + 0x2A6E7F;
|
||||
ff13_2_set_frame_rate_address = baseAddr + 0x802616;
|
||||
ff13_2_frame_pacer_ptr_address = (float**)(baseAddr + 0x4D67208);
|
||||
ff13_2_base_controller_input_address_ptr = (byte**)(baseAddr + 0x212A164);
|
||||
ff13_2_vibration_low_set_zero_address = baseAddr + 0x2A7221;
|
||||
ff13_2_vibration_high_set_zero_address = baseAddr + 0x2A7226;
|
||||
}
|
||||
|
||||
void MainContext::FF13_2_RemoveContinuousControllerScan() {
|
||||
// Disable continuous controller scanning.
|
||||
|
||||
|
@ -297,13 +318,65 @@ void MainContext::FF13_2_AddHookIngameFrameRateLimitSetter() {
|
|||
*((uint32_t*)(ff13_2_set_frame_rate_address + 1)) = FF13_2_SET_FRAME_RATE_INJECTED_CODE - ff13_2_set_frame_rate_address - 5;
|
||||
}
|
||||
|
||||
void MainContext::FF13_2_CreateSetFrameRateCodeBlock()
|
||||
{
|
||||
const int blockSize = 31;
|
||||
FF13_2_SET_FRAME_RATE_INJECTED_CODE = new byte[blockSize];
|
||||
|
||||
ChangeMemoryProtectionToReadWriteExecute(FF13_2_SET_FRAME_RATE_INJECTED_CODE, blockSize);
|
||||
|
||||
float frameRateConfigValue = (float)context.config.GetFFXIIIIngameFrameRateLimit();
|
||||
if (AreAlmostTheSame(frameRateConfigValue, -1.0F) || frameRateConfigValue > FF13_2_MAX_FRAME_CAP) {
|
||||
ff13_2_targetFrameRate = FF13_2_MAX_FRAME_CAP;
|
||||
}
|
||||
else {
|
||||
ff13_2_targetFrameRate = frameRateConfigValue;
|
||||
}
|
||||
|
||||
// movss xmm1,[&FF13_2_30_FPS]
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 0) = 0xF3;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 1) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 2) = 0x10;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 3) = 0x0D;
|
||||
*(float**)(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 4) = (float*)(&FF13_2_30_FPS);
|
||||
|
||||
// ucomiss xmm0,xmm1
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 8) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 9) = 0x2E;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 10) = 0xC1;
|
||||
|
||||
//jna SetFrameRateVar
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 11) = 0x76;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 12) = 0x08;
|
||||
|
||||
// movss xmm0,[&FF13_2_30_FPS]
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 13) = 0xF3;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 14) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 15) = 0x10;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 16) = 0x05;
|
||||
*(float**)(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 17) = (float*)(&ff13_2_targetFrameRate);
|
||||
|
||||
// SetFrameRateVar:
|
||||
// movss [ecx+04],xmm0
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 21) = 0xF3;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 22) = 0x0F;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 23) = 0x11;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 24) = 0x41;
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 25) = 0x04;
|
||||
|
||||
// jmp ffxiii2img.exe + 80261B
|
||||
*(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 26) = 0xE9;
|
||||
*(uint32_t*)(FF13_2_SET_FRAME_RATE_INJECTED_CODE + 27) = ff13_2_set_frame_rate_address - FF13_2_SET_FRAME_RATE_INJECTED_CODE - 26;
|
||||
}
|
||||
|
||||
|
||||
void MainContext::ChangeMemoryProtectionToReadWriteExecute(void* address, const int size) {
|
||||
DWORD oldProtection;
|
||||
VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldProtection);
|
||||
}
|
||||
|
||||
void MainContext::PrintVersionInfo() {
|
||||
PrintLog("FF13Fix 1.3.1 https://github.com/rebtd7/FF13Fix");
|
||||
PrintLog("FF13Fix 1.4.0 https://github.com/rebtd7/FF13Fix");
|
||||
}
|
||||
|
||||
bool MainContext::AreAlmostTheSame(float a, float b) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "Context.h"
|
||||
#include "IDirect3D9.h"
|
||||
#include <thread>
|
||||
|
||||
MainContext context;
|
||||
|
||||
|
@ -41,7 +42,7 @@ Config::Config()
|
|||
MainContext::MainContext() : oldWndProc(nullptr)
|
||||
{
|
||||
LogFile("FF13Fix.log");
|
||||
PrintVersionInfo();
|
||||
context.PrintVersionInfo();
|
||||
|
||||
if (config.GetAutoFix()) EnableAutoFix();
|
||||
|
||||
|
@ -61,6 +62,8 @@ MainContext::MainContext() : oldWndProc(nullptr)
|
|||
|
||||
MH_CreateHook(SetWindowLongW, HookSetWindowLongW, reinterpret_cast<void**>(&TrueSetWindowLongW));
|
||||
MH_EnableHook(SetWindowLongW);
|
||||
|
||||
|
||||
}
|
||||
|
||||
MainContext::~MainContext()
|
||||
|
@ -178,15 +181,21 @@ bool MainContext::CheckWindow(HWND hWnd)
|
|||
PrintLog("HWND 0x%p: ClassName \"%ls\", WindowName: \"%ls\"", hWnd, className.get(), windowName.get());
|
||||
|
||||
if (!context.didOneTimeFixes) {
|
||||
if (context.autofix == FINAL_FANTASY_XIII) {
|
||||
if (context.autofix == FINAL_FANTASY_XIII && wcscmp(windowName.get(), L"DIEmWin") == 0) {
|
||||
const std::lock_guard<std::mutex> lock(context.oneTimeFixesMutex);
|
||||
if(!context.didOneTimeFixes){
|
||||
PrintLog("Starting FFXIII one time RAM patches.");
|
||||
context.FF13_OneTimeFixes();
|
||||
}
|
||||
}
|
||||
else if (context.autofix == FINAL_FANTASY_XIII2 && wcscmp(windowName.get(), L"DIEmWin") == 0) {
|
||||
const std::lock_guard<std::mutex> lock(context.oneTimeFixesMutex);
|
||||
if (!context.didOneTimeFixes) {
|
||||
PrintLog("Starting FFXIII-2 one time RAM patches.");
|
||||
context.FF13_2_OneTimeFixes();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool class_found = config.GetWindowClass().compare(className.get()) == 0;
|
||||
bool window_found = config.GetWindowName().compare(windowName.get()) == 0;
|
||||
bool force = config.GetAllWindows();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "d3d9.h"
|
||||
#include <MinHook.h>
|
||||
#include "SimpleIni.h"
|
||||
#include "XInputManager.h"
|
||||
|
||||
struct hkIDirect3D9;
|
||||
|
||||
|
@ -44,6 +45,7 @@ class MainContext
|
|||
|
||||
public:
|
||||
MainContext();
|
||||
void Foo();
|
||||
~MainContext();
|
||||
|
||||
bool ApplyPresentationParameters(D3DPRESENT_PARAMETERS* pPresentationParameters);
|
||||
|
@ -69,27 +71,34 @@ private:
|
|||
};
|
||||
|
||||
void EnableAutoFix();
|
||||
void FF13_2_CreateSetFrameRateCodeBlock();
|
||||
void FF13_2_InitializeGameAddresses();
|
||||
|
||||
AutoFixes autofix = AutoFixes::NONE;
|
||||
|
||||
std::mutex oneTimeFixesMutex;
|
||||
bool didOneTimeFixes = false;
|
||||
|
||||
const float MAX_FRAME_RATE_LIMIT = 250000.0F;
|
||||
byte* FF13_SET_FRAMERATE_INGAME_INSTRUCTION_ADDRESS = (byte*)0x00E8D65F;
|
||||
byte* FF13_CONTINUOUS_SCAN_INSTRUCTION_ADDRESS = (byte*)0x00820868;
|
||||
byte* FF13_ENEMY_SCAN_BOX_CODE_ADDRESS = (byte*)0x0094C920;
|
||||
float** ff13_frame_pacer_ptr = NULL;
|
||||
byte* ff13_set_framerate_ingame_instruction_address = NULL;
|
||||
byte* ff13_continuous_scan_instruction_address = NULL;
|
||||
byte* ff13_enemy_scan_box_code_address = NULL;
|
||||
byte** ff13_base_controller_input_address_ptr = NULL;
|
||||
byte* ff13_vibration_high_set_zero_address = NULL;
|
||||
byte* ff13_vibration_low_set_zero_address = NULL;
|
||||
|
||||
byte* FF13_2_SET_FRAME_RATE_INJECTED_CODE = NULL;
|
||||
byte* ff13_2_continuous_scan_instruction_address;
|
||||
byte* ff13_2_set_frame_rate_address;
|
||||
float** ff13_2_frame_pacer_ptr_address;
|
||||
float ff13_2_targetFrameRate;
|
||||
byte** ff13_2_base_controller_input_address_ptr = NULL;
|
||||
byte* ff13_2_vibration_high_set_zero_address = NULL;
|
||||
byte* ff13_2_vibration_low_set_zero_address = NULL;
|
||||
|
||||
const float FF13_2_30_FPS = 30.0F;
|
||||
const float FF13_2_MAX_FRAME_CAP = 1000.0F;
|
||||
XInputManager* xinputManager;
|
||||
|
||||
float* framePacerTargetPtr = NULL;
|
||||
UINT backbufferWidth = 0;
|
||||
|
||||
void FixBehaviorFlagConflict(const DWORD flags_in, DWORD* flags_out);
|
||||
|
@ -102,15 +111,20 @@ private:
|
|||
bool AreAlmostTheSame(float a, float b);
|
||||
void PrintVersionInfo();
|
||||
|
||||
void FF13_InitializeGameAddresses();
|
||||
void FF13_OneTimeFixes();
|
||||
void FF13_AddHookIngameFrameRateLimitSetter();
|
||||
bool FF13_SetFrameRateVariables();
|
||||
void FF13_EnableControllerVibration();
|
||||
void FF13_NOPIngameFrameRateLimitSetter();
|
||||
void FF13_SetFrameRateVariables();
|
||||
void FF13_FixMissingEnemyScan();
|
||||
void FF13_RemoveContinuousControllerScan();
|
||||
|
||||
void FF13_2_CreateSetFrameRateCodeBlock();
|
||||
void FF13_2_InitializeGameAddresses();
|
||||
void FF13_2_RemoveContinuousControllerScan();
|
||||
void FF13_2_AddHookIngameFrameRateLimitSetter();
|
||||
void FF13_2_OneTimeFixes();
|
||||
void FF13_2_EnableControllerVibration();
|
||||
};
|
||||
|
||||
extern MainContext context;
|
|
@ -11,6 +11,7 @@ SETTING(bool, BoolValue, ForceHideCursor, Options, false);
|
|||
SETTING(u32, LongValue, BehaviorFlags, Options, 0);
|
||||
|
||||
SETTING(double, DoubleValue, FFXIIIIngameFrameRateLimit, Options, 0.0);
|
||||
SETTING(bool, BoolValue, FFXIIIEnableControllerVibration, Options, true);
|
||||
|
||||
SETTING(bool, BoolValue, Adapter, Adapter, false);
|
||||
SETTING(u32, LongValue, VendorId, Adapter, 0);
|
||||
|
|
69
d3d9ex/XInputManager.cpp
Normal file
69
d3d9ex/XInputManager.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include "stdafx.h"
|
||||
#include "XInputManager.h"
|
||||
#include <XInput.h>
|
||||
|
||||
XInputManager::XInputManager(byte** base_controller_input_address_ptr)
|
||||
{
|
||||
xinputThread = std::thread(&XInputManager::Run, this, base_controller_input_address_ptr);
|
||||
}
|
||||
|
||||
void XInputManager::Run(byte** base_controller_input_address_ptr)
|
||||
{
|
||||
DWORD controllerState;
|
||||
bool hasConnected = false;
|
||||
for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
|
||||
XINPUT_STATE state;
|
||||
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||
|
||||
controllerState = XInputGetState(i, &state);
|
||||
if (controllerState == ERROR_SUCCESS) {
|
||||
controllerId = i;
|
||||
hasConnected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasConnected) {
|
||||
WaitAndSetVibrationAddress(base_controller_input_address_ptr);
|
||||
VibrationLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void XInputManager::WaitAndSetVibrationAddress(byte** base_controller_input_address_ptr)
|
||||
{
|
||||
do {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(4));
|
||||
if (base_controller_input_address_ptr && *base_controller_input_address_ptr) {
|
||||
vibration_address_low_frequency = (float*)(*base_controller_input_address_ptr + 0x40 + 0x60 - 0x4);
|
||||
vibration_address_high_frequency = vibration_address_low_frequency + 1;
|
||||
}
|
||||
} while (vibration_address_low_frequency == NULL);
|
||||
}
|
||||
|
||||
void XInputManager::VibrationLoop()
|
||||
{
|
||||
const WORD maxVibrationStrength = 65535;
|
||||
bool wasVibrating = false;
|
||||
SetControllerVibration(0, 0);
|
||||
while (true) {
|
||||
const float vibrationStrengthLowFrequency = *vibration_address_low_frequency;
|
||||
const float vibrationStrengthHighFrequency = *vibration_address_high_frequency;
|
||||
if (vibrationStrengthLowFrequency || vibrationStrengthHighFrequency) {
|
||||
SetControllerVibration(vibrationStrengthLowFrequency * maxVibrationStrength, vibrationStrengthHighFrequency * maxVibrationStrength);
|
||||
wasVibrating = true;
|
||||
}
|
||||
else if(wasVibrating) {
|
||||
SetControllerVibration(0, 0);
|
||||
wasVibrating = false;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(4));
|
||||
}
|
||||
}
|
||||
|
||||
void XInputManager::SetControllerVibration(const WORD& leftMotorVibration, const WORD& rightMotorVibration)
|
||||
{
|
||||
XINPUT_VIBRATION vibration;
|
||||
ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));
|
||||
vibration.wLeftMotorSpeed = leftMotorVibration;
|
||||
vibration.wRightMotorSpeed = rightMotorVibration;
|
||||
XInputSetState(controllerId, &vibration);
|
||||
}
|
15
d3d9ex/XInputManager.h
Normal file
15
d3d9ex/XInputManager.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
class XInputManager
|
||||
{
|
||||
float* vibration_address_high_frequency = NULL;
|
||||
float* vibration_address_low_frequency = NULL;
|
||||
DWORD controllerId = -1;
|
||||
std::thread xinputThread;
|
||||
public:
|
||||
XInputManager(byte** base_controller_input_address_ptr);
|
||||
void Run(byte** base_controller_input_address_ptr);
|
||||
void WaitAndSetVibrationAddress(byte** base_controller_input_address_ptr);
|
||||
void VibrationLoop();
|
||||
void SetControllerVibration(const WORD& leftMotorVibration, const WORD& rightMotorVibration);
|
||||
};
|
||||
|
|
@ -137,7 +137,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>XINPUT9_1_0.LIB;d3d9.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
@ -172,6 +172,7 @@
|
|||
<ClInclude Include="Settings.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="XInputManager.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AutoFix.cpp" />
|
||||
|
@ -199,6 +200,7 @@
|
|||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XInputManager.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="exports.def" />
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
<ClInclude Include="IDirect3DVertexBuffer9.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="XInputManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -65,6 +68,9 @@
|
|||
<ClCompile Include="IDirect3DVertexBuffer9.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XInputManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="exports.def">
|
||||
|
|
Loading…
Reference in a new issue