diff --git a/libs/JSystem/src/JUtility/JUTFader.cpp b/libs/JSystem/src/JUtility/JUTFader.cpp index 599ae22720..e7d33454b7 100644 --- a/libs/JSystem/src/JUtility/JUTFader.cpp +++ b/libs/JSystem/src/JUtility/JUTFader.cpp @@ -8,6 +8,10 @@ #include "JSystem/JUtility/JUTFader.h" #include "JSystem/J2DGraph/J2DOrthoGraph.h" +#ifdef TARGET_PC +#include +#endif + JUTFader::JUTFader(int x, int y, int width, int height, JUtility::TColor pColor) : mColor(pColor), mBox(x, y, x + width, y + height) { mStatus = None; @@ -63,14 +67,24 @@ void JUTFader::advance() { void JUTFader::control() { advance(); -#ifndef TARGET_PC - // FRAME INTERP NOTE: Draw is called by JFWDisplay when interpolation is active draw(); -#endif } void JUTFader::draw() { if (mColor.a != 0) { +#ifdef TARGET_PC + if (dusk::frame_interp::is_enabled() && mDuration != 0) { + const auto step = dusk::frame_interp::get_interpolation_step(); + const auto progress = static_cast(mTimer) / static_cast(mDuration); + const auto timer = mTimer - 1 + step + progress; + auto alpha = timer / mDuration; + if (mStatus == FadeIn) { + alpha = 1.0f - alpha; + } + alpha = std::clamp(alpha, 0.0f, 1.0f); + mColor.a = static_cast(alpha * 255.0f); + } +#endif J2DOrthoGraph orthograph; orthograph.setColor(mColor); orthograph.fillBox(mBox); diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 8e13c6271f..0adf6d4bd6 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -11262,6 +11262,26 @@ static int camera_execute(camera_process_class* i_this) { return 1; } +#ifdef TARGET_PC +void set_ar_corrected_trim(dDlst_window_c* window, float trim_height) { + const auto viewport = window->getViewPort(); + + if (mDoGph_gInf_c::isWideZoom()) { + const auto target_ar = FB_WIDTH / (FB_HEIGHT - trim_height * 2.0f); + const auto current_ar = mDoGph_gInf_c::m_safeWidthF / mDoGph_gInf_c::m_safeHeightF; + + if (current_ar < target_ar) { + trim_height = FB_HEIGHT / 2.0f * (1.0f - current_ar / target_ar); + } else { + trim_height = 0.0f; + } + } + + trim_height *= viewport->height / FB_HEIGHT; + window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f); +} +#endif + static int camera_draw(camera_process_class* i_this) { camera_class* a_this = (camera_class*)i_this; dCamera_c* body = &i_this->mCamera; @@ -11315,21 +11335,40 @@ static int camera_draw(camera_process_class* i_this) { #endif #if TARGET_PC - auto trim_height = body->TrimHeight(); + set_ar_corrected_trim(window, body->TrimHeight()); - if (mDoGph_gInf_c::isWideZoom()) { - const auto target_ar = FB_WIDTH / (FB_HEIGHT - trim_height * 2.0f); - const auto current_ar = mDoGph_gInf_c::m_safeWidthF / mDoGph_gInf_c::m_safeHeightF; + if (dusk::getSettings().game.enableFrameInterpolation) { + dusk::frame_interp::add_interpolation_callback([](bool _, void* pUserWork) { + const auto i_this = static_cast(pUserWork); + const auto camera = &i_this->mCamera; - if (current_ar < target_ar) { - trim_height = FB_HEIGHT / 2.0f * (1.0f - current_ar / target_ar); - } else { - trim_height = 0.0f; - } + const auto trim_size = camera->mTrimSize; + + if (camera->mCurState != 2 && trim_size >= 0 && trim_size <= 3) { + // derive trim height at previous tick using current camera state + f32 target; + switch (trim_size) { + case 0: + target = 0.0f; + break; + case 1: + target = camera->mCamSetup.VistaTrimHeight(); + break; + case 2: + case 3: + target = camera->mCamSetup.CinemaScopeTrimHeight(); + break; + } + + const auto step = dusk::frame_interp::get_interpolation_step(); + const auto cur = camera->TrimHeight(); + const auto prev = (4.0f * cur - target) / 3.0f; + const auto trim_height = prev + (cur - prev) * step; + + set_ar_corrected_trim(get_window((camera_class*)i_this), trim_height); + } + }, i_this); } - - trim_height *= viewport->height / FB_HEIGHT; - window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f); #else int trim_height = body->TrimHeight(); diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index b6a53e15a5..61eaf3bc2d 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -502,6 +502,14 @@ void mDoGph_gInf_c::calcFade() { } if (mFadeColor.a != 0) { +#ifdef TARGET_PC + if (dusk::frame_interp::is_enabled() && mFade != 0) { + const auto step = dusk::frame_interp::get_interpolation_step(); + const auto progress = mFadeSpeed < 0.0f ? 1.0f - mFadeRate : mFadeRate; + const auto fade_amt = mFadeRate + mFadeSpeed * (step - 1.0f + progress); + mFadeColor.a = 255.0f * std::clamp(fade_amt, 0.0f, 1.0f); + } +#endif darwFilter(mFadeColor); } }