diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 788af51ab..669e24504 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -24,6 +24,7 @@ #include "window/gui/resource/FontFactory.h" #include "SpaghettiGui.h" +#include "port/interpolation/FrameInterpolation.h" #include #include //#include @@ -225,6 +226,28 @@ bool GameEngine::GenAssetFile() { return extractor->GenerateOTR(); } +uint32_t GameEngine::GetInterpolationFPS() { + if (CVarGetInteger("gMatchRefreshRate", 0)) { + return Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); + + } else if (CVarGetInteger("gVsyncEnabled", 1) || + !Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { + return std::min(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(), + CVarGetInteger("gInterpolationFPS", 60)); + } + + return CVarGetInteger("gInterpolationFPS", 60); +} + +uint32_t GameEngine::GetInterpolationFrameCount() +{ + return ceil((float)GetInterpolationFPS() / (60.0f / 2 /*gVIsPerFrame*/)); +} + +extern "C" uint32_t GameEngine_GetInterpolationFrameCount() { + return GameEngine::GetInterpolationFrameCount(); +} + void GameEngine::ShowMessage(const char* title, const char* message, SDL_MessageBoxFlags type) { #if defined(__SWITCH__) SPDLOG_ERROR(message); @@ -321,6 +344,36 @@ void GameEngine::RunCommands(Gfx* Commands) { } void GameEngine::ProcessGfxCommands(Gfx* commands) { + std::vector> mtx_replacements; + int target_fps = GameEngine::Instance->GetInterpolationFPS(); + static int last_fps; + static int last_update_rate; + static int time; + int fps = target_fps; + int original_fps = 60 / 2 /*gVIsPerFrame*/; + + if (target_fps == 20 || original_fps > target_fps) { + fps = original_fps; + } + + if (last_fps != fps || last_update_rate != 2 /*gVIsPerFrame*/) { + time = 0; + } + + // time_base = fps * original_fps (one second) + int next_original_frame = fps; + + while (time + original_fps <= next_original_frame) { + time += original_fps; + if (time != next_original_frame) { + mtx_replacements.push_back(FrameInterpolation_Interpolate((float) time / next_original_frame)); + } else { + mtx_replacements.emplace_back(); + } + } + + time -= fps; + auto wnd = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()); if (wnd != nullptr) { wnd->SetTargetFps(CVarGetInteger("gInterpolationFPS", 30)); diff --git a/src/port/Engine.h b/src/port/Engine.h index cd10ae431..4a4b25439 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -60,6 +60,7 @@ class GameEngine { static void AudioExit(); static uint32_t GetInterpolationFPS(); + static uint32_t GetInterpolationFrameCount(); void StartFrame() const; static void RunCommands(Gfx* Commands); void ProcessFrame(void (*run_one_game_iter)()) const; diff --git a/src/port/interpolation/FrameInterpolation.cpp b/src/port/interpolation/FrameInterpolation.cpp index dcc49a025..386561be8 100644 --- a/src/port/interpolation/FrameInterpolation.cpp +++ b/src/port/interpolation/FrameInterpolation.cpp @@ -5,7 +5,7 @@ #include #include #include "port/Engine.h" - +#include #include "FrameInterpolation.h" /* @@ -181,6 +181,8 @@ Data& append(Op op) { return m.emplace_back(); } +extern "C" {extern Mat4* gInterpolationMatrix;} + MtxF* Matrix_GetCurrent(){ return (MtxF*) gInterpolationMatrix; } diff --git a/src/port/interpolation/FrameInterpolation.h b/src/port/interpolation/FrameInterpolation.h index 2c5ab1278..77d08b9c0 100644 --- a/src/port/interpolation/FrameInterpolation.h +++ b/src/port/interpolation/FrameInterpolation.h @@ -15,6 +15,8 @@ extern "C" { #endif + + void FrameInterpolation_ShouldInterpolateFrame(bool shouldInterpolate); void FrameInterpolation_StartRecord(void);