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 <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)
|
||||
{
|
||||
os::process::StartProcess(os::process::GetExecutablePath(), restartArgs, os::process::GetWorkingDirectory());
|
||||
|
|
|
|||
|
|
@ -2,13 +2,6 @@
|
|||
|
||||
#include <user/config.h>
|
||||
|
||||
struct FrameLimiter
|
||||
{
|
||||
std::chrono::steady_clock::time_point next;
|
||||
|
||||
void execute(int64_t fps);
|
||||
};
|
||||
|
||||
class App
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -1896,17 +1896,17 @@ struct Profiler
|
|||
double values[PROFILER_VALUE_COUNT];
|
||||
std::chrono::steady_clock::time_point start;
|
||||
|
||||
void begin()
|
||||
void Begin()
|
||||
{
|
||||
start = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void end()
|
||||
void End()
|
||||
{
|
||||
value = std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start).count();
|
||||
}
|
||||
|
||||
double updateAndReturnAverage()
|
||||
double UpdateAndReturnAverage()
|
||||
{
|
||||
values[g_profilerValueIndex] = value;
|
||||
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))
|
||||
{
|
||||
g_applicationValues[g_profilerValueIndex] = App::s_deltaTime * 1000.0;
|
||||
double renderDirectorAvg = g_renderDirectorProfiler.updateAndReturnAverage();
|
||||
double renderDirectorAvg = g_renderDirectorProfiler.UpdateAndReturnAverage();
|
||||
|
||||
if (ImPlot::BeginPlot("Frame Time"))
|
||||
{
|
||||
|
|
@ -4849,7 +4849,7 @@ PPC_FUNC(sub_8258C8A0)
|
|||
PPC_FUNC_IMPL(__imp__sub_8258CAE0);
|
||||
PPC_FUNC(sub_8258CAE0)
|
||||
{
|
||||
g_renderDirectorProfiler.begin();
|
||||
g_renderDirectorProfiler.Begin();
|
||||
|
||||
if (g_needsResize)
|
||||
{
|
||||
|
|
@ -4864,7 +4864,7 @@ PPC_FUNC(sub_8258CAE0)
|
|||
|
||||
__imp__sub_8258CAE0(ctx, base);
|
||||
|
||||
g_renderDirectorProfiler.end();
|
||||
g_renderDirectorProfiler.End();
|
||||
}
|
||||
|
||||
void PostProcessResolutionFix(PPCRegister& r4, PPCRegister& f1, PPCRegister& f2)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
#include <cpu/code_cache.h>
|
||||
#include <cpu/guest_code.h>
|
||||
#include <api/SWA.h>
|
||||
#include <ui/game_window.h>
|
||||
#include <user/config.h>
|
||||
#include <app.h>
|
||||
|
||||
float m_lastLoadingFrameDelta = 0.0f;
|
||||
std::chrono::high_resolution_clock::time_point m_lastLoadingFrameTime;
|
||||
|
||||
void DownForceDeltaTimeFixMidAsmHook(PPCRegister& f0)
|
||||
{
|
||||
f0.f64 = 30.0;
|
||||
|
|
@ -79,14 +77,71 @@ void Camera2DSlopeLerpFixMidAsmHook(PPCRegister& t, PPCRegister& deltaTime)
|
|||
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);
|
||||
m_lastLoadingFrameTime = now;
|
||||
if (now < g_next)
|
||||
{
|
||||
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
|
||||
registers = ["r7"]
|
||||
|
||||
[[midasm_hook]]
|
||||
name = "LoadingScreenSpeedFixMidAsmHook"
|
||||
address = 0x824DAB60
|
||||
registers = ["r4"]
|
||||
|
||||
[[midasm_hook]]
|
||||
name = "MotionBlurPrevInvViewProjectionMidAsmHook"
|
||||
address = 0x82BA9E7C
|
||||
|
|
@ -592,3 +587,10 @@ registers = ["r3"]
|
|||
[[midasm_hook]]
|
||||
name = "ApplicationUpdateMidAsmHook"
|
||||
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