Skip to content

Commit

Permalink
Workaround the 2560x1440 resolution bug
Browse files Browse the repository at this point in the history
  • Loading branch information
rebtd7 authored Feb 10, 2020
1 parent 55fe5cf commit cadb6d0
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 14 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
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.

## Reporting issues
Expand Down
36 changes: 30 additions & 6 deletions d3d9ex/AutoFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,9 @@ HRESULT APIENTRY MainContext::ApplyVertexBufferFix(IDirect3DDevice9* pIDirect3DD
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));
if (*context.ff13_frame_pacer_ptr) {
context.FF13_OneTimeFixes();
}
context.FF13_OneTimeFixes();
}

void MainContext::FF13_InitializeGameAddresses()
Expand All @@ -128,6 +126,7 @@ void MainContext::FF13_InitializeGameAddresses()
}

void MainContext::FF13_OneTimeFixes() {
MainContext::FF13_Workaround_2560_1440_Res_Bug();
MainContext::FF13_NOPIngameFrameRateLimitSetter();
MainContext::FF13_RemoveContinuousControllerScan();
MainContext::FF13_FixMissingEnemyScan();
Expand All @@ -138,6 +137,17 @@ void MainContext::FF13_OneTimeFixes() {
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()
{
if (!config.GetFFXIIIEnableControllerVibration()) {
Expand Down Expand Up @@ -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));
context.FF13_2_OneTimeFixes();
}
Expand All @@ -268,6 +278,7 @@ void MainContext::FF13_2_OneTimeFixes() {
**ff13_2_frame_pacer_ptr_address = MAX_FRAME_RATE_LIMIT;
PrintLog("Frame pacer disabled");

context.FF13_2_Workaround_2560_1440_Res_Bug();
context.FF13_2_AddHookIngameFrameRateLimitSetter();
context.FF13_2_RemoveContinuousControllerScan();
context.FF13_2_EnableControllerVibration();
Expand All @@ -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()
{
if (!config.GetFFXIIIEnableControllerVibration()) {
Expand Down Expand Up @@ -316,6 +338,8 @@ void MainContext::FF13_2_InitializeGameAddresses()
ff13_2_base_controller_input_address_ptr = (uint8_t**)(baseAddr + 0x212A164);
ff13_2_vibration_low_set_zero_address = baseAddr + 0x2A7221;
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() {
Expand Down Expand Up @@ -404,7 +428,7 @@ void MainContext::ChangeMemoryProtectionToReadWriteExecute(void* address, const
}

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) {
Expand Down
8 changes: 4 additions & 4 deletions d3d9ex/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,16 @@ bool MainContext::CheckWindow(HWND hWnd)
if (!context.didOneTimeFixes) {
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);
if(!context.didOneTimeFixes){
if(!context.didOneTimeFixes && patchingThread == NULL){
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) {
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.");
patchingThread = new std::thread(&context.FF13_2_AsyncPatchingLoop);
patchingThread = new std::thread(&context.FF13_2_AsyncPatching);
}
}
}
Expand Down
10 changes: 7 additions & 3 deletions d3d9ex/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,13 @@ class MainContext
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_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_MAX_FRAME_CAP = 1000.0F;
XInputManager* xinputManager;
std::thread * patchingThread;
std::thread * patchingThread = NULL;

void FixBehaviorFlagConflict(const DWORD flags_in, DWORD* flags_out);
static const std::map<const AutoFixes, const uint32_t> behaviorflags_fixes;
Expand All @@ -112,21 +114,23 @@ class MainContext
void PrintVersionInfo();


static void FF13_AsyncPatchingLoop();
static void FF13_AsyncPatching();
void FF13_InitializeGameAddresses();
void FF13_OneTimeFixes();
void FF13_Workaround_2560_1440_Res_Bug();
void FF13_EnableControllerVibration();
void FF13_NOPIngameFrameRateLimitSetter();
void FF13_SetFrameRateVariables();
void FF13_FixMissingEnemyScan();
void FF13_RemoveContinuousControllerScan();

static void FF13_2_AsyncPatchingLoop();
static void FF13_2_AsyncPatching();
void FF13_2_CreateSetFrameRateCodeBlock();
void FF13_2_InitializeGameAddresses();
void FF13_2_RemoveContinuousControllerScan();
void FF13_2_AddHookIngameFrameRateLimitSetter();
void FF13_2_OneTimeFixes();
void FF13_2_Workaround_2560_1440_Res_Bug();
void FF13_2_EnableControllerVibration();
};

Expand Down

0 comments on commit cadb6d0

Please sign in to comment.