From 1d7c318a3d81e087f330bd4695949c6f6ee563bd Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 9 Jan 2025 21:56:28 +0100 Subject: [PATCH] feat: integrated input --- src/core/canvas_engine.cpp | 2 ++ src/core/input/input_effects.cpp | 30 +++++++++++++++++++++++------- src/core/input/input_effects.hpp | 16 +++++++++------- src/core/input/input_map.cpp | 18 ++++++++++++------ src/core/input/input_map.hpp | 5 +++-- 5 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/core/canvas_engine.cpp b/src/core/canvas_engine.cpp index 6150458..aa9ead4 100644 --- a/src/core/canvas_engine.cpp +++ b/src/core/canvas_engine.cpp @@ -123,8 +123,10 @@ void CanvasEngine::process_event(SDL_Event const &evt) { this->request_close(); break; case SDL_KEYDOWN: + this->input_map.process_event(evt); break; case SDL_KEYUP: + this->input_map.process_event(evt); break; case SDL_WINDOWEVENT: this->draw(render); diff --git a/src/core/input/input_effects.cpp b/src/core/input/input_effects.cpp index 4a6b757..4272c2a 100644 --- a/src/core/input/input_effects.cpp +++ b/src/core/input/input_effects.cpp @@ -1,7 +1,11 @@ #include "input_effects.hpp" namespace ce { -bool GamepadButton::evaluate(SDL_Event const &evt, InputValue &value) const { +GamepadButton::GamepadButton(SDL_JoystickID device, SDL_GameControllerButton button) +: which{device} +, button{button} {} + +bool GamepadButton::evaluate(SDL_Event const &evt, InputValue &value) { switch(evt.type) { case SDL_CONTROLLERBUTTONDOWN: if(this->button == evt.cbutton.button && this->which == evt.cbutton.which) { @@ -20,7 +24,11 @@ bool GamepadButton::evaluate(SDL_Event const &evt, InputValue &value) const { return false; } -bool GamepadAxis::evaluate(SDL_Event const &evt, InputValue &value) const { +GamepadAxis::GamepadAxis(SDL_JoystickID device, SDL_GameControllerAxis axis) +: which{device} +, axis{axis} {} + +bool GamepadAxis::evaluate(SDL_Event const &evt, InputValue &value) { switch(evt.type) { case SDL_CONTROLLERAXISMOTION: if(evt.caxis.axis == this->axis && evt.caxis.which == this->which) { @@ -33,7 +41,10 @@ bool GamepadAxis::evaluate(SDL_Event const &evt, InputValue &value) const { return false; } -bool KeyboardScancode::evaluate(SDL_Event const &evt, InputValue &value) const { +KeyboardScancode::KeyboardScancode(SDL_Scancode code) +: code{code} {} + +bool KeyboardScancode::evaluate(SDL_Event const &evt, InputValue &value) { switch(evt.type) { case SDL_KEYDOWN: if(evt.key.keysym.scancode == this->code) { @@ -52,7 +63,10 @@ bool KeyboardScancode::evaluate(SDL_Event const &evt, InputValue &value) const { return false; } -bool KeyboardKey::evaluate(SDL_Event const &evt, InputValue &value) const { +KeyboardKey::KeyboardKey(SDL_Keycode code) +: key{code} {} + +bool KeyboardKey::evaluate(SDL_Event const &evt, InputValue &value) { switch(evt.type) { case SDL_KEYDOWN: if(evt.key.keysym.sym == this->key) { @@ -71,10 +85,12 @@ bool KeyboardKey::evaluate(SDL_Event const &evt, InputValue &value) const { return false; } -bool ButtonAxis::evaluate(SDL_Event const &evt, InputValue &value) const { +ButtonAxis::ButtonAxis(InputEffect *negative, InputEffect *positive) +: neg{negative} +, pos{positive} {} + +bool ButtonAxis::evaluate(SDL_Event const &evt, InputValue &value) { bool changed{false}; - InputValue neg_value{0.f}; - InputValue pos_value{0.f}; if(neg != nullptr) changed |= neg->evaluate(evt, neg_value); if(pos != nullptr) changed |= pos->evaluate(evt, pos_value); if(changed && neg_value.is() && pos_value.is()) { diff --git a/src/core/input/input_effects.hpp b/src/core/input/input_effects.hpp index 495ec03..cbbe12f 100644 --- a/src/core/input/input_effects.hpp +++ b/src/core/input/input_effects.hpp @@ -10,40 +10,42 @@ struct InputEffect { typedef std::unique_ptr Ptr; virtual ~InputEffect() = default; template Ptr make(Param... p); - virtual bool evaluate(SDL_Event const &evt, InputValue &value) const = 0; + virtual bool evaluate(SDL_Event const &evt, InputValue &value) = 0; }; struct GamepadButton : InputEffect { GamepadButton(SDL_JoystickID device, SDL_GameControllerButton button); SDL_JoystickID which{0}; SDL_GameControllerButton button{SDL_CONTROLLER_BUTTON_A}; - virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; + virtual bool evaluate(SDL_Event const &evt, InputValue &value) override; }; struct GamepadAxis : InputEffect { GamepadAxis(SDL_JoystickID device, SDL_GameControllerAxis axis); SDL_JoystickID which{0}; SDL_GameControllerAxis axis{SDL_CONTROLLER_AXIS_LEFTX}; - virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; + virtual bool evaluate(SDL_Event const &evt, InputValue &value) override; }; struct KeyboardScancode : InputEffect { KeyboardScancode(SDL_Scancode code); SDL_Scancode code{SDL_SCANCODE_0}; - virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; + virtual bool evaluate(SDL_Event const &evt, InputValue &value) override; }; struct KeyboardKey : InputEffect { KeyboardKey(SDL_Keycode code); SDL_Keycode key{SDLK_KP_0}; - virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; + virtual bool evaluate(SDL_Event const &evt, InputValue &value) override; }; struct ButtonAxis : InputEffect { - ButtonAxis(InputEffect::Ptr &negative, InputEffect::Ptr &positive); + ButtonAxis(InputEffect *negative, InputEffect *positive); InputEffect::Ptr neg{}; + InputValue neg_value{0.f}; InputEffect::Ptr pos{}; - virtual bool evaluate(SDL_Event const &evt, InputValue &value) const override; + InputValue pos_value{0.f}; + virtual bool evaluate(SDL_Event const &evt, InputValue &value) override; }; template InputEffect::Ptr InputEffect::make(Param... p) { diff --git a/src/core/input/input_map.cpp b/src/core/input/input_map.cpp index 3fa4092..cad1db3 100644 --- a/src/core/input/input_map.cpp +++ b/src/core/input/input_map.cpp @@ -7,9 +7,9 @@ InputAction::InputAction(InputEffect::Ptr &effect) { this->effects.push_back(std::move(effect)); } -InputAction::InputAction(std::vector &effects) { - for(InputEffect::Ptr &effect : effects) - this->effects.push_back(std::move(effect)); +InputAction::InputAction(std::vector &effects) { + for(InputEffect* effect : effects) + this->effects.push_back(std::move(std::unique_ptr(effect))); } void InputAction::process_event(SDL_Event const &evt) { @@ -23,8 +23,14 @@ void InputAction::process_event(SDL_Event const &evt) { this->changed.invoke(value); } -void InputMap::bind_input(std::string const &name, std::vector &effects) { - InputAction action{InputAction(effects)}; - this->bindings.insert({name, std::move(action)}); +InputAction &InputMap::bind_input(std::string const &name, std::vector &&effects) { + this->bindings.insert({name, InputAction(effects)}); + return this->bindings[name]; +} + +void InputMap::process_event(SDL_Event const &evt) { + for(std::pair &binding : this->bindings) { + binding.second.process_event(evt); + } } } diff --git a/src/core/input/input_map.hpp b/src/core/input/input_map.hpp index 23162aa..6d26f5e 100644 --- a/src/core/input/input_map.hpp +++ b/src/core/input/input_map.hpp @@ -25,7 +25,7 @@ public: Signal changed{}; InputAction() = default; InputAction(InputEffect::Ptr &effect); - InputAction(std::vector &effects); + InputAction(std::vector &effects); void process_event(SDL_Event const &evt); //!< process an incoming OS event @@ -37,8 +37,9 @@ public: class InputMap { std::map bindings{}; public: - void bind_input(std::string const &name, std::vector &binds); + InputAction &bind_input(std::string const &name, std::vector &&binds); InputAction &get_action(std::string const &action_id); + void process_event(SDL_Event const &evt); }; template Effect *InputAction::get_effect_of_type() {