From 146e0294b47281e2b0d1fe7ee7302d35c0989def Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sat, 3 Jan 2015 18:48:09 +0100 Subject: [PATCH] Add option to fix the framerate to the native screen refresh rate Useful on mobile devices where using non-standard framerates looks absolutely horrible and screen refresh rates vary highly. --- mkxp.conf.sample | 11 +++++++++++ src/config.cpp | 2 ++ src/config.h | 1 + src/eventthread.h | 3 +++ src/graphics.cpp | 18 +++++++++++++++--- src/main.cpp | 15 ++++++++++++--- 6 files changed, 44 insertions(+), 6 deletions(-) diff --git a/mkxp.conf.sample b/mkxp.conf.sample index 589ae1e..31f2aae 100644 --- a/mkxp.conf.sample +++ b/mkxp.conf.sample @@ -88,6 +88,17 @@ # frameSkip=true +# Use a fixed framerate that is approx. equal to the +# native screen refresh rate. This is different from +# "fixedFramerate" because the actual frame rate is +# reported back to the game, ensuring correct timers. +# If the screen refresh rate cannot be determined, +# this option is force-disabled +# (default: disabled) +# +# syncToRefreshrate=false + + # Don't use alpha blending when rendering text # (default: disabled) # diff --git a/src/config.cpp b/src/config.cpp index fb2e676..091ea92 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -152,6 +152,7 @@ Config::Config() defScreenH(0), fixedFramerate(0), frameSkip(true), + syncToRefreshrate(false), solidFonts(false), subImageFix(false), gameFolder("."), @@ -181,6 +182,7 @@ void Config::read(int argc, char *argv[]) PO_DESC(defScreenH, int) \ PO_DESC(fixedFramerate, int) \ PO_DESC(frameSkip, bool) \ + PO_DESC(syncToRefreshrate, bool) \ PO_DESC(solidFonts, bool) \ PO_DESC(subImageFix, bool) \ PO_DESC(gameFolder, std::string) \ diff --git a/src/config.h b/src/config.h index 71cfb42..9117fc0 100644 --- a/src/config.h +++ b/src/config.h @@ -86,6 +86,7 @@ struct Config int fixedFramerate; bool frameSkip; + bool syncToRefreshrate; bool solidFonts; diff --git a/src/eventthread.h b/src/eventthread.h index 164148e..1414f37 100644 --- a/src/eventthread.h +++ b/src/eventthread.h @@ -187,6 +187,7 @@ struct RGSSThreadData Vec2 sizeResoRatio; Vec2i screenOffset; + const int refreshRate; Config config; @@ -196,12 +197,14 @@ struct RGSSThreadData const char *argv0, SDL_Window *window, ALCdevice *alcDev, + int refreshRate, const Config& newconf) : ethread(ethread), argv0(argv0), window(window), alcDev(alcDev), sizeResoRatio(1, 1), + refreshRate(refreshRate), config(newconf) {} }; diff --git a/src/graphics.cpp b/src/graphics.cpp index 76fb02c..2f31077 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -628,10 +628,19 @@ Graphics::Graphics(RGSSThreadData *data) { p = new GraphicsPrivate(data); - if (data->config.fixedFramerate > 0) - p->fpsLimiter.setDesiredFPS(data->config.fixedFramerate); - else if (data->config.fixedFramerate < 0) + if (data->config.syncToRefreshrate) + { + p->frameRate = data->refreshRate; p->fpsLimiter.disabled = true; + } + else if (data->config.fixedFramerate > 0) + { + p->fpsLimiter.setDesiredFPS(data->config.fixedFramerate); + } + else if (data->config.fixedFramerate < 0) + { + p->fpsLimiter.disabled = true; + } } Graphics::~Graphics() @@ -798,6 +807,9 @@ void Graphics::setFrameRate(int value) { p->frameRate = clamp(value, 10, 120); + if (p->threadData->config.syncToRefreshrate) + return; + if (p->threadData->config.fixedFramerate > 0) return; diff --git a/src/main.cpp b/src/main.cpp index 4a87c28..890d7e6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,13 +68,14 @@ printGLInfo() int rgssThreadFun(void *userdata) { RGSSThreadData *threadData = static_cast(userdata); + const Config &conf = threadData->config; SDL_Window *win = threadData->window; SDL_GLContext glCtx; /* Setup GL context */ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (threadData->config.debugMode) + if (conf.debugMode) SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); glCtx = SDL_GL_CreateContext(win); @@ -103,7 +104,8 @@ int rgssThreadFun(void *userdata) printGLInfo(); - SDL_GL_SetSwapInterval(threadData->config.vsync ? 1 : 0); + bool vsync = conf.vsync || conf.syncToRefreshrate; + SDL_GL_SetSwapInterval(vsync ? 1 : 0); GLDebugLogger dLogger; @@ -283,9 +285,16 @@ int main(int argc, char *argv[]) return 0; } + SDL_DisplayMode mode; + SDL_GetDisplayMode(0, 0, &mode); + + /* Can't sync to display refresh rate if its value is unknown */ + if (!mode.refresh_rate) + conf.syncToRefreshrate = false; + EventThread eventThread; RGSSThreadData rtData(&eventThread, argv[0], win, - alcDev, conf); + alcDev, mode.refresh_rate, conf); int winW, winH; SDL_GetWindowSize(win, &winW, &winH);