Workaround the 2560x1440 resolution bug
This commit is contained in:
parent
55fe5cf608
commit
cadb6d0eed
|
@ -38,7 +38,10 @@ By default the game forced a 60Hz refresh rate in full screen mode. With this mo
|
||||||
## Changes to where the memory is allocated on certain vertex buffers
|
## Changes to where the memory is allocated on certain vertex buffers
|
||||||
This considerably improves the frame rate when 2D elements are being disabled on the screen (i.e. minimap or battle menu HUD). This fix is not new, it is from [OneTweakNG](https://github.com/Nucleoprotein/OneTweakNG).
|
This considerably improves the frame rate when 2D elements are being disabled on the screen (i.e. minimap or battle menu HUD). This fix is not new, it is from [OneTweakNG](https://github.com/Nucleoprotein/OneTweakNG).
|
||||||
|
|
||||||
## Fix the enemy scan text on resolutions over 720p (FF13 only)
|
## Works around pixelated screen bug that happens when using 2560x1440 resolution
|
||||||
|
The internal resolution is reduced to 2559x1440 to workaround the issue.
|
||||||
|
|
||||||
|
## 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
|
## Reporting issues
|
||||||
|
|
|
@ -103,11 +103,9 @@ HRESULT APIENTRY MainContext::ApplyVertexBufferFix(IDirect3DDevice9* pIDirect3DD
|
||||||
return pIDirect3DDevice9->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle);
|
return pIDirect3DDevice9->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainContext::FF13_AsyncPatchingLoop() {
|
void MainContext::FF13_AsyncPatching() {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||||
if (*context.ff13_frame_pacer_ptr) {
|
context.FF13_OneTimeFixes();
|
||||||
context.FF13_OneTimeFixes();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainContext::FF13_InitializeGameAddresses()
|
void MainContext::FF13_InitializeGameAddresses()
|
||||||
|
@ -128,6 +126,7 @@ void MainContext::FF13_InitializeGameAddresses()
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainContext::FF13_OneTimeFixes() {
|
void MainContext::FF13_OneTimeFixes() {
|
||||||
|
MainContext::FF13_Workaround_2560_1440_Res_Bug();
|
||||||
MainContext::FF13_NOPIngameFrameRateLimitSetter();
|
MainContext::FF13_NOPIngameFrameRateLimitSetter();
|
||||||
MainContext::FF13_RemoveContinuousControllerScan();
|
MainContext::FF13_RemoveContinuousControllerScan();
|
||||||
MainContext::FF13_FixMissingEnemyScan();
|
MainContext::FF13_FixMissingEnemyScan();
|
||||||
|
@ -138,6 +137,17 @@ void MainContext::FF13_OneTimeFixes() {
|
||||||
context.didOneTimeFixes = true;
|
context.didOneTimeFixes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainContext::FF13_Workaround_2560_1440_Res_Bug()
|
||||||
|
{
|
||||||
|
if (*ff13_internal_res_w == 2560 && *ff13_internal_res_h == 1440) {
|
||||||
|
// We need to reduce one or another. Increasing the internal res causes crashes.
|
||||||
|
// Decreasing the internal res width by one pixel causes the last pixel column displayed on the screen to stay black.
|
||||||
|
PrintLog("Applying workaround for resolution 2560x1440 bug.");
|
||||||
|
*ff13_internal_res_w = 2559;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainContext::FF13_EnableControllerVibration()
|
void MainContext::FF13_EnableControllerVibration()
|
||||||
{
|
{
|
||||||
if (!config.GetFFXIIIEnableControllerVibration()) {
|
if (!config.GetFFXIIIEnableControllerVibration()) {
|
||||||
|
@ -257,7 +267,7 @@ void MainContext::FF13_SetFrameRateVariables() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainContext::FF13_2_AsyncPatchingLoop() {
|
void MainContext::FF13_2_AsyncPatching() {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||||
context.FF13_2_OneTimeFixes();
|
context.FF13_2_OneTimeFixes();
|
||||||
}
|
}
|
||||||
|
@ -268,6 +278,7 @@ void MainContext::FF13_2_OneTimeFixes() {
|
||||||
**ff13_2_frame_pacer_ptr_address = MAX_FRAME_RATE_LIMIT;
|
**ff13_2_frame_pacer_ptr_address = MAX_FRAME_RATE_LIMIT;
|
||||||
PrintLog("Frame pacer disabled");
|
PrintLog("Frame pacer disabled");
|
||||||
|
|
||||||
|
context.FF13_2_Workaround_2560_1440_Res_Bug();
|
||||||
context.FF13_2_AddHookIngameFrameRateLimitSetter();
|
context.FF13_2_AddHookIngameFrameRateLimitSetter();
|
||||||
context.FF13_2_RemoveContinuousControllerScan();
|
context.FF13_2_RemoveContinuousControllerScan();
|
||||||
context.FF13_2_EnableControllerVibration();
|
context.FF13_2_EnableControllerVibration();
|
||||||
|
@ -279,6 +290,17 @@ void MainContext::FF13_2_OneTimeFixes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainContext::FF13_2_Workaround_2560_1440_Res_Bug()
|
||||||
|
{
|
||||||
|
if (*ff13_2_internal_res_w == 2560 && *ff13_2_internal_res_h == 1440) {
|
||||||
|
// We need to reduce one or another. Increasing the internal res causes crashes.
|
||||||
|
// Decreasing the internal res width by one pixel causes the last pixel column displayed on the screen to stay black.
|
||||||
|
PrintLog("Applying workaround for resolution 2560x1440 bug.");
|
||||||
|
*ff13_2_internal_res_w = 2559;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MainContext::FF13_2_EnableControllerVibration()
|
void MainContext::FF13_2_EnableControllerVibration()
|
||||||
{
|
{
|
||||||
if (!config.GetFFXIIIEnableControllerVibration()) {
|
if (!config.GetFFXIIIEnableControllerVibration()) {
|
||||||
|
@ -316,6 +338,8 @@ void MainContext::FF13_2_InitializeGameAddresses()
|
||||||
ff13_2_base_controller_input_address_ptr = (uint8_t**)(baseAddr + 0x212A164);
|
ff13_2_base_controller_input_address_ptr = (uint8_t**)(baseAddr + 0x212A164);
|
||||||
ff13_2_vibration_low_set_zero_address = baseAddr + 0x2A7221;
|
ff13_2_vibration_low_set_zero_address = baseAddr + 0x2A7221;
|
||||||
ff13_2_vibration_high_set_zero_address = baseAddr + 0x2A7226;
|
ff13_2_vibration_high_set_zero_address = baseAddr + 0x2A7226;
|
||||||
|
ff13_2_internal_res_w = (uint32_t*)(baseAddr + 0x1FA864C);
|
||||||
|
ff13_2_internal_res_h = ff13_2_internal_res_w + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainContext::FF13_2_RemoveContinuousControllerScan() {
|
void MainContext::FF13_2_RemoveContinuousControllerScan() {
|
||||||
|
@ -404,7 +428,7 @@ void MainContext::ChangeMemoryProtectionToReadWriteExecute(void* address, const
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainContext::PrintVersionInfo() {
|
void MainContext::PrintVersionInfo() {
|
||||||
PrintLog("FF13Fix 1.4.3 https://github.com/rebtd7/FF13Fix");
|
PrintLog("FF13Fix 1.4.4 https://github.com/rebtd7/FF13Fix");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainContext::AreAlmostTheSame(float a, float b) {
|
bool MainContext::AreAlmostTheSame(float a, float b) {
|
||||||
|
|
|
@ -194,16 +194,16 @@ bool MainContext::CheckWindow(HWND hWnd)
|
||||||
if (!context.didOneTimeFixes) {
|
if (!context.didOneTimeFixes) {
|
||||||
if (context.autofix == FINAL_FANTASY_XIII && wcscmp(className.get(), L"SQEX.CDev.Engine.Framework.MainWindow") == 0) {
|
if (context.autofix == FINAL_FANTASY_XIII && wcscmp(className.get(), L"SQEX.CDev.Engine.Framework.MainWindow") == 0) {
|
||||||
const std::lock_guard<std::mutex> lock(context.oneTimeFixesMutex);
|
const std::lock_guard<std::mutex> lock(context.oneTimeFixesMutex);
|
||||||
if(!context.didOneTimeFixes){
|
if(!context.didOneTimeFixes && patchingThread == NULL){
|
||||||
PrintLog("Starting FFXIII one time RAM patches.");
|
PrintLog("Starting FFXIII one time RAM patches.");
|
||||||
patchingThread = new std::thread(&context.FF13_AsyncPatchingLoop);
|
patchingThread = new std::thread(&context.FF13_AsyncPatching);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (context.autofix == FINAL_FANTASY_XIII2 && wcscmp(className.get(), L"SQEX.CDev.Engine.Framework.MainWindow") == 0) {
|
else if (context.autofix == FINAL_FANTASY_XIII2 && wcscmp(className.get(), L"SQEX.CDev.Engine.Framework.MainWindow") == 0) {
|
||||||
const std::lock_guard<std::mutex> lock(context.oneTimeFixesMutex);
|
const std::lock_guard<std::mutex> lock(context.oneTimeFixesMutex);
|
||||||
if (!context.didOneTimeFixes) {
|
if (!context.didOneTimeFixes && patchingThread == NULL) {
|
||||||
PrintLog("Starting FFXIII-2 one time RAM patches.");
|
PrintLog("Starting FFXIII-2 one time RAM patches.");
|
||||||
patchingThread = new std::thread(&context.FF13_2_AsyncPatchingLoop);
|
patchingThread = new std::thread(&context.FF13_2_AsyncPatching);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,11 +95,13 @@ private:
|
||||||
uint8_t** ff13_2_base_controller_input_address_ptr = NULL;
|
uint8_t** ff13_2_base_controller_input_address_ptr = NULL;
|
||||||
uint8_t* ff13_2_vibration_high_set_zero_address = NULL;
|
uint8_t* ff13_2_vibration_high_set_zero_address = NULL;
|
||||||
uint8_t* ff13_2_vibration_low_set_zero_address = NULL;
|
uint8_t* ff13_2_vibration_low_set_zero_address = NULL;
|
||||||
|
uint32_t* ff13_2_internal_res_w;
|
||||||
|
uint32_t* ff13_2_internal_res_h;
|
||||||
|
|
||||||
const float FF13_2_30_FPS = 30.0F;
|
const float FF13_2_30_FPS = 30.0F;
|
||||||
const float FF13_2_MAX_FRAME_CAP = 1000.0F;
|
const float FF13_2_MAX_FRAME_CAP = 1000.0F;
|
||||||
XInputManager* xinputManager;
|
XInputManager* xinputManager;
|
||||||
std::thread * patchingThread;
|
std::thread * patchingThread = NULL;
|
||||||
|
|
||||||
void FixBehaviorFlagConflict(const DWORD flags_in, DWORD* flags_out);
|
void FixBehaviorFlagConflict(const DWORD flags_in, DWORD* flags_out);
|
||||||
static const std::map<const AutoFixes, const uint32_t> behaviorflags_fixes;
|
static const std::map<const AutoFixes, const uint32_t> behaviorflags_fixes;
|
||||||
|
@ -112,21 +114,23 @@ private:
|
||||||
void PrintVersionInfo();
|
void PrintVersionInfo();
|
||||||
|
|
||||||
|
|
||||||
static void FF13_AsyncPatchingLoop();
|
static void FF13_AsyncPatching();
|
||||||
void FF13_InitializeGameAddresses();
|
void FF13_InitializeGameAddresses();
|
||||||
void FF13_OneTimeFixes();
|
void FF13_OneTimeFixes();
|
||||||
|
void FF13_Workaround_2560_1440_Res_Bug();
|
||||||
void FF13_EnableControllerVibration();
|
void FF13_EnableControllerVibration();
|
||||||
void FF13_NOPIngameFrameRateLimitSetter();
|
void FF13_NOPIngameFrameRateLimitSetter();
|
||||||
void FF13_SetFrameRateVariables();
|
void FF13_SetFrameRateVariables();
|
||||||
void FF13_FixMissingEnemyScan();
|
void FF13_FixMissingEnemyScan();
|
||||||
void FF13_RemoveContinuousControllerScan();
|
void FF13_RemoveContinuousControllerScan();
|
||||||
|
|
||||||
static void FF13_2_AsyncPatchingLoop();
|
static void FF13_2_AsyncPatching();
|
||||||
void FF13_2_CreateSetFrameRateCodeBlock();
|
void FF13_2_CreateSetFrameRateCodeBlock();
|
||||||
void FF13_2_InitializeGameAddresses();
|
void FF13_2_InitializeGameAddresses();
|
||||||
void FF13_2_RemoveContinuousControllerScan();
|
void FF13_2_RemoveContinuousControllerScan();
|
||||||
void FF13_2_AddHookIngameFrameRateLimitSetter();
|
void FF13_2_AddHookIngameFrameRateLimitSetter();
|
||||||
void FF13_2_OneTimeFixes();
|
void FF13_2_OneTimeFixes();
|
||||||
|
void FF13_2_Workaround_2560_1440_Res_Bug();
|
||||||
void FF13_2_EnableControllerVibration();
|
void FF13_2_EnableControllerVibration();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue