mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
Move frame limiter, add limiters for SFD & loading screen.
This commit is contained in:
parent
5ed5ff7ff0
commit
6bf029b0bb
5 changed files with 77 additions and 56 deletions
|
|
@ -6,35 +6,6 @@
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
#include <os/process.h>
|
#include <os/process.h>
|
||||||
|
|
||||||
void FrameLimiter::execute(int64_t fps)
|
|
||||||
{
|
|
||||||
using namespace std::chrono_literals;
|
|
||||||
|
|
||||||
auto now = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
if (now < next)
|
|
||||||
{
|
|
||||||
std::this_thread::sleep_for(std::chrono::floor<std::chrono::milliseconds>(next - now - 1ms));
|
|
||||||
|
|
||||||
while ((now = std::chrono::steady_clock::now()) < next)
|
|
||||||
std::this_thread::yield();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
next = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
next += 1000000000ns / fps;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FrameLimiter g_frameLimiter;
|
|
||||||
|
|
||||||
void ApplicationUpdateMidAsmHook()
|
|
||||||
{
|
|
||||||
if (Config::FPS >= 15 && Config::FPS < 240)
|
|
||||||
g_frameLimiter.execute(Config::FPS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::Restart(std::vector<std::string> restartArgs)
|
void App::Restart(std::vector<std::string> restartArgs)
|
||||||
{
|
{
|
||||||
os::process::StartProcess(os::process::GetExecutablePath(), restartArgs, os::process::GetWorkingDirectory());
|
os::process::StartProcess(os::process::GetExecutablePath(), restartArgs, os::process::GetWorkingDirectory());
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,6 @@
|
||||||
|
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
|
|
||||||
struct FrameLimiter
|
|
||||||
{
|
|
||||||
std::chrono::steady_clock::time_point next;
|
|
||||||
|
|
||||||
void execute(int64_t fps);
|
|
||||||
};
|
|
||||||
|
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -1896,17 +1896,17 @@ struct Profiler
|
||||||
double values[PROFILER_VALUE_COUNT];
|
double values[PROFILER_VALUE_COUNT];
|
||||||
std::chrono::steady_clock::time_point start;
|
std::chrono::steady_clock::time_point start;
|
||||||
|
|
||||||
void begin()
|
void Begin()
|
||||||
{
|
{
|
||||||
start = std::chrono::steady_clock::now();
|
start = std::chrono::steady_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void end()
|
void End()
|
||||||
{
|
{
|
||||||
value = std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start).count();
|
value = std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
double updateAndReturnAverage()
|
double UpdateAndReturnAverage()
|
||||||
{
|
{
|
||||||
values[g_profilerValueIndex] = value;
|
values[g_profilerValueIndex] = value;
|
||||||
return std::accumulate(values, values + PROFILER_VALUE_COUNT, 0.0) / PROFILER_VALUE_COUNT;
|
return std::accumulate(values, values + PROFILER_VALUE_COUNT, 0.0) / PROFILER_VALUE_COUNT;
|
||||||
|
|
@ -1939,7 +1939,7 @@ static void DrawProfiler()
|
||||||
if (ImGui::Begin("Profiler", &g_profilerVisible))
|
if (ImGui::Begin("Profiler", &g_profilerVisible))
|
||||||
{
|
{
|
||||||
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
|
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
|
||||||
double renderDirectorAvg = g_renderDirectorProfiler.updateAndReturnAverage();
|
double renderDirectorAvg = g_renderDirectorProfiler.UpdateAndReturnAverage();
|
||||||
|
|
||||||
if (ImPlot::BeginPlot("Frame Time"))
|
if (ImPlot::BeginPlot("Frame Time"))
|
||||||
{
|
{
|
||||||
|
|
@ -4849,7 +4849,7 @@ PPC_FUNC(sub_8258C8A0)
|
||||||
PPC_FUNC_IMPL(__imp__sub_8258CAE0);
|
PPC_FUNC_IMPL(__imp__sub_8258CAE0);
|
||||||
PPC_FUNC(sub_8258CAE0)
|
PPC_FUNC(sub_8258CAE0)
|
||||||
{
|
{
|
||||||
g_renderDirectorProfiler.begin();
|
g_renderDirectorProfiler.Begin();
|
||||||
|
|
||||||
if (g_needsResize)
|
if (g_needsResize)
|
||||||
{
|
{
|
||||||
|
|
@ -4864,7 +4864,7 @@ PPC_FUNC(sub_8258CAE0)
|
||||||
|
|
||||||
__imp__sub_8258CAE0(ctx, base);
|
__imp__sub_8258CAE0(ctx, base);
|
||||||
|
|
||||||
g_renderDirectorProfiler.end();
|
g_renderDirectorProfiler.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostProcessResolutionFix(PPCRegister& r4, PPCRegister& f1, PPCRegister& f2)
|
void PostProcessResolutionFix(PPCRegister& r4, PPCRegister& f1, PPCRegister& f2)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
|
#include <cpu/code_cache.h>
|
||||||
#include <cpu/guest_code.h>
|
#include <cpu/guest_code.h>
|
||||||
#include <api/SWA.h>
|
#include <api/SWA.h>
|
||||||
#include <ui/game_window.h>
|
#include <ui/game_window.h>
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
#include <app.h>
|
#include <app.h>
|
||||||
|
|
||||||
float m_lastLoadingFrameDelta = 0.0f;
|
|
||||||
std::chrono::high_resolution_clock::time_point m_lastLoadingFrameTime;
|
|
||||||
|
|
||||||
void DownForceDeltaTimeFixMidAsmHook(PPCRegister& f0)
|
void DownForceDeltaTimeFixMidAsmHook(PPCRegister& f0)
|
||||||
{
|
{
|
||||||
f0.f64 = 30.0;
|
f0.f64 = 30.0;
|
||||||
|
|
@ -79,14 +77,71 @@ void Camera2DSlopeLerpFixMidAsmHook(PPCRegister& t, PPCRegister& deltaTime)
|
||||||
t.f64 = ComputeLerpFactor(t.f64, deltaTime.f64 / 60.0);
|
t.f64 = ComputeLerpFactor(t.f64, deltaTime.f64 / 60.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadingScreenSpeedFixMidAsmHook(PPCRegister& r4)
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
static std::chrono::steady_clock::time_point g_next;
|
||||||
|
|
||||||
|
void ApplicationUpdateMidAsmHook()
|
||||||
{
|
{
|
||||||
auto now = std::chrono::high_resolution_clock::now();
|
if (Config::FPS >= 15 && Config::FPS < 240)
|
||||||
|
{
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
m_lastLoadingFrameDelta = std::min(std::chrono::duration<float>(now - m_lastLoadingFrameTime).count(), 1.0f / 15.0f);
|
if (now < g_next)
|
||||||
m_lastLoadingFrameTime = now;
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::floor<std::chrono::milliseconds>(g_next - now - 1ms));
|
||||||
|
|
||||||
auto pDeltaTime = (be<float>*)g_memory.Translate(r4.u32);
|
while ((now = std::chrono::steady_clock::now()) < g_next)
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_next = now;
|
||||||
|
}
|
||||||
|
|
||||||
*pDeltaTime = m_lastLoadingFrameDelta;
|
g_next += 1000000000ns / Config::FPS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::chrono::steady_clock::time_point g_prev;
|
||||||
|
|
||||||
|
bool LoadingUpdateMidAsmHook(PPCRegister& r31)
|
||||||
|
{
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
double deltaTime = std::min(std::chrono::duration<double>(now - g_prev).count(), 1.0 / 15.0);
|
||||||
|
g_prev = now;
|
||||||
|
|
||||||
|
uint8_t* base = reinterpret_cast<uint8_t*>(g_memory.base);
|
||||||
|
uint32_t application = PPC_LOAD_U32(PPC_LOAD_U32(r31.u32 + 4));
|
||||||
|
uint32_t update = PPC_LOAD_U32(PPC_LOAD_U32(application) + 20);
|
||||||
|
|
||||||
|
g_ppcContext->r3.u32 = application;
|
||||||
|
g_ppcContext->f1.f64 = deltaTime;
|
||||||
|
reinterpret_cast<PPCFunc*>(g_codeCache.Find(update))(*g_ppcContext, base);
|
||||||
|
|
||||||
|
bool loading = PPC_LOAD_U8(0x83367A4C);
|
||||||
|
if (loading)
|
||||||
|
{
|
||||||
|
now = std::chrono::steady_clock::now();
|
||||||
|
constexpr auto INTERVAL = 1000000000ns / 30;
|
||||||
|
auto next = now + (INTERVAL - now.time_since_epoch() % INTERVAL);
|
||||||
|
|
||||||
|
std::this_thread::sleep_until(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADXM_WaitVsync
|
||||||
|
PPC_FUNC_IMPL(__imp__sub_8312DBF8);
|
||||||
|
PPC_FUNC(sub_8312DBF8)
|
||||||
|
{
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
constexpr auto INTERVAL = 1000000000ns / 60;
|
||||||
|
auto next = now + (INTERVAL - now.time_since_epoch() % INTERVAL);
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::floor<std::chrono::milliseconds>(next - now - 1ms));
|
||||||
|
|
||||||
|
while (std::chrono::steady_clock::now() < next)
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
|
@ -425,11 +425,6 @@ name = "ParticleTestDrawIndexedPrimitiveMidAsmHook"
|
||||||
address = 0x827D25AC
|
address = 0x827D25AC
|
||||||
registers = ["r7"]
|
registers = ["r7"]
|
||||||
|
|
||||||
[[midasm_hook]]
|
|
||||||
name = "LoadingScreenSpeedFixMidAsmHook"
|
|
||||||
address = 0x824DAB60
|
|
||||||
registers = ["r4"]
|
|
||||||
|
|
||||||
[[midasm_hook]]
|
[[midasm_hook]]
|
||||||
name = "MotionBlurPrevInvViewProjectionMidAsmHook"
|
name = "MotionBlurPrevInvViewProjectionMidAsmHook"
|
||||||
address = 0x82BA9E7C
|
address = 0x82BA9E7C
|
||||||
|
|
@ -592,3 +587,10 @@ registers = ["r3"]
|
||||||
[[midasm_hook]]
|
[[midasm_hook]]
|
||||||
name = "ApplicationUpdateMidAsmHook"
|
name = "ApplicationUpdateMidAsmHook"
|
||||||
address = 0x822C0EC8
|
address = 0x822C0EC8
|
||||||
|
|
||||||
|
[[midasm_hook]]
|
||||||
|
name = "LoadingUpdateMidAsmHook"
|
||||||
|
address = 0x825360C8
|
||||||
|
registers = ["r31"]
|
||||||
|
jump_address_on_true = 0x825360C8
|
||||||
|
jump_address_on_false = 0x82536140
|
||||||
Loading…
Add table
Reference in a new issue