From 85c3bde7e354a841af93fff37218598bf1296915 Mon Sep 17 00:00:00 2001 From: Isaac0-dev <62234577+Isaac0-dev@users.noreply.github.com> Date: Thu, 9 May 2024 23:56:54 +1000 Subject: [PATCH] improve frame delaying and vsync (#31) use uncapped framerate and vsync for the best experience --- data/dynos_mgr_tex.cpp | 24 ++++++++++++------------ src/pc/djui/djui_fps_display.c | 2 +- src/pc/djui/djui_fps_display.h | 2 +- src/pc/pc_main.c | 19 +++++++------------ src/pc/utils/misc.c | 2 ++ 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/data/dynos_mgr_tex.cpp b/data/dynos_mgr_tex.cpp index f16cf0cf..f07f922a 100644 --- a/data/dynos_mgr_tex.cpp +++ b/data/dynos_mgr_tex.cpp @@ -456,7 +456,7 @@ static inline bool IsPowerOfTwo(int n) { } bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) { - #define CONVERT_TEXINFO { \ + #define CONVERT_TEXINFO() { \ /* translate bit size */ \ switch (_Data->mRawSize) { \ case G_IM_SIZ_8b: aOutTexInfo->bitSize = 8; break; \ @@ -499,23 +499,23 @@ bool DynOS_Tex_Get(const char* aTexName, struct TextureInfo* aOutTexInfo) { free(_RawData); } - CONVERT_TEXINFO; + CONVERT_TEXINFO(); return true; } } - // check valid textures - for (DataNode* _Node : DynosValidTextures()) { - if (_Node->mName == aTexName) { - auto& _Data = _Node->mData; - CONVERT_TEXINFO; - return true; - } - }; - // check builtin textures const struct BuiltinTexInfo* info = DynOS_Builtin_Tex_GetInfoFromName(aTexName); - if (!info) { return false; } + if (!info) { + for (DataNode* _Node : DynosValidTextures()) { // check valid textures + if (_Node->mName == aTexName) { + auto& _Data = _Node->mData; + CONVERT_TEXINFO(); + return true; + } + } + return false; + } aOutTexInfo->bitSize = info->bitSize; aOutTexInfo->width = info->width; aOutTexInfo->height = info->height; diff --git a/src/pc/djui/djui_fps_display.c b/src/pc/djui/djui_fps_display.c index 702882cd..72aa6084 100644 --- a/src/pc/djui/djui_fps_display.c +++ b/src/pc/djui/djui_fps_display.c @@ -8,7 +8,7 @@ struct DjuiFpsDisplay { struct DjuiFpsDisplay *sFpsDisplay = NULL; -void djui_fps_display_update(s16 fps) { +void djui_fps_display_update(u16 fps) { if (configShowFPS) { char fpsText[30] = ""; snprintf(fpsText, 30, "\\#dcdcdc\\FPS: \\#ffffff\\%d", fps); diff --git a/src/pc/djui/djui_fps_display.h b/src/pc/djui/djui_fps_display.h index f398fed0..c40218d2 100644 --- a/src/pc/djui/djui_fps_display.h +++ b/src/pc/djui/djui_fps_display.h @@ -1,7 +1,7 @@ #pragma once #include "djui.h" -void djui_fps_display_update(s16 fps); +void djui_fps_display_update(u16 fps); void djui_fps_display_render(void); void djui_fps_display_create(void); void djui_fps_display_destroy(void); diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 6c70df67..82e8f64a 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -80,8 +80,6 @@ u32 gNumVblanks = 0; u8 gRenderingInterpolated = 0; f32 gRenderingDelta = 0; -f64 gGameSpeed = 1.0f; // TODO: should probably remove - #define FRAMERATE 30 static const f64 sFrameTime = (1.0 / ((double)FRAMERATE)); static f64 sFrameTargetTime = 0; @@ -172,26 +170,23 @@ void produce_interpolation_frames_and_delay(void) { gRenderingInterpolated = true; - // sanity check target time to deal with hangs and such - if (fabs(sFrameTargetTime - curTime) > 1) { sFrameTargetTime = curTime - 0.01f; } - // interpolate and render while ((curTime = clock_elapsed_f64()) < sFrameTargetTime) { gfx_start_frame(); - f32 delta = MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1); + f32 delta = (!configUncappedFramerate && configFrameLimit == FRAMERATE) ? 1 : MAX(MIN((curTime - sFrameTimeStart) / (sFrameTargetTime - sFrameTimeStart), 1), 0); gRenderingDelta = delta; - if (!gSkipInterpolationTitleScreen && (configFrameLimit > 30 || configUncappedFramerate)) { patch_interpolations(delta); } + if (!gSkipInterpolationTitleScreen) { patch_interpolations(delta); } send_display_list(gGfxSPTask); gfx_end_frame(); // delay - if (!configUncappedFramerate) { + if (!configUncappedFramerate && !configWindow.vsync) { f64 targetDelta = 1.0 / (f64) configFrameLimit; f64 now = clock_elapsed_f64(); f64 actualDelta = now - curTime; if (actualDelta < targetDelta) { f64 delay = ((targetDelta - actualDelta) * 1000.0); - WAPI.delay((u32) delay); + if (delay > 0) { WAPI.delay((u32) delay * 0.9); } } } @@ -205,15 +200,15 @@ void produce_interpolation_frames_and_delay(void) { u64 sCurrentFpsUpdateTime = (u64)clock_elapsed_f64(); if (sLastFpsUpdateTime != sCurrentFpsUpdateTime) { - u32 fps = sFramesSinceFpsUpdate / ((f32)(sCurrentFpsUpdateTime - sLastFpsUpdateTime)); + u32 fps = sFramesSinceFpsUpdate / (sCurrentFpsUpdateTime - sLastFpsUpdateTime); sLastFpsUpdateTime = sCurrentFpsUpdateTime; sFramesSinceFpsUpdate = 0; - djui_fps_display_update(floor(fps)); + djui_fps_display_update(fps); } sFrameTimeStart = sFrameTargetTime; - sFrameTargetTime += sFrameTime * gGameSpeed; + sFrameTargetTime += sFrameTime; gRenderingInterpolated = false; } diff --git a/src/pc/utils/misc.c b/src/pc/utils/misc.c index 302a888a..416d58ed 100644 --- a/src/pc/utils/misc.c +++ b/src/pc/utils/misc.c @@ -40,6 +40,7 @@ static void _clock_gettime(struct timespec* clock_time) { #ifdef DEVELOPMENT // give each instance a random offset for testing purposed + /* static s32 randomOffset1 = 0; static s32 randomOffset2 = 0; if (randomOffset1 == 0) { @@ -50,6 +51,7 @@ static void _clock_gettime(struct timespec* clock_time) { } clock_time->tv_sec += randomOffset1; clock_time->tv_nsec += randomOffset2; + */ #endif }