From 0c11452470ff6f08fbb0cbaa8971164afcf0b82c Mon Sep 17 00:00:00 2001
From: matthew <matthew@owens.tech>
Date: Sat, 13 Oct 2018 16:55:58 +0100
Subject: [PATCH] Changed to SDL_GetKeyBoardState for input

Also moved input to a seperate translation unit, implemented the
InputDevice struct to facilitate multiple input devices in the
future
---
 gl/camera.c   | 20 ++++++++++++-
 gl/camera.h   |  3 +-
 gl/input.c    | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gl/input.h    | 22 ++++++++++++++
 gl/main.c     | 45 +++++++---------------------
 gl/timestep.c |  9 +++---
 6 files changed, 140 insertions(+), 41 deletions(-)
 create mode 100644 gl/input.c
 create mode 100644 gl/input.h

diff --git a/gl/camera.c b/gl/camera.c
index a1196c9..980c143 100644
--- a/gl/camera.c
+++ b/gl/camera.c
@@ -1,6 +1,7 @@
 #include "camera.h"
 #include <math.h>
 #include <stdlib.h>
+#include "input.h"
 
 static vec3_t worldSpaceVec;
 static float aspectRatio = 16.f/9.f;	// sane default for the aspect ratio
@@ -99,7 +100,24 @@ void updatePan(vec3_t panAxis, vec3_t *components[3], float speed, float dtms)
 	}
 }
 
-void crpgCameraUpdate(crpgCamera *c, float dtms)
+void crpgCameraUpdate(crpgCamera *c)
+{
+	vec3_t panAxis = (vec3_t){0.f,0.f,0.f};
+
+	panAxis.x = crpgInputHeld(INPUT_CAMERA_PAN_RIGHT) ? 1 : 0;
+	panAxis.x = crpgInputHeld(INPUT_CAMERA_PAN_LEFT) ? -1 : panAxis.x;
+
+	panAxis.y = crpgInputHeld(INPUT_CAMERA_PAN_UP) ? 1 : 0;
+	panAxis.y = crpgInputHeld(INPUT_CAMERA_PAN_DOWN) ? -1 : panAxis.y;
+
+	panAxis.z = crpgInputHeld(INPUT_CAMERA_PAN_IN) ? 1 : 0;
+	panAxis.z = crpgInputHeld(INPUT_CAMERA_PAN_OUT) ? -1 : panAxis.z;
+
+	Camera_t *ct = (Camera_t *)c;
+	ct->pan = panAxis;
+}
+
+void crpgCameraRender(crpgCamera *c, float dtms)
 {
 	Camera_t *ct = (Camera_t *)c;
 	vec3_t *components[] = { &(ct->from), &(ct->to), &(ct->up) };
diff --git a/gl/camera.h b/gl/camera.h
index 9e513b3..030cc82 100644
--- a/gl/camera.h
+++ b/gl/camera.h
@@ -10,5 +10,6 @@ void crpgCameraPan(crpgCamera *c, vec3_t panAxis);
 void crpgCameraSetAR(float ar);
 mat4_t *crpgCameraGetMat(crpgCamera *c);
 void crpgCameraSetSpeed(crpgCamera *c, float speedPerSecond);
-void crpgCameraUpdate(crpgCamera *c, float dtms);
+void crpgCameraRender(crpgCamera *c, float dtms);
+void crpgCameraUpdate(crpgCamera *c);
 #endif//CAMERA_H
diff --git a/gl/input.c b/gl/input.c
new file mode 100644
index 0000000..f686f75
--- /dev/null
+++ b/gl/input.c
@@ -0,0 +1,82 @@
+#include "input.h"
+#include "err.h"
+#include <SDL2/SDL.h>
+
+typedef struct InputDevice{
+	Uint8 *state;
+	Uint8 *prevState;
+	Uint8 *binds;
+}InputDevice;
+
+static InputDevice kb = {NULL,NULL,NULL};
+
+bool devicesNotInitilised()
+{
+	if(kb.binds == NULL){
+		err_output("Error: Can't bind keys, kbBinds is NULL!");
+		return true;
+	}
+	return false;
+}
+
+void loadKeybinds()
+{
+	if(devicesNotInitilised()){
+		return;
+	}
+
+	//TODO: change from static keybinds to keybinds loaded from a file
+	kb.binds[INPUT_CAMERA_PAN_UP] = SDL_SCANCODE_W;
+	kb.binds[INPUT_CAMERA_PAN_DOWN] = SDL_SCANCODE_S;
+	kb.binds[INPUT_CAMERA_PAN_LEFT] = SDL_SCANCODE_A;
+	kb.binds[INPUT_CAMERA_PAN_RIGHT] = SDL_SCANCODE_D;
+	kb.binds[INPUT_CAMERA_PAN_IN] = SDL_SCANCODE_Q;
+	kb.binds[INPUT_CAMERA_PAN_OUT] = SDL_SCANCODE_E;
+}
+
+bool crpgInputPressed(int action)
+{
+	if(devicesNotInitilised()){
+		return false;
+	}
+	printf("binds is: %d, SDL is %d\n", kb.binds[action], SDL_SCANCODE_D);
+	printf("current state: %d, prev state: %d\n\n", kb.state[kb.binds[action]], kb.prevState[kb.binds[action]]);
+	return (kb.state[ kb.binds[action] ] && !kb.prevState[ kb.binds[action] ]);
+}
+
+bool crpgInputHeld(int action)
+{
+	if(devicesNotInitilised()){
+		return false;
+	}
+
+	return (kb.state[ kb.binds[action] ] || kb.prevState[ kb.binds[action] ]);
+}
+
+bool crpgInputReleased(int action)
+{
+	if(devicesNotInitilised()){
+		return false;
+	}
+
+	return (!kb.state[ kb.binds[action] ] && kb.prevState[ kb.binds[action] ]);
+}
+
+
+void crpgInputInit()
+{
+	kb.binds = malloc(sizeof(Uint8) * INPUT_LAST);
+	loadKeybinds();
+}
+
+void crpgInputCleanup()
+{
+	free(kb.binds);
+}
+
+void crpgInputUpdate()
+{
+	//SDL_PumpEvents();
+	kb.prevState = kb.state;
+	kb.state = SDL_GetKeyboardState(NULL);
+}
diff --git a/gl/input.h b/gl/input.h
new file mode 100644
index 0000000..3d6ae21
--- /dev/null
+++ b/gl/input.h
@@ -0,0 +1,22 @@
+#ifndef INPUT_H
+#define INPUT_H
+#include <stdbool.h>
+
+typedef enum crpgInputActions{
+	INPUT_CAMERA_PAN_DOWN = 0,
+	INPUT_CAMERA_PAN_UP,
+	INPUT_CAMERA_PAN_LEFT,
+	INPUT_CAMERA_PAN_RIGHT,
+	INPUT_CAMERA_PAN_IN,
+	INPUT_CAMERA_PAN_OUT,
+	INPUT_LAST
+}crpgInputActions;
+
+void crpgInputInit();
+void crpgInputUpdate();
+void crpgInputCleanup();
+
+bool crpgInputPressed(int action);
+bool crpgInputHeld(int action);
+bool crpgInputReleased(int action);
+#endif//INPUT_H
diff --git a/gl/main.c b/gl/main.c
index b98bb47..3cc6d91 100644
--- a/gl/main.c
+++ b/gl/main.c
@@ -13,6 +13,7 @@
 #include "cube.h"
 #include "camera.h"
 #include "timestep.h"
+#include "input.h"
 
 static SDL_Window *window = NULL;
 static SDL_GLContext *context = NULL;
@@ -141,6 +142,7 @@ static bool init()
 	/* syncing the buffer swap with the monitor's vertical refresh */
 	SDL_GL_SetSwapInterval(1);
 	glViewport(0, 0, screen_width, screen_height);
+	crpgInputInit();
 
 	glewExperimental = GL_TRUE;
 	glewInit();
@@ -158,50 +160,22 @@ static void update()
 		if(e.type == SDL_QUIT){
 			quit = true;
 		}
-		if(e.type == SDL_KEYDOWN){
-			switch(e.key.keysym.sym){
-				case SDLK_k:
-					blendVal += .2f;
-					crpgShaderSetFloat(shader, "blendVal", blendVal);
-					break;
-				case SDLK_j:
-					blendVal -= .2f;
-					crpgShaderSetFloat(shader, "blendVal", blendVal);
-					break;
-				case SDLK_w:
-					crpgCameraPan(camera, vec3(0,0,-1));
-					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
-					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
-					break;
-				case SDLK_s:
-					crpgCameraPan(camera, vec3(0,0,1));
-					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
-					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
-					break;
-				case SDLK_d:
-					crpgCameraPan(camera, vec3(1,0,0));
-					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
-					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
-					break;
-				case SDLK_a:
-					crpgCameraPan(camera, vec3(-1,0,0));
-					crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
-					crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
-					break;
-			}
-		}
 	}
+	crpgInputUpdate();
 
 	// Updating physics as many times as we need to consume dt
-	while(crpgTimeStepPhysRequried(physUpdates)){
-		crpgCameraUpdate(camera, crpgTimeStepDelta());
-
+	while(crpgTimeStepPhysRequired(physUpdates)){
+		crpgCameraUpdate(camera);
+		crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
+		crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
 		physUpdates++;
 	}
 }
 
 static void render()
 {
+	crpgCameraRender(camera, crpgTimeStepDelta());
+
 	glClearColor(0.2, 0.3, 0.3, 1.0);
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
@@ -243,6 +217,7 @@ int main()
 	}
 
 	SDL_Quit();
+	crpgInputCleanup();
 	crpgCubeFree(cubes[0]);
 	crpgCubeFree(cubes[1]);
 	return 0;
diff --git a/gl/timestep.c b/gl/timestep.c
index add1b30..bbda557 100644
--- a/gl/timestep.c
+++ b/gl/timestep.c
@@ -39,12 +39,13 @@ void crpgTimeStepUpdate()
 	totalDeltaTime = frameTime / desiredFrameTime;
 }
 
-bool crpgTimeStepPhysRequried(int updatesThisFrame)
+bool crpgTimeStepPhysRequired(int updatesThisFrame)
 {
 	if(totalDeltaTime <= 0.f || updatesThisFrame >= MAX_PHYSICS_STEPS){
 		return false;
-	} else {
-		deltaTime = fminf(totalDeltaTime, MAX_DELTA_TIME);
-		totalDeltaTime -= deltaTime;
 	}
+
+	deltaTime = fminf(totalDeltaTime, MAX_DELTA_TIME);
+	totalDeltaTime -= deltaTime;
+	return true;
 }
-- 
2.20.1