[FF13] Allow usage of 4GB memory patch

This commit is contained in:
rebtd7 2021-03-20 21:31:44 -03:00
parent 511e343535
commit 240ee9a015
4 changed files with 112 additions and 5 deletions

View File

@ -43,11 +43,19 @@ This considerably improves the frame rate when 2D elements are being disabled on
## Fix the enemy scan text on resolutions over 720p (FFXIII only) ## Fix the enemy scan text on resolutions over 720p (FFXIII only)
The game calls [SetScissorRect](https://docs.microsoft.com/en-us/windows/win32/api/d3d9helper/nf-d3d9helper-idirect3ddevice9-setscissorrect) using a rectangle hardcoded with the 720p coordenates. This correct the coordenates and rectangle size in order to fix it. The game calls [SetScissorRect](https://docs.microsoft.com/en-us/windows/win32/api/d3d9helper/nf-d3d9helper-idirect3ddevice9-setscissorrect) using a rectangle hardcoded with the 720p coordenates. This correct the coordenates and rectangle size in order to fix it.
## Reporting issues # Usage with the 4GB Large Address Aware patch
You may wish to patch the games to allow them to access more than 4GB of RAM. This seems to avoid crashes in FF13-2 (and may help FF13 under some configurations).
## FF13:
* Create a copy of the unpatched ```ffxiiiimg.exe``` to the folder ```FINAL FANTASY XIII\white_data\prog\win\bin```. Name it ```untouched.exe```.
* Patch the original ```ffxiiiimg.exe``` (you can use https://ntcore.com/?page_id=371)
## FF13-2:
* Patch ```ffxiii2img.exe``` (you can use https://ntcore.com/?page_id=371)
# Reporting issues
* Please specify what game are you talking about, which mods are you using (dxvk?) post system specs, and post FF13Fix.log * Please specify what game are you talking about, which mods are you using (dxvk?) post system specs, and post FF13Fix.log
* Add a save file and steps to reproduce the issue if possible * Add a save file and steps to reproduce the issue if possible
## Other notes # Other notes
* This is currently not compatible with GeDoSaTo. * This is currently not compatible with GeDoSaTo.
* I strongly recommend forcing anisotropic filtering on your GPU driver to improve the quality of the textures. * I strongly recommend forcing anisotropic filtering on your GPU driver to improve the quality of the textures.
* Using "Maximum Performance" power management in the GPU driver can also help keeping the frame rate smooth. * Using "Maximum Performance" power management in the GPU driver can also help keeping the frame rate smooth.

View File

@ -4,7 +4,7 @@
#include "MemPatch.h" #include "MemPatch.h"
#include "Context.h" #include "Context.h"
//#include "IDirect3DVertexBuffer9.h" #include <MinHook.h>
void MainContext::EnableAutoFix() void MainContext::EnableAutoFix()
{ {
@ -16,6 +16,7 @@ void MainContext::EnableAutoFix()
autofix = AutoFixes::FINAL_FANTASY_XIII; autofix = AutoFixes::FINAL_FANTASY_XIII;
PrintLog("AutoFix for \"Final Fantasy XIII\" enabled"); PrintLog("AutoFix for \"Final Fantasy XIII\" enabled");
FF13_InitializeGameAddresses(); FF13_InitializeGameAddresses();
FF13_HandleLargeAddressAwarePatch();
} }
if (exe_name == "ffxiii2img.exe") if (exe_name == "ffxiii2img.exe")
@ -38,6 +39,67 @@ const std::map<const MainContext::AutoFixes, const uint32_t> MainContext::behavi
//{ AutoFixes::FINAL_FANTASY_XIII2, D3DCREATE_PUREDEVICE } //{ AutoFixes::FINAL_FANTASY_XIII2, D3DCREATE_PUREDEVICE }
}; };
HANDLE WINAPI MainContext::HookCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
const char* ffxiiiimgPrt = strstr(lpFileName, "ffxiiiimg.exe");
if (ffxiiiimgPrt) {
PrintLog("HookCreateFileA Before Replacement: %s", lpFileName);
int arrayPosition = ffxiiiimgPrt - lpFileName;
int len = strlen(lpFileName);
char* newFileName = new char[len + 1];
strcpy_s(newFileName, len + 1, lpFileName);
const char* untouched = "untouched"; // needs to have the size of "ffxiiiimg"
memcpy(newFileName + arrayPosition, untouched, strlen(untouched));
PrintLog("HookCreateFileA After Replacement: %s", newFileName);
MH_STATUS disableHookCreateFileA = MH_DisableHook(CreateFileA);
PrintLog("disableHookCreateFileA = %d", disableHookCreateFileA);
MH_STATUS disableHookCreateFileW = MH_DisableHook(CreateFileW);
PrintLog("disableHookCreateFileW = %d", disableHookCreateFileW);
if (GetFileAttributesA(newFileName) == INVALID_FILE_ATTRIBUTES) {
PrintLog("ERROR: Unable to get attributes of %s. Does the file exist?", newFileName);
}
HANDLE fileHandle = context.TrueCreateFileA(newFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);;
delete[] newFileName;
PrintLog("Returning File Handle");
return fileHandle;
}
else {
return context.TrueCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
}
HANDLE WINAPI MainContext::HookCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
const wchar_t* ffxiiiimgPrt = wcsstr(lpFileName, L"ffxiiiimg.exe");;
if (ffxiiiimgPrt) {
PrintLog("HookCreateFileW Before Replacement: %s", lpFileName);
int arrayPosition = ffxiiiimgPrt - lpFileName;
int len = wcslen(lpFileName);
wchar_t* newFileName = new wchar_t[len + 1];
wcscpy_s(newFileName, len + 1, lpFileName);
const wchar_t* untouched = L"untouched"; //needs to have the size of L"ffxiiiimg"
wmemcpy(newFileName + arrayPosition, untouched, wcslen(untouched));
PrintLog("HookCreateFileW After Replacement: %s", newFileName);
MH_STATUS disableHookCreateFileA = MH_DisableHook(CreateFileA);
PrintLog("disableHookCreateFileA = %d", disableHookCreateFileA);
MH_STATUS disableHookCreateFileW = MH_DisableHook(CreateFileW);
PrintLog("disableHookCreateFileW = %d", disableHookCreateFileW);
if (GetFileAttributesW(newFileName) == INVALID_FILE_ATTRIBUTES) {
PrintLog("ERROR: Unable to get attributes of %s. Does the file exist?", newFileName);
}
HANDLE fileHandle = context.TrueCreateFileW(newFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);;
delete[] newFileName;
PrintLog("Returning File Handle");
return fileHandle;
}
else {
return context.TrueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
}
void MainContext::FixBehaviorFlagConflict(const DWORD flags_in, DWORD* flags_out) void MainContext::FixBehaviorFlagConflict(const DWORD flags_in, DWORD* flags_out)
{ {
if (flags_in & D3DCREATE_SOFTWARE_VERTEXPROCESSING) if (flags_in & D3DCREATE_SOFTWARE_VERTEXPROCESSING)
@ -199,6 +261,38 @@ void MainContext::FF13_InitializeGameAddresses()
ff13_party_screen_scissor_scaling_factor_4 = baseAddr + 0x668E91; ff13_party_screen_scissor_scaling_factor_4 = baseAddr + 0x668E91;
ff13_message_box_call_address = baseAddr + 0xA8A98F; ff13_message_box_call_address = baseAddr + 0xA8A98F;
ff13_message_box_stack_push_address = baseAddr + 0xA8A982; ff13_message_box_stack_push_address = baseAddr + 0xA8A982;
ff13_exe_large_address_aware_flag_address = baseAddr + 0x126;
ff13_exe_checksum_address = baseAddr + 0x168;
}
void MainContext::FF13_HandleLargeAddressAwarePatch() {
const uint8_t laaMask = 0x20;
if (*ff13_exe_large_address_aware_flag_address && laaMask) {
PrintLog("LargeAddressAwarePatch found. Make sure untouched.exe is an unmodified copy of ffxiiiimg.exe");
const MH_STATUS createHookCreateFileA = MH_CreateHook(CreateFileA, HookCreateFileA, reinterpret_cast<void**>(&TrueCreateFileA));
PrintLog("createHookCreateFileA = %d", createHookCreateFileA);
const MH_STATUS enableHookCreateFileA = MH_EnableHook(CreateFileA);
PrintLog("enableHookCreateFileA = %d", enableHookCreateFileA);
const MH_STATUS createHookCreateFileW = MH_CreateHook(CreateFileW, HookCreateFileW, reinterpret_cast<void**>(&TrueCreateFileW));
PrintLog("createHookCreateFileW = %d", createHookCreateFileW);
const MH_STATUS enableHookCreateFileW = MH_EnableHook(CreateFileW);
PrintLog("enableHookCreateFileW = %d", enableHookCreateFileW);
uint8_t new_ff13_exe_large_address_aware_flag = *ff13_exe_large_address_aware_flag_address & ~laaMask;
MemPatch::Patch(ff13_exe_large_address_aware_flag_address, &new_ff13_exe_large_address_aware_flag, 1);
PrintLog("LargeAddressAware patched back = %d", *ff13_exe_large_address_aware_flag_address);
uint32_t new_ff13_exe_checksum = 0;
MemPatch::Patch(ff13_exe_checksum_address, &new_ff13_exe_checksum, sizeof(uint32_t));
PrintLog("Checksum patched back = %d", *ff13_exe_checksum_address);
PrintLog("LargeAddressAwarePatch handled");
}
else {
PrintLog("LargeAddressAwarePatch not found.");
}
} }
void MainContext::ForceWindowActivate(const HWND hWnd) { void MainContext::ForceWindowActivate(const HWND hWnd) {

View File

@ -50,8 +50,6 @@ MainContext::MainContext()
LogFile("FF13Fix.log"); LogFile("FF13Fix.log");
context.PrintVersionInfo(); context.PrintVersionInfo();
if (config.GetOptionsAutoFix()) EnableAutoFix();
PrintLog("Enabling hooks:"); PrintLog("Enabling hooks:");
const MH_STATUS initializeHooks = MH_Initialize(); const MH_STATUS initializeHooks = MH_Initialize();
PrintLog("initializeHooks = %d", initializeHooks); PrintLog("initializeHooks = %d", initializeHooks);
@ -80,6 +78,8 @@ MainContext::MainContext()
PrintLog("createHookSetWindowLongW = %d", createHookSetWindowLongW); PrintLog("createHookSetWindowLongW = %d", createHookSetWindowLongW);
const MH_STATUS enableHookSetWindowLongW = MH_EnableHook(SetWindowLongW); const MH_STATUS enableHookSetWindowLongW = MH_EnableHook(SetWindowLongW);
PrintLog("enableHookSetWindowLongW = %d", enableHookSetWindowLongW); PrintLog("enableHookSetWindowLongW = %d", enableHookSetWindowLongW);
if (config.GetOptionsAutoFix()) EnableAutoFix();
} }
MainContext::~MainContext() MainContext::~MainContext()

View File

@ -41,6 +41,8 @@ class MainContext
DECLARE_HOOK(HWND, WINAPI, CreateWindowExW, DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DECLARE_HOOK(HWND, WINAPI, CreateWindowExW, DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName,
DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
DECLARE_HOOK(HANDLE, WINAPI, CreateFileA, LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
DECLARE_HOOK(HANDLE, WINAPI, CreateFileW, LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);
public: public:
MainContext(); MainContext();
virtual ~MainContext(); virtual ~MainContext();
@ -95,6 +97,8 @@ private:
uint8_t* ff13_party_screen_scissor_scaling_factor_4 = NULL; uint8_t* ff13_party_screen_scissor_scaling_factor_4 = NULL;
uint8_t* ff13_message_box_stack_push_address = NULL; uint8_t* ff13_message_box_stack_push_address = NULL;
uint8_t* ff13_message_box_call_address = NULL; uint8_t* ff13_message_box_call_address = NULL;
uint8_t* ff13_exe_large_address_aware_flag_address = NULL;
uint8_t* ff13_exe_checksum_address = NULL;
uint32_t* ff13_internal_res_w; uint32_t* ff13_internal_res_w;
uint32_t* ff13_internal_res_h; uint32_t* ff13_internal_res_h;
@ -151,6 +155,7 @@ private:
void FF13_SetFrameRateVariables(); void FF13_SetFrameRateVariables();
void FF13_FixScissorRect(); void FF13_FixScissorRect();
void FF13_RemoveContinuousControllerScan(); void FF13_RemoveContinuousControllerScan();
void FF13_HandleLargeAddressAwarePatch();
void FF13_2_CreateSetFrameRateCodeBlock(); void FF13_2_CreateSetFrameRateCodeBlock();
void FF13_2_InitializeGameAddresses(); void FF13_2_InitializeGameAddresses();