diff options
author | Jonas Gunz <himself@jonasgunz.de> | 2019-03-20 01:31:40 +0100 |
---|---|---|
committer | Jonas Gunz <himself@jonasgunz.de> | 2019-03-20 01:31:40 +0100 |
commit | a8a1f8236fff67cbae595600abc7a9dfbf6e231d (patch) | |
tree | f689c90eaf4ed896c24077a577150da2af9a6e78 | |
parent | 7a7c5d5055953301c9046d3543dc5325db236e29 (diff) | |
download | termgl-a8a1f8236fff67cbae595600abc7a9dfbf6e231d.tar.gz |
+cRender():setTargetFPS(uint) to set target Framerate
if set >1 render sleeps until target frametime is reached
-rw-r--r-- | src/cRender.cpp | 64 | ||||
-rw-r--r-- | src/cRender.h | 30 |
2 files changed, 89 insertions, 5 deletions
diff --git a/src/cRender.cpp b/src/cRender.cpp index 57b06a7..71c4d76 100644 --- a/src/cRender.cpp +++ b/src/cRender.cpp @@ -11,6 +11,10 @@ cRender::cRender(char _backound, WORD _color, unsigned int _sx, unsigned int _sy cBackound = _backound; wBackColor = _color; + uTargetFPS = 0; + lastFrameTime = 0; + lastRenderTime = 0; + #ifdef __linux__ //In Linux, setting Console size is not supported, so it gets Size of Console (Window) instead. wDefColor = _COL_DEFAULT; @@ -188,9 +192,16 @@ int cRender::render(void) if (bBlockRender) return _ERR_RENDER_BLOCKED_BY_CHILD_; + waitForFrametime(); + //Resize screenbuffer if needed setBufferSize( getConsoleWindowSize( ) ); + printDebugInfo(); + + //For measuring render time + clock_t startTime = clock(); + for (unsigned int i = 0; i < sizeY; i++) { for (unsigned int o = 0; o < sizeX; o++) { if(bChanged[o][i]) @@ -236,6 +247,18 @@ int cRender::render(void) bChanged[o][i] = false; } } + + //calc render time + lastRenderTime = clock() - startTime; + + //calc time since last render + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + lastFrameTime = (now.tv_sec - lastRender.tv_sec); + lastFrameTime += (now.tv_nsec - lastRender.tv_nsec) / 1000000000.0; + //save current time + clock_gettime(CLOCK_MONOTONIC, &lastRender); + return 0; } @@ -417,3 +440,44 @@ void cRender::setConsoleEcho(bool _enable) _enable ? write (STDOUT_FILENO, "\e[?8h", 5) : write (STDOUT_FILENO, "\e[?8l", 5); #endif //__linux__ } + +double cRender::getFrametime() +{ + return lastFrameTime; +} + +void cRender::setTargetFPS(unsigned int _fps) +{ + uTargetFPS = _fps; +} + +void cRender::printDebugInfo() +{ + char dbgtxt[30]; + + sprintf(dbgtxt, "R: %f F: %f", ((float)lastRenderTime) / CLOCKS_PER_SEC, 1/getFrametime()); + + drawText(dbgtxt, {0,0}, _COL_BLACK | _COL_WHITE_BG); +} + +void cRender::waitForFrametime() +{ + if(!uTargetFPS) + return; + + timespec now; + double elapsed; + double left; + clock_gettime(CLOCK_MONOTONIC, &now); + elapsed = (now.tv_sec - lastRender.tv_sec); + elapsed += (now.tv_nsec - lastRender.tv_nsec) / 1000000000.0; + + if(elapsed > (1/(double)uTargetFPS)) + return; + + left = (1/(double)uTargetFPS) - elapsed - (((double)lastRenderTime) / CLOCKS_PER_SEC); + + std::this_thread::sleep_for(std::chrono::milliseconds(int (left * 1000))); + + +} diff --git a/src/cRender.h b/src/cRender.h index 42c3388..19a0367 100644 --- a/src/cRender.h +++ b/src/cRender.h @@ -5,6 +5,9 @@ #include <string> #include <cmath> #include <termios.h> +#include <time.h> //clock() +#include <chrono> +#include <thread> #ifdef __linux__ #include <unistd.h> @@ -131,6 +134,14 @@ public: */ sPos getSize(); + /** Time in (real) seconds between last and second to last renders + */ + double getFrametime(); + + /** Sets target Framerate. 0 for unlimited + */ + void setTargetFPS(unsigned int _fps); + protected: /** Empty Constructor for being inheritable @@ -159,6 +170,12 @@ protected: unsigned int sizeX, sizeY; //* Size of screen array + //Timekeeping + unsigned int uTargetFPS; + clock_t lastRenderTime; + double lastFrameTime; + timespec lastRender; + #ifdef _WIN32 HANDLE hstdout; CONSOLE_SCREEN_BUFFER_INFO csbi; @@ -170,17 +187,20 @@ protected: int iLastError; private: + void forceReRender(); + + void setConsoleEcho(bool _enable); + + void printDebugInfo(); + + void waitForFrametime(); #ifdef _WIN32 int SetConsoleWindowSize(int x, int y); //Slightly adapted from: http://www.cplusplus.com/forum/windows/121444/ void gotoxy( int x, int y ); -#endif - - void forceReRender(); - void setConsoleEcho(bool _enable); -#ifdef __linux__ +#elif __linux__ sPos getConsoleWindowSize(); void setConsoleCursor(bool _enable); |