diff --git a/config.h b/config.h index 169a708..4f3a3b2 100644 --- a/config.h +++ b/config.h @@ -18,5 +18,7 @@ #define CFG_VID_DEFDISPLAY "-1" #define CFG_VID_DEFFULLSCREEN "0" #define CFG_VID_DEFRESIZABLE "0" +#define CFG_VID_DEFFGFPS "30" +#define CFG_VID_DEFBGFPS "5" #define CFG_VID_MINWIDTH 1080 #define CFG_VID_MINHEIGHT 720 \ No newline at end of file diff --git a/engine/core/core_video.cpp b/engine/core/core_video.cpp index f6bfcf1..2e1b630 100644 --- a/engine/core/core_video.cpp +++ b/engine/core/core_video.cpp @@ -48,6 +48,8 @@ class core_video_c: public core_IVideo, public conCmdHandler_c { conVar_c* vid_fullscreen; conVar_c* vid_resizable; conVar_c* vid_last; + conVar_c* vid_fgfps; + conVar_c* vid_bgfps; void C_Vid_Apply(IConsole* conHnd, args_c &args); void C_Vid_ModeList(IConsole* conHnd, args_c &args); @@ -71,6 +73,8 @@ core_video_c::core_video_c(sys_IMain* sysHnd) vid_fullscreen = sys->con->Cvar_Add("vid_fullscreen", CV_ARCHIVE, CFG_VID_DEFFULLSCREEN); vid_resizable = sys->con->Cvar_Add("vid_resizable", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFRESIZABLE, 0, 3); vid_last = sys->con->Cvar_Add("vid_last", CV_ARCHIVE, ""); + vid_fgfps = sys->con->Cvar_Add("vid_fgfps", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFFGFPS, 5, 120); + vid_bgfps = sys->con->Cvar_Add("vid_bgfps", CV_ARCHIVE|CV_CLAMP, CFG_VID_DEFBGFPS, 5, 120); Cmd_Add("vid_apply", 0, "", this, &core_video_c::C_Vid_Apply); Cmd_Add("vid_modeList", 0, "", this, &core_video_c::C_Vid_ModeList); @@ -111,6 +115,8 @@ void core_video_c::Apply(bool shown) set.depth = 0; set.minSize[0] = CFG_VID_MINWIDTH; set.minSize[1] = CFG_VID_MINHEIGHT; + set.fgfps = vid_fgfps->intVal; + set.bgfps = vid_bgfps->intVal; sys->video->Apply(&set); } diff --git a/engine/system/sys_video.h b/engine/system/sys_video.h index 461a95e..b5bff56 100644 --- a/engine/system/sys_video.h +++ b/engine/system/sys_video.h @@ -22,6 +22,8 @@ struct sys_vidSave_s { int size[2] = {}; int pos[2] = {}; bool maximised = false; + int fgfps = 0; + int bgfps = 0; }; // Video settings structure @@ -32,6 +34,8 @@ struct sys_vidSet_s { int mode[2] = {}; // Resolution or window size int depth = 0; // Bit depth int minSize[2] = {}; // Minimum size for resizable windows + int fgfps = 0; // Foreground FPS limit + int bgfps = 0; // Background FPS limit sys_vidSave_s save; // Saved state }; diff --git a/engine/system/win/sys_video.cpp b/engine/system/win/sys_video.cpp index 6d8d81b..6eedae3 100644 --- a/engine/system/win/sys_video.cpp +++ b/engine/system/win/sys_video.cpp @@ -275,6 +275,9 @@ int sys_video_c::Apply(sys_vidSet_s* set) vid.size[0] = wrec.right; vid.size[1] = wrec.bottom; + vid.fgfps = cur.fgfps; + vid.bgfps = cur.bgfps; + // Process any messages generated during application sys->RunMessages(); diff --git a/ui_main.cpp b/ui_main.cpp index f9622e0..17be353 100644 --- a/ui_main.cpp +++ b/ui_main.cpp @@ -6,6 +6,9 @@ #include "ui_local.h" +#include +#include + // ====== // Locals // ====== @@ -373,6 +376,8 @@ void ui_main_c::ScriptInit() void ui_main_c::Frame() { + const auto frameStart = std::chrono::high_resolution_clock::now(); + auto fpsLimit = sys->video->vid.fgfps; if (!sys->video->IsVisible() || sys->conWin->IsVisible() || restartFlag || didExit) { framesSinceWindowHidden = 0; } @@ -380,8 +385,7 @@ void ui_main_c::Frame() framesSinceWindowHidden++; } else if (!sys->video->IsActive() && !sys->video->IsCursorOverWindow()) { - sys->Sleep(100); - return; + fpsLimit = sys->video->vid.bgfps; } if (renderer) { @@ -425,8 +429,8 @@ void ui_main_c::Frame() } //sys->con->Printf("Finishing up...\n"); - if ( !sys->video->IsActive() ) { - sys->Sleep(100); + if ( sys->video->IsActive() ) { + fpsLimit = sys->video->vid.fgfps; } while (restartFlag) { @@ -436,6 +440,14 @@ void ui_main_c::Frame() } ScriptInit(); } + + using FpMilliseconds = std::chrono::duration; + const auto minimumFrameDuration = FpMilliseconds(1000.0f / fpsLimit); + const auto frameEnd = std::chrono::high_resolution_clock::now(); + const auto frameDuration = std::chrono::duration_cast(frameEnd - frameStart); + if (frameDuration < minimumFrameDuration) { + std::this_thread::sleep_for(minimumFrameDuration - frameDuration); + } } void ui_main_c::ScriptShutdown()