From: matthew <matthew@owens.tech>
Date: Tue, 9 Oct 2018 18:45:13 +0000 (+0100)
Subject: implemented semi-fixed timestep
X-Git-Url: https://git.owens.tech/112-editable-focus.html/112-editable-focus.html/git?a=commitdiff_plain;h=e818add9382ecb967b290ead5991fc570b05ff8c;p=csrpg.git

implemented semi-fixed timestep
---

diff --git a/gl/main.c b/gl/main.c
index 54ff28e..b98bb47 100644
--- a/gl/main.c
+++ b/gl/main.c
@@ -12,13 +12,14 @@
 #include "point.h"
 #include "cube.h"
 #include "camera.h"
+#include "timestep.h"
 
 static SDL_Window *window = NULL;
 static SDL_GLContext *context = NULL;
 static int screen_width = 1280;
 static int screen_height = 720;
 static bool quit = false;
-static Uint32 ltime, ctime, numframes, cftime, lftime;
+//static Uint32 ltime, ctime, numframes, cftime, lftime;
 
 static float vertices[] = {
 	// positions		// colours		 	// texture coords
@@ -100,7 +101,7 @@ static void initView()
 {
 	crpgCameraSetAR((float)screen_width/(float)screen_height);
 	camera = crpgCameraNew(vec3(0,0,4), vec3(0,0,0), vec3(0,1,0));
-	crpgCameraSetSpeed(camera, 2);
+	crpgCameraSetSpeed(camera, 20);
 	crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
 	crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
 
@@ -149,18 +150,8 @@ static bool init()
 
 static void update()
 {
-	// measuring frame times
-	numframes++;
-	ctime = SDL_GetTicks();
-	if(ctime - ltime > 1000){	// if the last printf was more than a second ago
-		printf("%f ms/frame\n", 1000/(double)(numframes));
-		numframes = 0;
-		ltime = ctime;
-	}
-
-	// calculating delta time
-	cftime = SDL_GetTicks();
-	float dtms = cftime - lftime;
+	int physUpdates = 0;
+	crpgTimeStepUpdate();
 
 	SDL_Event e;
 	while(SDL_PollEvent(&e) != 0){
@@ -201,8 +192,12 @@ static void update()
 		}
 	}
 
-	crpgCameraUpdate(camera, dtms);
-	lftime = cftime;
+	// Updating physics as many times as we need to consume dt
+	while(crpgTimeStepPhysRequried(physUpdates)){
+		crpgCameraUpdate(camera, crpgTimeStepDelta());
+
+		physUpdates++;
+	}
 }
 
 static void render()
@@ -240,9 +235,7 @@ int main()
 
 	initShapes();
 	initView();
-
-	ltime = SDL_GetTicks();
-	lftime = SDL_GetTicks();
+	crpgTimeStepInit(60.f);
 
 	while(!quit){
 		update();
diff --git a/gl/timestep.c b/gl/timestep.c
new file mode 100644
index 0000000..add1b30
--- /dev/null
+++ b/gl/timestep.c
@@ -0,0 +1,50 @@
+#include "timestep.h"
+#include <SDL2/SDL.h>
+#include <math.h>
+
+static const int MAX_PHYSICS_STEPS = 6;
+static const float MAX_DELTA_TIME = 1.f;
+static const float MS_PER_SECOND = 1000.f;
+
+static float desiredFrameTime;
+static Uint32 currentT;
+static Uint32 prevT;
+static float frameTime;
+static float totalDeltaTime;
+static float deltaTime;
+
+float crpgTimeStepDelta()
+{
+	return deltaTime;
+}
+
+void crpgTimeStepSetDesiredFT(float desiredFPS)
+{
+	desiredFrameTime = MS_PER_SECOND/desiredFPS;
+}
+
+void crpgTimeStepInit(float desiredFPS)
+{
+	crpgTimeStepSetDesiredFT(desiredFPS);
+
+	currentT = SDL_GetTicks();
+	prevT = SDL_GetTicks();
+}
+
+void crpgTimeStepUpdate()
+{
+	prevT = currentT;
+	currentT = SDL_GetTicks();
+	frameTime = currentT - prevT;
+	totalDeltaTime = frameTime / desiredFrameTime;
+}
+
+bool crpgTimeStepPhysRequried(int updatesThisFrame)
+{
+	if(totalDeltaTime <= 0.f || updatesThisFrame >= MAX_PHYSICS_STEPS){
+		return false;
+	} else {
+		deltaTime = fminf(totalDeltaTime, MAX_DELTA_TIME);
+		totalDeltaTime -= deltaTime;
+	}
+}
diff --git a/gl/timestep.h b/gl/timestep.h
new file mode 100644
index 0000000..499fe84
--- /dev/null
+++ b/gl/timestep.h
@@ -0,0 +1,10 @@
+#ifndef TIMESTEP_H
+#define TIMESTEP_H
+#include <stdbool.h>
+
+void crpgTimeStepInit(float desiredFPS);
+void crpgTimeStepSetDesiredFT(float desiredUpdateFT);
+void crpgTimeStepUpdate();
+bool crpgTimeStepPhysRequired(int updatesThisFrame);
+float crpgTimeStepDelta();
+#endif//TIMESTEP_H