mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 05:13:39 -07:00
Implement AnyFPS + option to queue one rendered frame (#401)
This commit is contained in:
parent
90a33e9756
commit
ccab94c765
14 changed files with 298 additions and 89 deletions
|
@ -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) {
|
||||
|
|
|
@ -451,7 +451,7 @@ void FrameInterpolation_StartRecord(void) {
|
|||
current_recording = {};
|
||||
current_path.clear();
|
||||
current_path.push_back(¤t_recording.root_path);
|
||||
if (CVar_GetS32("g60FPS", 0) != 0) {
|
||||
if (CVar_GetS32("gInterpolationFPS", 20) != 20) {
|
||||
is_recording = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue