Merge pull request #52 from rebtd7/laa_patch
[FF13] Allow usage of 4GB memory patch
This commit is contained in:
commit
2249c4cdb0
12
README.md
12
README.md
|
@ -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)
|
||||
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
|
||||
* Add a save file and steps to reproduce the issue if possible
|
||||
|
||||
## Other notes
|
||||
# Other notes
|
||||
* This is currently not compatible with GeDoSaTo.
|
||||
* 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.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "MemPatch.h"
|
||||
|
||||
#include "Context.h"
|
||||
//#include "IDirect3DVertexBuffer9.h"
|
||||
#include <MinHook.h>
|
||||
|
||||
void MainContext::EnableAutoFix()
|
||||
{
|
||||
|
@ -16,6 +16,7 @@ void MainContext::EnableAutoFix()
|
|||
autofix = AutoFixes::FINAL_FANTASY_XIII;
|
||||
PrintLog("AutoFix for \"Final Fantasy XIII\" enabled");
|
||||
FF13_InitializeGameAddresses();
|
||||
FF13_HandleLargeAddressAwarePatch();
|
||||
}
|
||||
|
||||
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 }
|
||||
};
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
if (flags_in & D3DCREATE_SOFTWARE_VERTEXPROCESSING)
|
||||
|
@ -199,6 +261,38 @@ void MainContext::FF13_InitializeGameAddresses()
|
|||
ff13_party_screen_scissor_scaling_factor_4 = baseAddr + 0x668E91;
|
||||
ff13_message_box_call_address = baseAddr + 0xA8A98F;
|
||||
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) {
|
||||
|
|
|
@ -50,8 +50,6 @@ MainContext::MainContext()
|
|||
LogFile("FF13Fix.log");
|
||||
context.PrintVersionInfo();
|
||||
|
||||
if (config.GetOptionsAutoFix()) EnableAutoFix();
|
||||
|
||||
PrintLog("Enabling hooks:");
|
||||
const MH_STATUS initializeHooks = MH_Initialize();
|
||||
PrintLog("initializeHooks = %d", initializeHooks);
|
||||
|
@ -80,6 +78,8 @@ MainContext::MainContext()
|
|||
PrintLog("createHookSetWindowLongW = %d", createHookSetWindowLongW);
|
||||
const MH_STATUS enableHookSetWindowLongW = MH_EnableHook(SetWindowLongW);
|
||||
PrintLog("enableHookSetWindowLongW = %d", enableHookSetWindowLongW);
|
||||
|
||||
if (config.GetOptionsAutoFix()) EnableAutoFix();
|
||||
}
|
||||
|
||||
MainContext::~MainContext()
|
||||
|
|
|
@ -41,6 +41,8 @@ class MainContext
|
|||
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);
|
||||
|
||||
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:
|
||||
MainContext();
|
||||
virtual ~MainContext();
|
||||
|
@ -95,6 +97,8 @@ private:
|
|||
uint8_t* ff13_party_screen_scissor_scaling_factor_4 = NULL;
|
||||
uint8_t* ff13_message_box_stack_push_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_h;
|
||||
|
||||
|
@ -151,6 +155,7 @@ private:
|
|||
void FF13_SetFrameRateVariables();
|
||||
void FF13_FixScissorRect();
|
||||
void FF13_RemoveContinuousControllerScan();
|
||||
void FF13_HandleLargeAddressAwarePatch();
|
||||
|
||||
void FF13_2_CreateSetFrameRateCodeBlock();
|
||||
void FF13_2_InitializeGameAddresses();
|
||||
|
|
Loading…
Reference in a new issue