improve frame delaying and vsync (#31)

use uncapped framerate and vsync for the best experience
This commit is contained in:
Isaac0-dev 2024-05-09 23:56:54 +10:00 committed by GitHub
parent e3bfbb65b1
commit 85c3bde7e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 23 additions and 26 deletions

View file

@ -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<TexData>* _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<TexData>* _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;

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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
}