FUgma
This commit is contained in:
		| @@ -7,6 +7,8 @@ | ||||
| cmake_minimum_required(VERSION 3.13) | ||||
| set(CMAKE_C_STANDARD 99) | ||||
| set(CMAKE_C_STANDARD_REQUIRED ON) | ||||
| set(CMAKE_CXX_STANDARD 11) | ||||
| set(CMAKE_CXX_STANDARD_REQUIRED True) | ||||
|  | ||||
| # Set some global flags | ||||
| add_compile_definitions( | ||||
|   | ||||
| @@ -19,7 +19,7 @@ target_link_libraries(${PROJECT_NAME} | ||||
|  | ||||
| target_sources(${PROJECT_NAME} | ||||
|   PRIVATE | ||||
|     glfwclient.c | ||||
|     glfwclient.cpp | ||||
| ) | ||||
|  | ||||
| # Includes | ||||
|   | ||||
| @@ -1,149 +0,0 @@ | ||||
| // Copyright (c) 2021 Dominic Msters | ||||
| //  | ||||
| // This software is released under the MIT License. | ||||
| // https://opensource.org/licenses/MIT | ||||
|  | ||||
| #include "glfwclient.h" | ||||
|  | ||||
| static game_t *GAME_STATE; | ||||
| static GLFWwindow *window = NULL; | ||||
|  | ||||
| int32_t main() { | ||||
|   double time, newTime; | ||||
|   game_t *game; | ||||
|   input_t *input; | ||||
|   float fDelta; | ||||
|  | ||||
|   // Attempt to init GLFW | ||||
|   if(!glfwInit()) return 1; | ||||
|  | ||||
|   // Setup window hints  | ||||
|   glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false); | ||||
|  | ||||
|   // Create Window | ||||
|   window = glfwCreateWindow( | ||||
|     WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT, "", NULL, NULL | ||||
|   ); | ||||
|   if(!window) { | ||||
|     glfwTerminate(); | ||||
|     return 1; | ||||
|   } | ||||
|    | ||||
|   // Load GLAD | ||||
|   glfwMakeContextCurrent(window); | ||||
|   glfwSwapInterval(0); | ||||
|   gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); | ||||
|  | ||||
|   // Setup window listeners | ||||
|   glfwSetWindowSizeCallback(window, &glfwOnResize); | ||||
|   glfwSetKeyCallback(window, &glfwOnKey); | ||||
|   glfwSetErrorCallback(&glfwOnError); | ||||
|   glfwSetCursorPosCallback(window, &glfwOnCursor); | ||||
|   glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | ||||
|    | ||||
|   // Prepare the game | ||||
|   game = malloc(sizeof(game_t)); | ||||
|   GAME_STATE = game; | ||||
|   input = &game->engine.input; | ||||
|  | ||||
|   printf("Game is %zu bytes.\n", sizeof(game_t)); | ||||
|    | ||||
|   // Init the render resolution | ||||
|   renderSetResolution(&game->engine.render, | ||||
|     WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT | ||||
|   );   | ||||
|   // Init the game | ||||
|   if(gameInit(game)) { | ||||
|     // Bind initial keys | ||||
|     inputBind(input, INPUT_NULL,          glfwGetInputSourceForKey(GLFW_KEY_ESCAPE)); | ||||
|     inputBind(input, INPUT_UP,            glfwGetInputSourceForKey(GLFW_KEY_UP)); | ||||
|     inputBind(input, INPUT_DOWN,          glfwGetInputSourceForKey(GLFW_KEY_DOWN)); | ||||
|     inputBind(input, INPUT_LEFT,          glfwGetInputSourceForKey(GLFW_KEY_LEFT)); | ||||
|     inputBind(input, INPUT_RIGHT,         glfwGetInputSourceForKey(GLFW_KEY_RIGHT)); | ||||
|     inputBind(input, INPUT_UP,            glfwGetInputSourceForKey(GLFW_KEY_W)); | ||||
|     inputBind(input, INPUT_DOWN,          glfwGetInputSourceForKey(GLFW_KEY_S)); | ||||
|     inputBind(input, INPUT_LEFT,          glfwGetInputSourceForKey(GLFW_KEY_A)); | ||||
|     inputBind(input, INPUT_RIGHT,         glfwGetInputSourceForKey(GLFW_KEY_D)); | ||||
|     inputBind(input, INPUT_ACCEPT,        glfwGetInputSourceForKey(GLFW_KEY_E)); | ||||
|     inputBind(input, INPUT_ACCEPT,        glfwGetInputSourceForKey(GLFW_KEY_ENTER)); | ||||
|     inputBind(input, INPUT_ACCEPT,        glfwGetInputSourceForKey(GLFW_KEY_SPACE)); | ||||
|  | ||||
|     // Bind the fake inputs | ||||
|     inputBind(input, INPUT_MOUSE_X,       GLFW_PLATFORM_INPUT_MOUSE_X); | ||||
|     inputBind(input, INPUT_MOUSE_Y,       GLFW_PLATFORM_INPUT_MOUSE_Y); | ||||
|  | ||||
|     // Set up the client | ||||
|     game->engine.client.setTitle = &glfwClientSetTitle; | ||||
|  | ||||
|     // Set up some GLFW stuff | ||||
|     glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | ||||
|     glfwSetWindowTitle(window, game->engine.name); | ||||
|  | ||||
|     // Begin time. | ||||
|     time = 0; | ||||
|  | ||||
|     // Main Render Loop  | ||||
|     while(!glfwWindowShouldClose(window)) { | ||||
|       glfwPollEvents(); | ||||
|  | ||||
|       // Determine the delta. | ||||
|       newTime = glfwGetTime(); | ||||
|       fDelta = (float)(newTime - time); | ||||
|       time = newTime; | ||||
|  | ||||
|       // Tick the engine. | ||||
|       if(!gameUpdate(game, fDelta)) break; | ||||
|       glfwSwapBuffers(window); | ||||
|       sleep(0);//Fixes some weird high CPU bug, not actually necessary. | ||||
|     } | ||||
|  | ||||
|      | ||||
|     // Game has finished running, cleanup. | ||||
|     gameDispose(game); | ||||
|   } | ||||
|  | ||||
|   free(game); | ||||
|    | ||||
|   // Terminate the GLFW context. | ||||
|   glfwSetWindowSizeCallback(window, NULL); | ||||
|   glfwTerminate(); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height) { | ||||
|   renderSetResolution(&GAME_STATE->engine.render, (float)width, (float)height); | ||||
| } | ||||
|  | ||||
| void glfwOnKey(GLFWwindow *window, | ||||
|   int32_t key, int32_t scancode, int32_t action, int32_t mods | ||||
| ) { | ||||
|   input_t *input = &GAME_STATE->engine.input; | ||||
|   if(action == GLFW_PRESS) { | ||||
|     inputStateSet(input, glfwGetInputSourceForKey(key), 1.0f); | ||||
|   } else if(action == GLFW_RELEASE) { | ||||
|     inputStateSet(input, glfwGetInputSourceForKey(key), 0.0f); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void glfwOnError(int error, const char* description) { | ||||
|   fputs(description, stderr); | ||||
| } | ||||
|  | ||||
| void glfwOnCursor(GLFWwindow *window, double x, double y) { | ||||
|   input_t *input = &GAME_STATE->engine.input; | ||||
|   inputStateSet(input, GLFW_PLATFORM_INPUT_MOUSE_X, (float)x); | ||||
|   inputStateSet(input, GLFW_PLATFORM_INPUT_MOUSE_Y, (float)y); | ||||
| } | ||||
|  | ||||
| inputsource_t glfwGetInputSourceForKey(int32_t key) { | ||||
|   return (inputsource_t)(( | ||||
|     key <= GLFW_KEY_GRAVE_ACCENT ? key - GLFW_KEY_SPACE : | ||||
|     key <= GLFW_KEY_MENU ? key - GLFW_KEY_ESCAPE + GLFW_KEY_GRAVE_ACCENT : | ||||
|     key | ||||
|   ) % INPUT_SOURCE_COUNT); | ||||
| } | ||||
|  | ||||
| void glfwClientSetTitle(char *name) { | ||||
|   glfwSetWindowTitle(window, name); | ||||
| } | ||||
							
								
								
									
										157
									
								
								client/glfwclient/glfwclient.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								client/glfwclient/glfwclient.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| // Copyright (c) 2021 Dominic Msters | ||||
| //  | ||||
| // This software is released under the MIT License. | ||||
| // https://opensource.org/licenses/MIT | ||||
|  | ||||
| #include "glfwclient.hpp" | ||||
|  | ||||
| static GLFWEngine *engine; | ||||
|  | ||||
| GLFWEngine::GLFWEngine(char **args, int32_t argc) { | ||||
|   this->args = args; | ||||
|   this->argc = argc; | ||||
|   this->window = NULL; | ||||
| } | ||||
|  | ||||
| int32_t GLFWEngine::init(void) { | ||||
|   if(!glfwInit()) return 1; | ||||
|  | ||||
|   // Setup window hints  | ||||
|   glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false); | ||||
|  | ||||
|   // Create Window | ||||
|   this->window = glfwCreateWindow( | ||||
|     WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT, this->game.name, NULL, NULL | ||||
|   ); | ||||
|   if(!this->window) { | ||||
|     glfwTerminate(); | ||||
|     return 1; | ||||
|   } | ||||
|    | ||||
|   // Load GLAD | ||||
|   glfwMakeContextCurrent(window); | ||||
|   glfwSwapInterval(0); | ||||
|   gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); | ||||
|  | ||||
|   // Init the game | ||||
|   this->game.init(); | ||||
|  | ||||
|   // Init the render resolution | ||||
|   this->game.render.setResolution(WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT); | ||||
|  | ||||
|   // Bind initial keys | ||||
|   this->game.input.bind(glfwGetInputSourceForKey(GLFW_KEY_ESCAPE), INPUT_NULL); | ||||
|   // input = &this->game.input; | ||||
|   // inputBind(input, INPUT_NULL,          glfwGetInputSourceForKey(GLFW_KEY_ESCAPE)); | ||||
|   // inputBind(input, INPUT_UP,            glfwGetInputSourceForKey(GLFW_KEY_UP)); | ||||
|   // inputBind(input, INPUT_DOWN,          glfwGetInputSourceForKey(GLFW_KEY_DOWN)); | ||||
|   // inputBind(input, INPUT_LEFT,          glfwGetInputSourceForKey(GLFW_KEY_LEFT)); | ||||
|   // inputBind(input, INPUT_RIGHT,         glfwGetInputSourceForKey(GLFW_KEY_RIGHT)); | ||||
|   // inputBind(input, INPUT_UP,            glfwGetInputSourceForKey(GLFW_KEY_W)); | ||||
|   // inputBind(input, INPUT_DOWN,          glfwGetInputSourceForKey(GLFW_KEY_S)); | ||||
|   // inputBind(input, INPUT_LEFT,          glfwGetInputSourceForKey(GLFW_KEY_A)); | ||||
|   // inputBind(input, INPUT_RIGHT,         glfwGetInputSourceForKey(GLFW_KEY_D)); | ||||
|   // inputBind(input, INPUT_ACCEPT,        glfwGetInputSourceForKey(GLFW_KEY_E)); | ||||
|   // inputBind(input, INPUT_ACCEPT,        glfwGetInputSourceForKey(GLFW_KEY_ENTER)); | ||||
|   // inputBind(input, INPUT_ACCEPT,        glfwGetInputSourceForKey(GLFW_KEY_SPACE)); | ||||
|  | ||||
|   // Bind the fake inputs | ||||
|   this->game.input.bind(GLFW_PLATFORM_INPUT_MOUSE_X, INPUT_MOUSE_X); | ||||
|   this->game.input.bind(GLFW_PLATFORM_INPUT_MOUSE_Y, INPUT_MOUSE_Y); | ||||
|  | ||||
|   // Set up some GLFW callbacks | ||||
|   glfwSetWindowSizeCallback(window, &glfwOnResize); | ||||
|   glfwSetKeyCallback(window, &glfwOnKey); | ||||
|   glfwSetErrorCallback(&glfwOnError); | ||||
|   glfwSetCursorPosCallback(window, &glfwOnCursor); | ||||
|   glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | ||||
|   glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | ||||
|   // glfwSetWindowTitle(window, game->engine.name); | ||||
|  | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int32_t GLFWEngine::update(float delta) { | ||||
|   int32_t ret; | ||||
|  | ||||
|   ret = this->game.update(delta); | ||||
|   if(ret != 0) return ret; | ||||
|  | ||||
|   if(this->game.input.isPressed(INPUT_NULL)) return 1; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| GLFWEngine::~GLFWEngine(void) { | ||||
|   glfwSetWindowSizeCallback(window, NULL); | ||||
|   glfwTerminate(); | ||||
| } | ||||
|  | ||||
|  | ||||
| int32_t main(int32_t argc, char **args) { | ||||
|   int32_t ret; | ||||
|   double time, newTime; | ||||
|   float fDelta; | ||||
|  | ||||
|   // Init engine | ||||
|   engine = new GLFWEngine(args, argc); | ||||
|   ret = engine->init(); | ||||
|   if(ret != 0) return ret; | ||||
|  | ||||
|   printf("Game is %zu bytes.\n", sizeof(engine)); | ||||
|  | ||||
|   // Main Render Loop  | ||||
|   while(!glfwWindowShouldClose(engine->window)) { | ||||
|     glfwPollEvents(); | ||||
|  | ||||
|     // Determine the delta. | ||||
|     newTime = glfwGetTime(); | ||||
|     fDelta = (float)(newTime - time); | ||||
|     time = newTime; | ||||
|  | ||||
|     ret = engine->update(fDelta); | ||||
|  | ||||
|     // Tick the engine. | ||||
|     glfwSwapBuffers(engine->window); | ||||
|     sleep(0); | ||||
|  | ||||
|     if(ret != 0) break; | ||||
|   } | ||||
|  | ||||
|   // Cleanup the engine. | ||||
|   delete engine; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height) { | ||||
|   engine->game.render.setResolution((float)width, (float)height); | ||||
| } | ||||
|  | ||||
| void glfwOnKey(GLFWwindow *window, | ||||
|   int32_t key, int32_t scancode, int32_t action, int32_t mods | ||||
| ) { | ||||
|   if(action == GLFW_PRESS) { | ||||
|     engine->game.input.setValue(glfwGetInputSourceForKey(key), 1.0f); | ||||
|   } else if(action == GLFW_RELEASE) { | ||||
|     engine->game.input.setValue(glfwGetInputSourceForKey(key), 0.0f); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void glfwOnError(int error, const char* description) { | ||||
|   fputs(description, stderr); | ||||
| } | ||||
|  | ||||
| void glfwOnCursor(GLFWwindow *window, double x, double y) { | ||||
|   engine->game.input.setValue(GLFW_PLATFORM_INPUT_MOUSE_X, (float)x); | ||||
|   engine->game.input.setValue(GLFW_PLATFORM_INPUT_MOUSE_Y, (float)y); | ||||
| } | ||||
|  | ||||
| inputsource_t glfwGetInputSourceForKey(int32_t key) { | ||||
|   return (inputsource_t)(( | ||||
|     key <= GLFW_KEY_GRAVE_ACCENT ? key - GLFW_KEY_SPACE : | ||||
|     key <= GLFW_KEY_MENU ? key - GLFW_KEY_ESCAPE + GLFW_KEY_GRAVE_ACCENT : | ||||
|     key | ||||
|   ) % 0xFF); | ||||
| } | ||||
| @@ -1,58 +0,0 @@ | ||||
| // Copyright (c) 2021 Dominic Msters | ||||
| //  | ||||
| // This software is released under the MIT License. | ||||
| // https://opensource.org/licenses/MIT | ||||
|  | ||||
| #pragma once | ||||
| #include <glad/glad.h> | ||||
| #include <GLFW/glfw3.h> | ||||
| #include <libs.h> | ||||
| #include "display/render.h" | ||||
| #include "input/input.h" | ||||
| #include "game/game.h" | ||||
|  | ||||
| #define WINDOW_WIDTH_DEFAULT 1280 | ||||
| #define WINDOW_HEIGHT_DEFAULT WINDOW_WIDTH_DEFAULT/16*9 | ||||
|  | ||||
| #define GLFW_PLATFORM_INPUT_MOUSE_X (inputsource_t)0xFF | ||||
| #define GLFW_PLATFORM_INPUT_MOUSE_Y (inputsource_t)0xFE | ||||
|  | ||||
| /** | ||||
|  * Entry of the program | ||||
|  * @return 0 if success, anything else for failure. | ||||
|  */ | ||||
| int32_t main(); | ||||
|  | ||||
| /** | ||||
|  * Resize callbacks. | ||||
|  *  | ||||
|  * @param window Window that was resized. | ||||
|  * @param width New window width. | ||||
|  * @param height New window height. | ||||
|  */ | ||||
| void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height); | ||||
|  | ||||
| /** | ||||
|  * Keyboard Input callbacks. | ||||
|  *  | ||||
|  * @param window Window that was resized. | ||||
|  */ | ||||
| void glfwOnKey(GLFWwindow *window, | ||||
|   int32_t key, int32_t scancode, int32_t action, int32_t mods | ||||
| ); | ||||
|  | ||||
|  | ||||
| void glfwOnError(int error, const char* description); | ||||
| void glfwOnCursor(GLFWwindow *window, double x, double y); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Get the game engine specific input source for a given GLFW Key code. | ||||
|  *  | ||||
|  * @param key Key to get the input source for. | ||||
|  * @return The input source.  | ||||
|  */ | ||||
| inputsource_t glfwGetInputSourceForKey(int32_t key); | ||||
|  | ||||
| /** GLFW Client Methods */ | ||||
| void glfwClientSetTitle(char *name); | ||||
							
								
								
									
										105
									
								
								client/glfwclient/glfwclient.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								client/glfwclient/glfwclient.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| // Copyright (c) 2021 Dominic Msters | ||||
| //  | ||||
| // This software is released under the MIT License. | ||||
| // https://opensource.org/licenses/MIT | ||||
|  | ||||
| #pragma once | ||||
| extern "C" { | ||||
|   #include <glad/glad.h> | ||||
|   #include <GLFW/glfw3.h> | ||||
|   #include "libs.h" | ||||
| } | ||||
|  | ||||
| #define WINDOW_WIDTH_DEFAULT 1280 | ||||
| #define WINDOW_HEIGHT_DEFAULT WINDOW_WIDTH_DEFAULT/16*9 | ||||
|  | ||||
| #define GLFW_PLATFORM_INPUT_MOUSE_X (inputsource_t)0xFF | ||||
| #define GLFW_PLATFORM_INPUT_MOUSE_Y (inputsource_t)0xFE | ||||
|  | ||||
| class GLFWEngine { | ||||
|   private: | ||||
|     char **args; | ||||
|     int32_t argc; | ||||
|  | ||||
|   public: | ||||
|     GLFWwindow *window; | ||||
|  | ||||
|     /** | ||||
|      * Construct a new GLFW Engine instance. | ||||
|      *  | ||||
|      * @param argc Count of arguments. | ||||
|      * @param args Array of strings for the arguments provided to the engine. | ||||
|      */ | ||||
|     GLFWEngine(int32_t argc, char **args); | ||||
|  | ||||
|     /** | ||||
|      * Initializes the GLFW engine. | ||||
|      *  | ||||
|      * @return 0 if success, everything else is a failure. | ||||
|      */ | ||||
|     virtual int32_t init(void); | ||||
|  | ||||
|     /** | ||||
|      * Tick the game engine by delta amount. | ||||
|      *  | ||||
|      * @param delta  | ||||
|      * @return 0 if success, everything else is a failure. | ||||
|      */ | ||||
|     int32_t update(float delta); | ||||
|  | ||||
|     virtual ~GLFWEngine(void) override; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Entry of the program | ||||
|  *  | ||||
|  * @param argc Count of args in the args array. | ||||
|  * @param args Args provided to us by the parent O.S. | ||||
|  * @return 0 if success, anything else for failure. | ||||
|  */ | ||||
| int32_t main(int32_t argc, char **args); | ||||
|  | ||||
| /** | ||||
|  * Resize callbacks. | ||||
|  *  | ||||
|  * @param window Window that was resized. | ||||
|  * @param width New window width. | ||||
|  * @param height New window height. | ||||
|  */ | ||||
| void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height); | ||||
|  | ||||
| /** | ||||
|  * Keyboard Input callbacks. | ||||
|  *  | ||||
|  * @param window Window that was resized. | ||||
|  */ | ||||
| void glfwOnKey(GLFWwindow *window, | ||||
|   int32_t key, int32_t scancode, int32_t action, int32_t mods | ||||
| ); | ||||
|  | ||||
| /** | ||||
|  * Callback for generic GLFW errors. | ||||
|  *  | ||||
|  * @param error Error code/descriptor. | ||||
|  * @param description String representation of the error. | ||||
|  */ | ||||
| void glfwOnError(int error, const char* description); | ||||
|  | ||||
| /** | ||||
|  * Event callback for mouse cursor movement. | ||||
|  *  | ||||
|  * @param window  | ||||
|  * @param x  | ||||
|  * @param y  | ||||
|  */ | ||||
| void glfwOnCursor(GLFWwindow *window, double x, double y); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Get the game engine specific input source for a given GLFW Key code. | ||||
|  *  | ||||
|  * @param key Key to get the input source for. | ||||
|  * @return The input source.  | ||||
|  */ | ||||
| inputsource_t glfwGetInputSourceForKey(int32_t key); | ||||
| @@ -6,5 +6,5 @@ | ||||
| # Sources | ||||
| target_sources(${PROJECT_NAME} | ||||
|   PRIVATE | ||||
|     input.c | ||||
|     input.cpp | ||||
| ) | ||||
| @@ -1,192 +0,0 @@ | ||||
| // Copyright (c) 2021 Dominic Masters | ||||
| //  | ||||
| // This software is released under the MIT License. | ||||
| // https://opensource.org/licenses/MIT | ||||
|  | ||||
| #pragma once | ||||
| #include "../libs.h" | ||||
| #include "../util/list.h" | ||||
|  | ||||
| /** Debug Inputs */ | ||||
| #define INPUT_NULL        (inputbind_t)0x00 | ||||
|  | ||||
| /** Real Inputs (Starts at 32/0x20) */ | ||||
| #define INPUT_UP          (inputbind_t)0x20 | ||||
| #define INPUT_DOWN        (inputbind_t)0x21 | ||||
| #define INPUT_LEFT        (inputbind_t)0x22 | ||||
| #define INPUT_RIGHT       (inputbind_t)0x23 | ||||
| #define INPUT_ACCEPT      (inputbind_t)0x24 | ||||
|  | ||||
| /** Additional sources */ | ||||
| #define INPUT_MOUSE_X     (inputsource_t)0x10 | ||||
| #define INPUT_MOUSE_Y     (inputsource_t)0x11 | ||||
|  | ||||
| #define INPUT_BIND_COUNT 0x40 | ||||
| #define INPUT_SOURCE_COUNT 0xFF | ||||
|  | ||||
| /** | ||||
|  * Input Bind, a specific action bind reference for the game engine to use. | ||||
|  * e.g. "Jump" or "Walk Forward". | ||||
|  */ | ||||
| typedef uint8_t inputbind_t; | ||||
|  | ||||
| /** | ||||
|  * Input source identifier. It's up to the platform itself to decide what the | ||||
|  * hell this number refers to. For most platforms it will be an input, such as a | ||||
|  * keyboard scancode or a (pad number * button count) + button. | ||||
|  */ | ||||
| typedef uint8_t inputsource_t; | ||||
|  | ||||
| /** | ||||
|  * Value that represents the state of an input. Defined as 0-1 where 0 is set | ||||
|  * to be completely off / netural state, and 1 is completely on / full state. | ||||
|  */ | ||||
| typedef float inputval_t; | ||||
|  | ||||
| /** | ||||
|  * Structure for the entire input mapping. | ||||
|  */ | ||||
| typedef struct { | ||||
|   /** Float of the input between 0 and 1. */ | ||||
|   inputval_t inputsA[INPUT_BIND_COUNT]; | ||||
|   /** Float of the input between 0 and 1. */ | ||||
|   inputval_t inputsB[INPUT_BIND_COUNT]; | ||||
|  | ||||
|   /** Flippable state */ | ||||
|   inputval_t *current, *previous; | ||||
|  | ||||
|   /** | ||||
|    * Binding Map, Array of lists where index = binding and entry is a list of | ||||
|    * input sources. | ||||
|    */ | ||||
|   list_t *bindMap[INPUT_BIND_COUNT]; | ||||
|  | ||||
|   /** | ||||
|    * Input buffer array. Keeps track of raw values from the inputs. | ||||
|    * The engine will read from the buffer when necessary. | ||||
|    */ | ||||
|   inputval_t buffer[INPUT_SOURCE_COUNT]; | ||||
|  | ||||
|   /** Float of the GameTime that the input was actuated last. */ | ||||
|   float times[INPUT_BIND_COUNT]; | ||||
| } input_t; | ||||
|  | ||||
| /** | ||||
|  * Initializes the input manager. | ||||
|  *  | ||||
|  * @param input The input manager to initialize. | ||||
|  */ | ||||
| void inputInit(input_t *input); | ||||
|  | ||||
| /** | ||||
|  * Tick the input manager. | ||||
|  *  | ||||
|  * @param input The input manager to update. | ||||
|  */ | ||||
| void inputUpdate(input_t *input); | ||||
|  | ||||
| /** | ||||
|  * Destroy the input manager and cleanup. | ||||
|  *  | ||||
|  * @param input The input manager to dispose. | ||||
|  */ | ||||
| void inputDispose(input_t *input); | ||||
|  | ||||
| /** | ||||
|  * Binds the given input binding to the input source. Essentially allowing any | ||||
|  * time we fetch the state of bind, we will read the value from source. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param bind The binding to bind against. | ||||
|  * @param source The source that is being bound. | ||||
|  */ | ||||
| void inputBind(input_t *input, inputbind_t bind, inputsource_t source); | ||||
|  | ||||
| /** | ||||
|  * Unbind a previously bound input source from a binding. This method is costly. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param bind The binding to unbind from. | ||||
|  * @param source The source that is being unbound. | ||||
|  */ | ||||
| void inputUnbind(input_t *input, inputbind_t bind, inputsource_t source); | ||||
|  | ||||
| /** | ||||
|  * Set the state of an input. | ||||
|  *  | ||||
|  * @param input Input to set the state for. | ||||
|  * @param source Source to set. | ||||
|  * @param value Value to set. | ||||
|  */ | ||||
| void inputStateSet(input_t *input, inputsource_t source, float value); | ||||
|  | ||||
| /** | ||||
|  * Is the current input "down", being pressed, being moved, not in a state | ||||
|  * of rest. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param binding The previously bound input binding. | ||||
|  * @return True if the input vector is non-zero. | ||||
|  */ | ||||
| bool inputIsDown(input_t *input, inputbind_t binding); | ||||
|  | ||||
| /** | ||||
|  * Is the current input "up", in a state of rest, not being actioned, moved. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param binding The previously bound input binding. | ||||
|  * @return True if input vector is zero | ||||
|  */ | ||||
| bool inputIsUp(input_t *input, inputbind_t binding); | ||||
|  | ||||
| /** | ||||
|  * Returns true on the first tick that an input was actioned/downed. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param binding The previously bound input binding. | ||||
|  * @return True if the input vector was non-zeroed this tick but not last.  | ||||
|  */ | ||||
| bool inputIsPressed(input_t *input, inputbind_t binding); | ||||
|  | ||||
| /** | ||||
|  * Returns true on the first tick that an input was released/upped. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param binding The previously bound input binding. | ||||
|  * @return True if the input vector was zeroed this tick but not last.  | ||||
|  */ | ||||
| bool inputIsReleased(input_t *input, inputbind_t binding); | ||||
|  | ||||
| /** | ||||
|  * Returns the raw input value as a float between 0 and 1. For digital (buttons) | ||||
|  * this will typicall be 0 or 1 only. Other analogue inputs will have anywhere | ||||
|  * within the range. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param binding The previously bound input binding. | ||||
|  * @return Input state of the axis. | ||||
|  */ | ||||
| inputval_t inputGetAxis(input_t *input, inputbind_t binding); | ||||
|  | ||||
| /** | ||||
|  * Returns a raw input value between -1 and 1 between two axis. This would be | ||||
|  * indicitive of having an input with an axis that can be moved one direction | ||||
|  * for a positive input and another for a negative input, typically a game | ||||
|  * controller's analogue sticks. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param postitive The positive axis binding. | ||||
|  * @param negative The negative axis binding. | ||||
|  * @return A float between -1 and 1 representing the result of both. | ||||
|  */ | ||||
| float inputGetFullAxis(input_t *input, inputbind_t positive, inputbind_t negative); | ||||
|  | ||||
| /** | ||||
|  * Returns the time that an input was actuated at. Actuate would count as a | ||||
|  * non-zero input for analogue inputs. | ||||
|  *  | ||||
|  * @param input The input manager. | ||||
|  * @param binding The previously bound input binding. | ||||
|  * @return Game Engine time that an input was non-zeroed | ||||
|  */ | ||||
| float inputGetAccuated(input_t *input, inputbind_t binding); | ||||
							
								
								
									
										133
									
								
								src/input/input.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/input/input.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| // Copyright (c) 2021 Dominic Masters | ||||
| //  | ||||
| // This software is released under the MIT License. | ||||
| // https://opensource.org/licenses/MIT | ||||
|  | ||||
| #pragma once | ||||
| extern "C" { | ||||
|   #include "../util/math.h" | ||||
| } | ||||
| #include "../libs.hpp" | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Input source identifier. It's up to the platform itself to decide what the | ||||
|  * hell this number refers to. For most platforms it will be an input, such as a | ||||
|  * keyboard scancode or a (pad number * button count) + button. | ||||
|  */ | ||||
| typedef uint8_t inputsource_t; | ||||
|  | ||||
| /** | ||||
|  * Input Bind, a specific action bind reference for the game engine to use. | ||||
|  * e.g. "Jump" or "Walk Forward". | ||||
|  */ | ||||
| typedef uint8_t inputbind_t; | ||||
|  | ||||
| /** | ||||
|  * Value that represents the state of an input. Defined as 0-1 where 0 is set | ||||
|  * to be completely off / netural state, and 1 is completely on / full state. | ||||
|  */ | ||||
| typedef float inputval_t; | ||||
|  | ||||
| /** Debug Inputs */ | ||||
| #define INPUT_NULL      (inputbind_t)0x00 | ||||
|  | ||||
| /** Additional sources */ | ||||
| #define INPUT_MOUSE_X   (inputbind_t)0x10 | ||||
| #define INPUT_MOUSE_Y   (inputsource_t)0x11 | ||||
|  | ||||
| namespace Dawn { | ||||
|   class Input { | ||||
|     private: | ||||
|       std::map<inputbind_t, std::vector<inputsource_t>> binds; | ||||
|       std::map<inputbind_t, inputval_t> valsLeft; | ||||
|       std::map<inputbind_t, inputval_t> valsRight; | ||||
|       std::map<inputsource_t, inputval_t> buffer; | ||||
|       bool left; | ||||
|    | ||||
|     public: | ||||
|       /** | ||||
|        * Initializes the input manager. | ||||
|        */ | ||||
|       Input(void); | ||||
|  | ||||
|       /** | ||||
|        * Tick the input manager. | ||||
|        */ | ||||
|       void update(void); | ||||
|  | ||||
|       /** | ||||
|        * Binds the given input binding to the input source. Essentially allowing any | ||||
|        * time we fetch the state of bind, we will read the value from source. | ||||
|        *  | ||||
|        * @param source The source that is being bound. | ||||
|        * @param bind The binding to bind against. | ||||
|        */ | ||||
|       void bind(inputsource_t source, inputbind_t bind); | ||||
|  | ||||
|       /** | ||||
|        * Unbind a previously bound input source from a binding. | ||||
|        *  | ||||
|        * @param source The source that is being unbound. | ||||
|        * @param bind The binding to unbind from. | ||||
|        */ | ||||
|       void unbind(inputsource_t source, inputbind_t bind); | ||||
|  | ||||
|       /** | ||||
|        * Set the state of an input. | ||||
|        *  | ||||
|        * @param source Source to set. | ||||
|        * @param value Value to set. | ||||
|        */ | ||||
|       void setValue(inputsource_t source, float value); | ||||
|  | ||||
|       /** | ||||
|        * Returns the raw input value as a float between 0 and 1. For digital | ||||
|        * (buttons) this will typicall be 0 or 1 only. Other analogue inputs will | ||||
|        * have anywhere within the range. | ||||
|        *  | ||||
|        * @param binding The previously bound input binding. | ||||
|        * @return Input state of the axis. | ||||
|        */ | ||||
|       inputval_t getAxis(inputbind_t bind); | ||||
|  | ||||
|       /** | ||||
|        * Is the current input "down", being pressed, being moved, not in a state | ||||
|        * of rest. | ||||
|        *  | ||||
|        * @param binding The previously bound input binding. | ||||
|        * @return True if the input vector is non-zero. | ||||
|        */ | ||||
|       bool isDown(inputbind_t binding); | ||||
|  | ||||
|       /** | ||||
|        * Is the current input "up", in a state of rest, not being actioned, | ||||
|        * moved. | ||||
|        *  | ||||
|        * @param binding The previously bound input binding. | ||||
|        * @return True if input vector is zero | ||||
|        */ | ||||
|       bool isUp(inputbind_t binding); | ||||
|  | ||||
|       /** | ||||
|        * Returns true on the first tick that an input was actioned/downed. | ||||
|        *  | ||||
|        * @param binding The previously bound input binding. | ||||
|        * @return True if the input vector was non-zeroed this tick but not last.  | ||||
|        */ | ||||
|       bool isPressed(inputbind_t binding); | ||||
|  | ||||
|       /** | ||||
|        * Returns true on the first tick that an input was released/upped. | ||||
|        *  | ||||
|        * @param binding The previously bound input binding. | ||||
|        * @return True if the input vector was zeroed this tick but not last.  | ||||
|        */ | ||||
|       bool isReleased(inputbind_t binding); | ||||
|  | ||||
|       /** | ||||
|        * Destroy the input manager and cleanup. | ||||
|        */ | ||||
|       ~Input(void); | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/libs.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/libs.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| // Copyright (c) 2021 Dominic Masters | ||||
| //  | ||||
| // This software is released under the MIT License. | ||||
| // https://opensource.org/licenses/MIT | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| extern "C" { | ||||
|   #include "libs.h" | ||||
| } | ||||
|  | ||||
| #include <vector> | ||||
| #include <iostream> | ||||
| #include <map> | ||||
| #include <iterator> | ||||
| #include <algorithm> | ||||
		Reference in New Issue
	
	Block a user