From 39a054783092d3674969c1dee886f6fa1f0e6e73 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 24 Feb 2025 12:37:26 -0600 Subject: [PATCH] Input and tick --- src/dusk/CMakeLists.txt | 2 +- src/dusk/game.c | 5 ++++ src/dusk/game.h | 2 ++ src/dusk/input.c | 37 +++++++++++++++++++++++++ src/dusk/input.h | 54 ++++++++++++++++++++++++++++++++++++- src/duskgl/display/render.c | 13 --------- src/duskglfw/input.c | 16 ++++++----- src/duskglfw/main.c | 16 +++++------ 8 files changed, 116 insertions(+), 29 deletions(-) create mode 100644 src/dusk/input.c diff --git a/src/dusk/CMakeLists.txt b/src/dusk/CMakeLists.txt index ad1c559..c72315b 100644 --- a/src/dusk/CMakeLists.txt +++ b/src/dusk/CMakeLists.txt @@ -19,10 +19,10 @@ target_include_directories(${DUSK_TARGET_NAME} target_sources(${DUSK_TARGET_NAME} PRIVATE game.c + input.c ) # Subdirs add_subdirectory(assert) -add_subdirectory(console) add_subdirectory(entity) add_subdirectory(display) \ No newline at end of file diff --git a/src/dusk/game.c b/src/dusk/game.c index 8580694..7445d0d 100644 --- a/src/dusk/game.c +++ b/src/dusk/game.c @@ -14,6 +14,11 @@ void gameInit() { void gameUpdate() { inputUpdate(); + + if(inputWasPressed(INPUT_MENU)) { + // Quit + printf("Quit\n"); + } } void gameDispose() { diff --git a/src/dusk/game.h b/src/dusk/game.h index 4f19c95..69bc4b8 100644 --- a/src/dusk/game.h +++ b/src/dusk/game.h @@ -8,6 +8,8 @@ #pragma once #include "dusk.h" +#define GAME_TICK_RATE 60 + /** * Initializes the game. */ diff --git a/src/dusk/input.c b/src/dusk/input.c new file mode 100644 index 0000000..b773f5d --- /dev/null +++ b/src/dusk/input.c @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "input.h" + +inputstate_t INPUT_CURRENT; +inputstate_t INPUT_LAST_FRAME; + +void inputInit() { + INPUT_CURRENT = 0; + INPUT_LAST_FRAME = 0; +} + +void inputUpdate() { + INPUT_LAST_FRAME = INPUT_CURRENT; + INPUT_CURRENT = inputPlatformState(); +} + +bool_t inputWasPressed(const inputstate_t state) { + return (INPUT_LAST_FRAME & state) == 0 && (INPUT_CURRENT & state) != 0; +} + +bool_t inputWasReleased(const inputstate_t state) { + return (INPUT_LAST_FRAME & state) != 0 && (INPUT_CURRENT & state) == 0; +} + +bool_t inputIsDown(const inputstate_t state) { + return (INPUT_CURRENT & state) != 0; +} + +bool_t inputIsUp(const inputstate_t state) { + return (INPUT_CURRENT & state) == 0; +} \ No newline at end of file diff --git a/src/dusk/input.h b/src/dusk/input.h index 3226322..9682ae0 100644 --- a/src/dusk/input.h +++ b/src/dusk/input.h @@ -6,9 +6,18 @@ */ #pragma once +#include "dusk.h" typedef uint16_t inputstate_t; +#define INPUT_MENU (1 << 0) +#define INPUT_UP (1 << 1) +#define INPUT_DOWN (1 << 2) +#define INPUT_LEFT (1 << 3) +#define INPUT_RIGHT (1 << 4) +#define INPUT_ACCEPT (1 << 5) +#define INPUT_BACK (1 << 6) + extern inputstate_t INPUT_CURRENT; extern inputstate_t INPUT_LAST_FRAME; @@ -16,4 +25,47 @@ extern inputstate_t INPUT_LAST_FRAME; * Initializes the input system */ void inputInit(); -void inputUpdate(); \ No newline at end of file + +/** + * Updates the input system for this tick. + */ +void inputUpdate(); + +/** + * Requests the platform let us know the current state of each input. + * + * @return Current input state. + */ +inputstate_t inputPlatformState(); + +/** + * Returns true if the input was pressed this frame, but not last frame. + * + * @param state Inputs to check, typically a single input. + * @return True if input was pressed this frame but not last frame. + */ +bool_t inputWasPressed(const inputstate_t state); + +/** + * Returns true if the input was released this frame, but pressed last frame. + * + * @param state Inputs to check, typically a single input. + * @return True if input was released this frame but was pressed last frame. + */ +bool_t inputWasReleased(const inputstate_t state); + +/** + * Returns true if the input is currently pressed. + * + * @param state Inputs to check, typically a single input. + * @return True if input is currently pressed. + */ +bool_t inputIsDown(const inputstate_t state); + +/** + * Returns true if the input is currently released. + * + * @param state Inputs to check, typically a single input. + * @return True if input is currently released. + */ +bool_t inputIsUp(const inputstate_t state); \ No newline at end of file diff --git a/src/duskgl/display/render.c b/src/duskgl/display/render.c index 17e13b7..bdb2493 100644 --- a/src/duskgl/display/render.c +++ b/src/duskgl/display/render.c @@ -7,24 +7,11 @@ #include "assert/assertgl.h" #include "render.h" -#include "console/console.h" render_t RENDER; void renderInit() { memset(&RENDER, 0, sizeof(render_t)); - - // Get OpenGL version - const GLubyte *version = glGetString(GL_VERSION); - const GLubyte *renderer = glGetString(GL_RENDERER); - const GLubyte *vendor = glGetString(GL_VENDOR); - const GLubyte *glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); - - consolePrint("OpenGL Renderer"); - consolePrint("Version: %s", version); - consolePrint("Renderer: %s", renderer); - consolePrint("Vendor: %s", vendor); - consolePrint("GLSL: %s", glslVersion); } void renderUpdate() { diff --git a/src/duskglfw/input.c b/src/duskglfw/input.c index 0313a50..a96262a 100644 --- a/src/duskglfw/input.c +++ b/src/duskglfw/input.c @@ -10,7 +10,7 @@ typedef struct { uint16_t glfw; - inputbind_t bind; + inputstate_t bind; } glfwkeybindmap_t; glfwkeybindmap_t GLFW_KEY_BIND_MAP[] = { @@ -30,23 +30,27 @@ glfwkeybindmap_t GLFW_KEY_BIND_MAP[] = { {GLFW_KEY_E, INPUT_ACCEPT}, {GLFW_KEY_SPACE, INPUT_ACCEPT}, - {GLFW_KEY_ESCAPE, INPUT_BACK}, {GLFW_KEY_BACKSPACE, INPUT_BACK}, {GLFW_KEY_Q, INPUT_BACK}, + {GLFW_KEY_ESCAPE, INPUT_MENU}, + {0, 0} }; -inputvalue_t inputStateGet(const inputbind_t input) { +inputstate_t inputPlatformState() { + inputstate_t state = 0; // Handle keybinds glfwkeybindmap_t *map = GLFW_KEY_BIND_MAP; do { - if(map->bind == input && glfwGetKey(window, map->glfw) == GLFW_PRESS) { - return 1; + if(glfwGetKey(window, map->glfw) != GLFW_PRESS) { + map++; + continue; } + state |= map->bind; map++; } while(map->glfw != 0); - return 0; + return state; } \ No newline at end of file diff --git a/src/duskglfw/main.c b/src/duskglfw/main.c index 2b4be11..2b58378 100644 --- a/src/duskglfw/main.c +++ b/src/duskglfw/main.c @@ -10,7 +10,6 @@ #include "display/render.h" #include "game.h" #include "asset.h" -#include "console/console.h" char_t EXECUTABLE_PATH[FILENAME_MAX]; char_t EXECUTABLE_DIRECTORY[FILENAME_MAX]; @@ -34,17 +33,13 @@ int32_t main(int32_t argc, char_t **argv) { } gameInit(); - // Print OS Information - const char* glfwVersionString = glfwGetVersionString(); - consolePrint("GLFW: %s", glfwVersionString); - // Init asset and render systems. assetInit(); renderInit(); // Prepare for time tracking double_t time, newTime; - float_t fDelta; + float_t fDelta, fTimeSinceLastFrame = 1.0f; int32_t updateResult; // Main loop @@ -53,10 +48,15 @@ int32_t main(int32_t argc, char_t **argv) { newTime = glfwGetTime(); fDelta = (float_t)(newTime - time); time = newTime; + fTimeSinceLastFrame += fDelta; - gameUpdate(fDelta); + // Tick according to the game tick rate. + if(fTimeSinceLastFrame >= (1.0f / GAME_TICK_RATE)) { + gameUpdate(); + fTimeSinceLastFrame = 0.0f; + } - // Draw + // Draw. In future may be tick based. renderUpdate(); windowUpdate(); }