Implement AnyFPS + option to queue one rendered frame (#401)

This commit is contained in:
Emill 2022-05-29 18:16:23 +02:00 committed by GitHub
commit ccab94c765
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 298 additions and 89 deletions

View file

@ -175,8 +175,6 @@ extern "C" void Graph_StartFrame() {
// C->C++ Bridge
extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
OTRGlobals::Instance->context->GetWindow()->SetFrameDivisor(CVar_GetS32("g60FPS", 0) == 0 ? R_UPDATE_RATE : 1);
if (!audio.initialized) {
audio.initialized = true;
std::thread([]() {
@ -226,15 +224,45 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
audio.cv_to_thread.notify_one();
std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements;
if (CVar_GetS32("g60FPS", 0) != 0) {
int to = R_UPDATE_RATE;
for (int i = 1; i < to; i++) {
mtx_replacements.push_back(FrameInterpolation_Interpolate(i / (float)to));
int target_fps = CVar_GetS32("gInterpolationFPS", 20);
static int last_fps;
static int last_update_rate;
static int time;
int fps = target_fps;
int original_fps = 60 / R_UPDATE_RATE;
if (target_fps == 20 || original_fps > target_fps) {
fps = original_fps;
}
if (last_fps != fps || last_update_rate != R_UPDATE_RATE) {
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;
OTRGlobals::Instance->context->GetWindow()->SetTargetFps(fps);
int threshold = CVar_GetS32("gExtraLatencyThreshold", 80);
OTRGlobals::Instance->context->GetWindow()->SetMaximumFrameLatency(threshold > 0 && target_fps >= threshold ? 2 : 1);
OTRGlobals::Instance->context->GetWindow()->RunCommands(commands, mtx_replacements);
last_fps = fps;
last_update_rate = R_UPDATE_RATE;
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (audio.processing) {

View file

@ -451,7 +451,7 @@ void FrameInterpolation_StartRecord(void) {
current_recording = {};
current_path.clear();
current_path.push_back(&current_recording.root_path);
if (CVar_GetS32("g60FPS", 0) != 0) {
if (CVar_GetS32("gInterpolationFPS", 20) != 20) {
is_recording = true;
}
}

View file

@ -2290,8 +2290,8 @@ void Actor_DrawFaroresWindPointer(GlobalContext* globalCtx) {
((void)0, gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y) + yOffset,
((void)0, gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z), 255, 255, 255, lightRadius);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 5474);
}
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 5474);
}
void func_80030488(GlobalContext* globalCtx) {

View file

@ -5,6 +5,8 @@
#include "textures/title_static/title_static.h"
#include "textures/parameter_static/parameter_static.h"
#include "soh/frame_interpolation.h"
static s16 sUnused = 106;
static s16 sScreenFillAlpha = 255;
@ -1136,6 +1138,8 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
FileChoose_SetWindowVtx(&this->state);
FileChoose_SetWindowContentVtx(&this->state);
FrameInterpolation_RecordOpenChild(this, this->configMode);
if ((this->configMode != CM_NAME_ENTRY) && (this->configMode != CM_START_NAME_ENTRY)) {
gDPPipeSync(POLY_OPA_DISP++);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
@ -1227,6 +1231,8 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
gDPPipeSync(POLY_OPA_DISP++);
FileChoose_SetView(this, 0.0f, 0.0f, 64.0f);
FrameInterpolation_RecordCloseChild();
CLOSE_DISPS(this->state.gfxCtx, "../z_file_choose.c", 2352);
}
@ -1669,7 +1675,9 @@ void FileChoose_Main(GameState* thisx) {
FileChoose_PulsateCursor(&this->state);
gFileSelectUpdateFuncs[this->menuMode](&this->state);
FrameInterpolation_StartRecord();
gFileSelectDrawFuncs[this->menuMode](&this->state);
FrameInterpolation_StopRecord();
// do not draw controls text in the options menu
if ((this->configMode <= CM_NAME_ENTRY_TO_MAIN) || (this->configMode >= CM_UNUSED_DELAY)) {