improve frame delaying and vsync (#31)
use uncapped framerate and vsync for the best experience
This commit is contained in:
parent
e3bfbb65b1
commit
85c3bde7e3
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue