mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-05 02:37:50 -04:00
feat: FPS Limiter (#1446)
* Add interpolation frame rate cap * wip: reworked framelimiter Based on my testing this is a bit more stable in frametimes. * wip: efficiency improvement + windows build fix Significantly improve efficiency by using a hybrid approach. * wip: UI changes * wip: end frame AFTER limiting * wip: remove unused include * wip: minor ui code change Makes it easier to remove/add presets * Simplify Limiter UI - Change enableFrameInterpolation to an enum with off/capped/unlimited values - Simplify the UI to use 2 settings (unlock framerate + a max value entry) * wip: slight limiter simplification * wip: implement review suggestions * wip: fix syntax error * wip: revert enum order + replace old checks * Fix compile error --------- Co-authored-by: SailorSnoW <sailorsnow@pm.me> Co-authored-by: Loïs <49660929+SailorSnoW@users.noreply.github.com> Co-authored-by: SuperDude88 <82904174+SuperDude88@users.noreply.github.com> Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
@@ -5990,7 +5990,7 @@ void daAlink_c::setItemMatrix(int param_0) {
|
||||
|
||||
mDoMtx_stack_c::XrotS(-0x8000);
|
||||
#ifdef TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
Mtx boot_mtx;
|
||||
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), boot_mtx);
|
||||
mpLinkBootModels[1]->setAnmMtx(1, boot_mtx);
|
||||
@@ -19767,7 +19767,7 @@ int daAlink_c::draw() {
|
||||
dComIfGd_getOpaListDark()->entryImm(mpHookChain, 0);
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation &&
|
||||
if (dusk::frame_interp::is_enabled() &&
|
||||
mEquipItem == dItemNo_IRONBALL_e &&
|
||||
mIronBallChainPos != NULL && mIronBallChainAngle != NULL)
|
||||
{
|
||||
|
||||
@@ -397,7 +397,7 @@ static int daB_GND_Draw(b_gnd_class* i_this) {
|
||||
i_this->field_0x21e8.update(2, l_color, &a_this->tevStr);
|
||||
dComIfGd_set3DlineMat(&i_this->field_0x21e8);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mReinsInterpCurrValid) {
|
||||
memcpy(i_this->mReinsInterpPrev, i_this->mReinsInterpCurr, sizeof(i_this->mReinsInterpCurr));
|
||||
memcpy(i_this->mReinsTexInterpPrev, i_this->mReinsTexInterpCurr, sizeof(i_this->mReinsTexInterpCurr));
|
||||
|
||||
@@ -116,7 +116,7 @@ static int daE_DB_Draw(e_db_class* i_this) {
|
||||
i_this->stalkLine.update(12, l_color, &actor->tevStr);
|
||||
dComIfGd_set3DlineMat(&i_this->stalkLine);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mStalkLineInterpCurrValid) {
|
||||
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
|
||||
i_this->mStalkLineInterpPrevValid = true;
|
||||
|
||||
@@ -103,7 +103,7 @@ static int daE_HB_Draw(e_hb_class* i_this) {
|
||||
i_this->stalkLine.update(12, l_color, &actor->tevStr);
|
||||
dComIfGd_set3DlineMat(&i_this->stalkLine);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mStalkLineInterpCurrValid) {
|
||||
memcpy(i_this->mStalkLineInterpPrev, i_this->mStalkLineInterpCurr, sizeof(i_this->mStalkLineInterpCurr));
|
||||
i_this->mStalkLineInterpPrevValid = true;
|
||||
|
||||
@@ -105,7 +105,7 @@ static int daE_MB_Draw(e_mb_class* i_this) {
|
||||
i_this->mRopeMat.update(16, l_color, &a_this->tevStr);
|
||||
dComIfGd_set3DlineMat(&i_this->mRopeMat);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mRopeInterpCurrValid) {
|
||||
memcpy(i_this->mRopeInterpPrev, i_this->mRopeInterpCurr, sizeof(i_this->mRopeInterpCurr));
|
||||
i_this->mRopeInterpPrevValid = true;
|
||||
|
||||
@@ -161,7 +161,7 @@ static int daE_S1_Draw(e_s1_class* i_this) {
|
||||
dComIfGd_set3DlineMatDark(&i_this->mLineMat);
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mHairInterpCurrValid) {
|
||||
memcpy(i_this->mHairInterpPrev, i_this->mHairInterpCurr, sizeof(i_this->mHairInterpCurr));
|
||||
i_this->mHairInterpPrevValid = true;
|
||||
|
||||
@@ -535,7 +535,7 @@ static int daE_WB_Draw(e_wb_class* i_this) {
|
||||
i_this->himo_tex.update(2, l_color, &actor->tevStr);
|
||||
dComIfGd_set3DlineMat(&i_this->himo_tex);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->himo_interp_curr_valid) {
|
||||
memcpy(i_this->himo_mat_interp_prev, i_this->himo_mat_interp_curr, sizeof(i_this->himo_mat_interp_curr));
|
||||
memcpy(i_this->himo_tex_interp_prev, i_this->himo_tex_interp_curr, sizeof(i_this->himo_tex_interp_curr));
|
||||
|
||||
@@ -107,7 +107,7 @@ static s32 daE_YD_Draw(e_yd_class* i_this) {
|
||||
i_this->mLineMat.update(12, l_color, &i_this->actor.tevStr);
|
||||
dComIfGd_set3DlineMat(&i_this->mLineMat);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mLineMatInterpCurrValid) {
|
||||
memcpy(i_this->mLineMatInterpPrev, i_this->mLineMatInterpCurr, sizeof(i_this->mLineMatInterpCurr));
|
||||
i_this->mLineMatInterpPrevValid = true;
|
||||
|
||||
@@ -191,7 +191,7 @@ static int daE_YG_Draw(e_yg_class* i_this) {
|
||||
dComIfGd_set3DlineMatDark(&i_this->mLineMat);
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mTentacleInterpCurrValid) {
|
||||
memcpy(i_this->mTentacleInterpPrev, i_this->mTentacleInterpCurr, sizeof(i_this->mTentacleInterpCurr));
|
||||
i_this->mTentacleInterpPrevValid = true;
|
||||
|
||||
@@ -135,7 +135,7 @@ static int daE_YH_Draw(e_yh_class* i_this) {
|
||||
i_this->mLine.update(12, l_color, &a_this->tevStr);
|
||||
dComIfGd_set3DlineMat(&i_this->mLine);
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (i_this->mLineInterpCurrValid) {
|
||||
memcpy(i_this->mLineInterpPrev, i_this->mLineInterpCurr, sizeof(i_this->mLineInterpCurr));
|
||||
i_this->mLineInterpPrevValid = true;
|
||||
|
||||
@@ -3165,7 +3165,7 @@ void daHorse_c::setReinPosNormalSubstance() {
|
||||
#if TARGET_PC
|
||||
void daHorse_c::lerpControlPoints(f32 alpha) {
|
||||
// FRAME INTERP NOTE: Currently only lerping points for Epona's reins. Need a more global solution.
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation || !s_horseReinSimPrevValid || !s_horseReinSimCurrValid) {
|
||||
if (!dusk::frame_interp::is_enabled() || !s_horseReinSimPrevValid || !s_horseReinSimCurrValid) {
|
||||
return;
|
||||
}
|
||||
const int nCurr = s_horseReinSimNumCurr;
|
||||
|
||||
@@ -325,7 +325,7 @@ int daObjFchain_c::draw() {
|
||||
dComIfGd_getOpaListDark()->entryImm(&mShape, 0);
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (mChainInterpCurrValid) {
|
||||
memcpy(mChainInterpPrev, mChainInterpCurr, sizeof(mChainInterpCurr));
|
||||
mChainInterpPrevValid = true;
|
||||
|
||||
@@ -493,7 +493,7 @@ int daObjKLift00_c::Draw() {
|
||||
dComIfGd_setList();
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
if (mChainInterpCurrValid) {
|
||||
memcpy(mChainInterpPrev, mChainInterpCurr, mNumChains * sizeof(cXyz));
|
||||
mChainInterpPrevValid = true;
|
||||
|
||||
@@ -170,7 +170,7 @@ int daTitle_c::Execute() {
|
||||
}
|
||||
|
||||
#ifdef TARGET_PC
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (!dusk::frame_interp::is_enabled()) {
|
||||
#endif
|
||||
dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
|
||||
#ifdef TARGET_PC
|
||||
@@ -354,7 +354,7 @@ void daTitle_c::fastLogoDispInit() {
|
||||
mProcID = 5;
|
||||
|
||||
#ifdef TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
dusk::frame_interp::request_presentation_sync();
|
||||
}
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -10431,7 +10431,7 @@ bool dCamera_c::eventCamera(s32 param_0) {
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
switch (var_r29) {
|
||||
case 3:
|
||||
case 4:
|
||||
@@ -11322,7 +11322,7 @@ static int camera_execute(camera_process_class* i_this) {
|
||||
#ifdef TARGET_PC
|
||||
widezoom_correction(i_this, i_this->mCamera.TrimHeight());
|
||||
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
dusk::frame_interp::add_interpolation_callback([](bool _, void* pUserWork) {
|
||||
const auto i_this = static_cast<camera_process_class*>(pUserWork);
|
||||
const auto camera = &i_this->mCamera;
|
||||
|
||||
@@ -991,7 +991,7 @@ void dMenu_DmapBg_c::draw() {
|
||||
-35.0f + (local_224.x - local_218.x),
|
||||
-35.0f + (local_224.y - local_218.y));
|
||||
#if TARGET_PC
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (!dusk::frame_interp::is_enabled()) {
|
||||
field_0xdda = 0;
|
||||
}
|
||||
#else
|
||||
@@ -2624,7 +2624,7 @@ void dMenu_Dmap_c::zoomIn_proc() {
|
||||
|
||||
void dMenu_Dmap_c::zoomOut_init_proc() {
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
mpDrawBg->resetScrollArrowMask();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1146,7 +1146,7 @@ void dMenu_Fmap_c::zoom_spot_to_region_init() {
|
||||
field_0x1ec = 1.0f;
|
||||
#if TARGET_PC
|
||||
// Frame interp note: field_0x122d used to be set every draw, causing flickering. Do it here instead.
|
||||
if (dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (dusk::frame_interp::is_enabled()) {
|
||||
mpDraw2DBack->resetScrollArrowMask();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -437,7 +437,7 @@ void dMenu_Fmap2DBack_c::draw() {
|
||||
if (field_0x122d) {
|
||||
mpMeterHaihai->drawHaihai(field_0x122d);
|
||||
#if TARGET_PC
|
||||
if (!dusk::getSettings().game.enableFrameInterpolation) {
|
||||
if (!dusk::frame_interp::is_enabled()) {
|
||||
field_0x122d = 0;
|
||||
}
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user