#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
 {
        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));
 
 
 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){
                }
        }
 
-       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()
 
        initShapes();
        initView();
-
-       ltime = SDL_GetTicks();
-       lftime = SDL_GetTicks();
+       crpgTimeStepInit(60.f);
 
        while(!quit){
                update();
 
--- /dev/null
+#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;
+       }
+}