aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2019-03-20 01:31:40 +0100
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2019-03-20 01:31:40 +0100
commita8a1f8236fff67cbae595600abc7a9dfbf6e231d (patch)
treef689c90eaf4ed896c24077a577150da2af9a6e78
parent7a7c5d5055953301c9046d3543dc5325db236e29 (diff)
downloadtermgl-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.cpp64
-rw-r--r--src/cRender.h30
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);