Skip to content

Commit

Permalink
Fix stutter elimination code for new patch
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaldaien authored Apr 28, 2017
1 parent 37cb0c9 commit 6252e30
Showing 1 changed file with 69 additions and 33 deletions.
102 changes: 69 additions & 33 deletions nier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <SpecialK/steam_api.h>

#include <SpecialK/input/input.h>
#include <SpecialK/input/xinput.h>

#include <SpecialK/hooks.h>
#include <SpecialK/core.h>
#include <process.h>
Expand All @@ -21,7 +23,7 @@
#include <atlbase.h>


#define FAR_VERSION_NUM L"0.5.4.3"
#define FAR_VERSION_NUM L"0.5.6"
#define FAR_VERSION_STR L"FAR v " FAR_VERSION_NUM

// Block until update finishes, otherwise the update dialog
Expand All @@ -30,6 +32,12 @@
volatile LONG __FAR_init = FALSE;


//#define WORKING_FPS_UNCAP
//#define WORKING_CAMERA_CONTROLS
//#define WORKING_GAMESTATES
#define WORKING_FPS_SLEEP_FIX


struct far_game_state_s {
// Game state addresses courtesy of Francesco149
DWORD* pMenu = (DWORD *)0x1418F39C4;
Expand All @@ -44,8 +52,8 @@ struct far_game_state_s {
bool patchable = false; // True only if the memory addresses can be validated

bool needFPSCap (void) {
return enforce_cap || ( *pMenu != 0) || (*pLoading != 0) ||
(*pHacking != 0) || (*pShortcuts != 0);
return enforce_cap; //|| ( *pMenu != 0) || (*pLoading != 0) ||
//(*pHacking != 0) || (*pShortcuts != 0);
}

void capFPS (void);
Expand Down Expand Up @@ -106,8 +114,8 @@ struct far_cam_state_s {
focus_lock = false;

SK_Keybind center_binding {
"Camera Center Lock Toggle", L"Ctrl+Shift+F10",
true, true, false, VK_F10
"Camera Center Lock Toggle", L"Num /",
true, true, false, VK_DIVIDE
};

SK_Keybind focus_binding {
Expand Down Expand Up @@ -376,14 +384,20 @@ SK_FAR_SetFramerateCap (bool enable)
}
}

// Altimor's FPS cap removal
//
uint8_t* psleep = (uint8_t *)0x14092E887; // Original pre-patch
uint8_t* pspinlock = (uint8_t *)0x14092E8CF; // +0x48
uint8_t* pmin_tstep = (uint8_t *)0x140805DEC; // Original pre-patch
uint8_t* pmax_tstep = (uint8_t *)0x140805E18; // +0x2c

bool
SK_FAR_SetLimiterWait (SK_FAR_WaitBehavior behavior)
{
const uint8_t sleep_wait [] = { 0xFF, 0x15, 0xD3, 0x4B, 0x2C, 0x06 };
const uint8_t busy_wait [] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
static uint8_t sleep_wait [] = { 0x7e, 0x08, 0x8b, 0xca, 0xff, 0x15 };
static uint8_t busy_wait [] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };

static bool init = false;
static LPVOID wait_addr = 0x0;
static bool init = false;

// Square-Enix rarely patches the games they publish, so just search for this pattern and
// don't bother to adjust memory addresses... if it's not found using the hard-coded address,
Expand All @@ -392,37 +406,50 @@ SK_FAR_SetLimiterWait (SK_FAR_WaitBehavior behavior)
{
init = true;

if ( (wait_addr = SK_Scan ( sleep_wait, 6, nullptr )) == nullptr )
if ( (psleep = (uint8_t *)SK_Scan ( sleep_wait, 6, nullptr )) == nullptr )
{
dll_log.Log (L"[ FARLimit ] Could not locate Framerate Limiter Sleep Addr.");
}
else {
dll_log.Log (L"[ FARLimit ] Scanned Framerate Limiter Sleep Addr.: 0x%p", wait_addr);
psleep += 4;
dll_log.Log (L"[ FARLimit ] Scanned Framerate Limiter Sleep Addr.: 0x%p", psleep);
memcpy (sleep_wait, psleep, 6);

pspinlock = psleep + 0x48;


uint8_t tstep0 [] = { 0x73, 0x1C, 0xC7, 0x05, 0x00, 0x00 };
uint8_t tstep0_mask [] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 };

pmin_tstep = (uint8_t *)SK_Scan ( tstep0, sizeof tstep0, tstep0_mask );
pmax_tstep = pmin_tstep + 0x2c;

dll_log.Log (L"[ FARLimit ] Scanned Framerate Limiter TStepMin Addr.: 0x%p", pmin_tstep);
}
}

if (wait_addr == nullptr)
if (psleep == nullptr)
return false;

wait_behavior = behavior;

DWORD dwProtect;
VirtualProtect (wait_addr, 6, PAGE_EXECUTE_READWRITE, &dwProtect);
VirtualProtect (psleep, 6, PAGE_EXECUTE_READWRITE, &dwProtect);

// Hard coded for now; safe to do this without pausing threads and flushing caches
// because the config UI runs from the only thread that the game framerate limits.
switch (behavior)
{
case SK_FAR_WaitBehavior::Busy:
memcpy (wait_addr, busy_wait, 6);
memcpy (psleep, busy_wait, 6);
break;

case SK_FAR_WaitBehavior::Sleep:
memcpy (wait_addr, sleep_wait, 6);
memcpy (psleep, sleep_wait, 6);
break;
}

VirtualProtect (wait_addr, 6, dwProtect, &dwProtect);
VirtualProtect (psleep, 6, dwProtect, &dwProtect);

return true;
}
Expand Down Expand Up @@ -450,7 +477,7 @@ SK_FAR_EndFrame (void)
if (far_osd_disclaimer->get_value ())
SK_DrawExternalOSD ( "FAR", " Press Ctrl + Shift + O to toggle In-Game OSD\n"
" Press Ctrl + Shift + Backspace to access In-Game Config Menu\n"
" ( Select + Start )\n\n"
" ( Select + Start on Gamepads )\n\n"
" * This message will go away the first time you actually read it and successfully toggle the OSD.\n" );
else if (config.system.log_level == 1)
{
Expand Down Expand Up @@ -553,6 +580,7 @@ SK_FAR_EndFrame (void)
}
}

#ifdef WORKING_CAMERA_CONTROLS
XINPUT_STATE state;
if (__FAR_Freelook && SK_XInput_PollController (0, &state))
{
Expand Down Expand Up @@ -632,6 +660,7 @@ SK_FAR_EndFrame (void)
(*far_cam.pCamera) [0] = pos [0] + dX;
(*far_cam.pCamera) [2] = pos [2] + dY;
}
#endif
}


Expand Down Expand Up @@ -693,9 +722,11 @@ SK_FAR_PluginKeyPress (BOOL Control, BOOL Shift, BOOL Alt, BYTE vkCode)

switch (uiMaskedKeyCode)
{
#ifdef WORKING_FPS_UNCAP
case SK_ControlShiftKey (VK_OEM_PERIOD):
SK_FAR_SetFramerateCap (game_state.enforce_cap);
break;
#endif

case SK_ControlShiftKey (VK_OEM_6): // ']'
{
Expand Down Expand Up @@ -1458,18 +1489,21 @@ SK_FAR_PSSetShaderResources (
{
static ID3D11ShaderResourceView* views [256];

for (UINT i = 0; i < NumViews; i++)
if (ppShaderResourceViews != nullptr)
{
views [i] = ppShaderResourceViews [i];
for (UINT i = 0; i < NumViews; i++)
{
views [i] = ppShaderResourceViews [i];

if (far_ao.views.count (ppShaderResourceViews [i]) && far_ao.disable) {
views [i] = nullptr;
far_ao.active = true;
}
if (far_ao.views.count (ppShaderResourceViews [i]) && far_ao.disable) {
views [i] = nullptr;
far_ao.active = true;
}

else if (far_bloom.views.count (ppShaderResourceViews [i]) && far_bloom.disable) {
views [i] = nullptr;
far_bloom.active = true;
else if (far_bloom.views.count (ppShaderResourceViews [i]) && far_bloom.disable) {
views [i] = nullptr;
far_bloom.active = true;
}
}
}

Expand Down Expand Up @@ -1657,6 +1691,11 @@ typedef void (WINAPI *D3D11_DrawInstancedIndirect_pfn)(
far_uncap_fps->store ();
}

#ifndef WORKING_FPS_UNCAP
// FORCE OFF UNTIL I CAN FIX
far_uncap_fps->set_value (false);
#endif


far_rtss_warned =
static_cast <sk::ParameterBool *>
Expand Down Expand Up @@ -2151,6 +2190,7 @@ SK_FAR_ControlPanel (void)
bool remove_cap = far_uncap_fps->get_value ();
bool busy_wait = (wait_behavior == SK_FAR_WaitBehavior::Busy);

#ifdef WORKING_FPS_UNCAP
if (ImGui::Checkbox ("Remove 60 FPS Cap ", &remove_cap))
{
changed = true;
Expand All @@ -2175,6 +2215,7 @@ SK_FAR_ControlPanel (void)
}

ImGui::SameLine ();
#endif

if (ImGui::Checkbox ("Use Busy-Wait For Capped FPS", &busy_wait))
{
Expand All @@ -2195,6 +2236,7 @@ SK_FAR_ControlPanel (void)
ImGui::TreePop ();
}

#ifdef WORKING_CAMERA_CONTROLS
if (ImGui::CollapsingHeader ("Camera and HUD"))
{
auto Keybinding = [](SK_Keybind* binding, sk::ParameterStringW* param) ->
Expand Down Expand Up @@ -2265,6 +2307,7 @@ SK_FAR_ControlPanel (void)

ImGui::TreePop ();
}
#endif

ImGui::TreePop ( );
ImGui::PopStyleColor (3);
Expand Down Expand Up @@ -2300,13 +2343,6 @@ SK_FAR_IsPlugIn (void)



// Altimor's FPS cap removal
//
uint8_t* psleep = (uint8_t *)0x14092E887;
uint8_t* pspinlock = (uint8_t *)0x14092E8CF;
uint8_t* pmin_tstep = (uint8_t *)0x140805DEC;
uint8_t* pmax_tstep = (uint8_t *)0x140805E18;

void
far_game_state_s::uncapFPS (void)
{
Expand Down

0 comments on commit 6252e30

Please sign in to comment.