From 57b3354d4cc5c280cbf14ad9793f7508d4597949 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 25 Oct 2022 20:55:05 -0700 Subject: [PATCH] InputManager finish --- src/dawn/CMakeLists.txt | 1 + src/dawn/game/DawnGame.hpp | 2 + src/dawn/input/CMakeLists.txt | 4 + src/dawn/input/_InputManager.hpp | 163 +++++++++++++++++++++++ src/dawnglfw/CMakeLists.txt | 3 +- src/dawnglfw/host/DawnGLFWHost.cpp | 25 ++++ src/dawnglfw/host/DawnGLFWHost.hpp | 6 +- src/dawnglfw/input/CMakeLists.txt | 10 ++ src/dawnglfw/input/InputManager.cpp | 20 +++ src/dawnglfw/input/InputManager.hpp | 19 +++ src/dawnpokergame/game/DawnPokerGame.cpp | 4 +- 11 files changed, 254 insertions(+), 3 deletions(-) create mode 100644 src/dawn/input/CMakeLists.txt create mode 100644 src/dawn/input/_InputManager.hpp create mode 100644 src/dawnglfw/input/CMakeLists.txt create mode 100644 src/dawnglfw/input/InputManager.cpp create mode 100644 src/dawnglfw/input/InputManager.hpp diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt index 82074828..5d1b4b2f 100644 --- a/src/dawn/CMakeLists.txt +++ b/src/dawn/CMakeLists.txt @@ -19,5 +19,6 @@ target_include_directories(${DAWN_TARGET_NAME} # Subdirs add_subdirectory(asset) add_subdirectory(display) +add_subdirectory(input) add_subdirectory(scene) add_subdirectory(ui) \ No newline at end of file diff --git a/src/dawn/game/DawnGame.hpp b/src/dawn/game/DawnGame.hpp index 64956a15..fec6cf96 100644 --- a/src/dawn/game/DawnGame.hpp +++ b/src/dawn/game/DawnGame.hpp @@ -8,6 +8,7 @@ #include "scene/Scene.hpp" #include "display/RenderManager.hpp" #include "asset/AssetManager.hpp" +#include "input/InputManager.hpp" #define DAWN_GAME_INIT_RESULT_SUCCESS 0 #define DAWN_GAME_UPDATE_RESULT_SUCCESS 0 @@ -22,6 +23,7 @@ namespace Dawn { DawnHost &host; RenderManager renderManager; AssetManager assetManager; + InputManager inputManager; /** * Construct a new instance of the DawnGame. diff --git a/src/dawn/input/CMakeLists.txt b/src/dawn/input/CMakeLists.txt new file mode 100644 index 00000000..5c38ab94 --- /dev/null +++ b/src/dawn/input/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT \ No newline at end of file diff --git a/src/dawn/input/_InputManager.hpp b/src/dawn/input/_InputManager.hpp new file mode 100644 index 00000000..ae1d3ddc --- /dev/null +++ b/src/dawn/input/_InputManager.hpp @@ -0,0 +1,163 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "dawnlibs.hpp" +#include "util/mathutils.hpp" + +namespace Dawn { + class DawnGame; + typedef int_fast16_t inputbind_t; + + template + class IInputManager { + protected: + std::map> binds; + std::map valuesLeft; + std::map valuesRight; + bool_t currentIsLeft = true; + + /** + * Method to be overwritten by the platform, reads a RAW input value from + * the pad/input device directly. + * + * @param axis Axis to get the value of. + * @return The current input value (between 0 and 1). + */ + virtual float_t getInputValue(T axis) = 0; + + public: + DawnGame &game; + + IInputManager(DawnGame &game) : game(game) {} + + /** + * Binds an axis to a bind. + * + * @param bind Bind to bind the axis to. + * @param axis Axis to use for this bind. + */ + void bind(inputbind_t bind, T axis) { + this->binds[bind].push_back(axis); + } + + /** + * Unbind a previously bound axis from a bind. + * + * @param bind Bind to remove all binds from. + */ + void unbind(inputbind_t bind) { + this->binds[bind].clear(); + } + + /** + * Unbind all values, all of them. + */ + void unbindAll() { + this->binds.clear(); + this->values.clear(); + } + + /** + * Return the current bind value. + * + * @param bind Bind to get the value of. + * @return The current input state (between 0 and 1). + */ + float_t getValue(inputbind_t bind) { + if(this->currentIsLeft) { + auto exist = this->valuesLeft.find(bind); + return exist == this->valuesLeft.end() ? 0.0f : exist->second; + } else { + auto exist = this->valuesRight.find(bind); + return exist == this->valuesRight.end() ? 0.0f : exist->second; + } + } + + /** + * Return the bind value from the previous frame. + * + * @param bind Bind to get the value of. + * @return The value of the bind, last frame. + */ + float_t getValueLastUpdate(inputbind_t bind) { + if(this->currentIsLeft) { + auto exist = this->valuesRight.find(bind); + return exist == this->valuesRight.end() ? 0.0f : exist->second; + } else { + auto exist = this->valuesLeft.find(bind); + return exist == this->valuesLeft.end() ? 0.0f : exist->second; + } + } + + /** + * Returns true if the given bind is currently being pressed (a non-zero + * value). + * + * @param bind Bind to check if pressed. + * @return True if value is non-zero, or false for zero. + */ + bool_t isDown(inputbind_t bind) { + return this->getValue(bind) != 0.0f; + } + + /** + * Returns true on the first frame an input was pressed (when the state + * had changed from 0 to non-zero). + * + * @param bind Bind to check if pressed. + * @return True if down this frame and not down last frame. + */ + bool_t isPressed(inputbind_t bind) { + return this->getValue(bind)!=0 && this->getValueLastUpdate(bind)==0; + } + + /** + * Returns true on the first frame an input was released (when the state + * had changed from non-zero to 0). + * + * @param bind Bind to check if released. + * @return True if up this frame, and down last frame. + */ + bool_t wasReleased(inputbind_t bind) { + return this->getValue(bind)==0 && this->getValueLastUpdate(bind)!=0; + } + + /** + * Internal method to update the input state, checks current input raws + * and decides what values are set for the inputs. + */ + void update() { + auto it = this->binds.begin(); + this->currentIsLeft = !this->currentIsLeft; + + // For each bind... + while(it != this->binds.end()) { + float_t value = 0.0f; + + // For each input axis... + auto bindIt = it->second.begin(); + while(bindIt != it->second.end()) { + // Get value and make the new max. + float_t inputValue = this->getInputValue(*bindIt); + value = mathMax(value, inputValue); + ++bindIt; + } + + std::cout << "Bind " << it->first << ": " << value << std::endl; + + // Set into current values + if(this->currentIsLeft) { + this->valuesLeft[it->first] = value; + } else { + this->valuesRight[it->first] = value; + } + ++it; + } + + // TODO: trigger events + } + }; +} \ No newline at end of file diff --git a/src/dawnglfw/CMakeLists.txt b/src/dawnglfw/CMakeLists.txt index d8503e49..a4474e04 100644 --- a/src/dawnglfw/CMakeLists.txt +++ b/src/dawnglfw/CMakeLists.txt @@ -17,4 +17,5 @@ target_include_directories(${DAWN_TARGET_NAME} ) # Subdirs -add_subdirectory(host) \ No newline at end of file +add_subdirectory(host) +add_subdirectory(input) \ No newline at end of file diff --git a/src/dawnglfw/host/DawnGLFWHost.cpp b/src/dawnglfw/host/DawnGLFWHost.cpp index ad332beb..34907798 100644 --- a/src/dawnglfw/host/DawnGLFWHost.cpp +++ b/src/dawnglfw/host/DawnGLFWHost.cpp @@ -54,6 +54,7 @@ int32_t DawnHost::init(DawnGame &game) { auto result = game.init(); if(result != DAWN_GAME_INIT_RESULT_SUCCESS) return result; + // Override the defaults game.renderManager.backBuffer.setSize( DAWN_GLFW_WINDOW_WIDTH_DEFAULT, DAWN_GLFW_WINDOW_HEIGHT_DEFAULT @@ -61,6 +62,7 @@ int32_t DawnHost::init(DawnGame &game) { // Set up event listeners glfwSetWindowSizeCallback(this->data->window, &glfwOnResize); + glfwSetKeyCallback(this->data->window, &glfwOnKey); return DAWN_HOST_INIT_RESULT_SUCCESS; } @@ -139,4 +141,27 @@ void glfwOnResize( (float_t)width, (float_t)height ); +} + +void glfwOnKey( + GLFWwindow *window, + int32_t key, + int32_t scancode, + int32_t action, + int32_t mods +) { + if(DAWN_HOST == nullptr) return; + + // Determine Value + float_t value; + if(action == GLFW_PRESS) { + value = 1.0f; + } else if(action == GLFW_RELEASE) { + value = 0.0f; + } else { + return; + } + + // Determine the input axis + DAWN_HOST->game->inputManager.rawInputValues[key] = value; } \ No newline at end of file diff --git a/src/dawnglfw/host/DawnGLFWHost.hpp b/src/dawnglfw/host/DawnGLFWHost.hpp index 54ed7944..7d35fb8b 100644 --- a/src/dawnglfw/host/DawnGLFWHost.hpp +++ b/src/dawnglfw/host/DawnGLFWHost.hpp @@ -26,4 +26,8 @@ namespace Dawn { // GLFW Callbacks void glfwOnError(int error, const char* description); -void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height); \ No newline at end of file +void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height); +void glfwOnKey( + GLFWwindow *window, + int32_t key, int32_t scancode, int32_t action, int32_t mods +); \ No newline at end of file diff --git a/src/dawnglfw/input/CMakeLists.txt b/src/dawnglfw/input/CMakeLists.txt new file mode 100644 index 00000000..5b301e2b --- /dev/null +++ b/src/dawnglfw/input/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DAWN_TARGET_NAME} + PRIVATE + InputManager.cpp +) \ No newline at end of file diff --git a/src/dawnglfw/input/InputManager.cpp b/src/dawnglfw/input/InputManager.cpp new file mode 100644 index 00000000..9cd9649d --- /dev/null +++ b/src/dawnglfw/input/InputManager.cpp @@ -0,0 +1,20 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "InputManager.hpp" +#include "game/DawnGame.hpp" + +using namespace Dawn; + +InputManager::InputManager(DawnGame &game) : IInputManager(game) { + +} + +float_t InputManager::getInputValue(int32_t axis) { + auto exist = this->rawInputValues.find(axis); + if(exist == this->rawInputValues.end()) return 0.0f; + + return exist->second; +} \ No newline at end of file diff --git a/src/dawnglfw/input/InputManager.hpp b/src/dawnglfw/input/InputManager.hpp new file mode 100644 index 00000000..fa83ba3b --- /dev/null +++ b/src/dawnglfw/input/InputManager.hpp @@ -0,0 +1,19 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "input/_InputManager.hpp" + +namespace Dawn { + class InputManager : public IInputManager { + protected: + float_t getInputValue(int32_t axis) override; + + public: + std::map rawInputValues; + + InputManager(DawnGame &game); + }; +} \ No newline at end of file diff --git a/src/dawnpokergame/game/DawnPokerGame.cpp b/src/dawnpokergame/game/DawnPokerGame.cpp index b69cf8a3..7ec5da27 100644 --- a/src/dawnpokergame/game/DawnPokerGame.cpp +++ b/src/dawnpokergame/game/DawnPokerGame.cpp @@ -15,7 +15,8 @@ float_t fs = 1.0f; DawnGame::DawnGame(DawnHost &host) : host(host), - renderManager(*this) + renderManager(*this), + inputManager(*this) { } @@ -62,6 +63,7 @@ int32_t DawnGame::init() { int32_t DawnGame::update(float_t delta) { this->assetManager.update(); + this->inputManager.update(); if(this->scene != nullptr) this->scene->update();