feat: integrated input

main
Sara 2025-01-09 21:56:28 +01:00
parent d4a436da2f
commit 1d7c318a3d
5 changed files with 49 additions and 22 deletions

View File

@ -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);

View File

@ -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<float>() && pos_value.is<float>()) {

View File

@ -10,40 +10,42 @@ struct InputEffect {
typedef std::unique_ptr<InputEffect> Ptr;
virtual ~InputEffect() = default;
template<class Effect, typename... Param> 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 <class Effect, typename... Param> InputEffect::Ptr InputEffect::make(Param... p) {

View File

@ -7,9 +7,9 @@ InputAction::InputAction(InputEffect::Ptr &effect) {
this->effects.push_back(std::move(effect));
}
InputAction::InputAction(std::vector<InputEffect::Ptr> &effects) {
for(InputEffect::Ptr &effect : effects)
this->effects.push_back(std::move(effect));
InputAction::InputAction(std::vector<InputEffect*> &effects) {
for(InputEffect* effect : effects)
this->effects.push_back(std::move(std::unique_ptr<InputEffect>(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<InputEffect::Ptr> &effects) {
InputAction action{InputAction(effects)};
this->bindings.insert({name, std::move(action)});
InputAction &InputMap::bind_input(std::string const &name, std::vector<InputEffect*> &&effects) {
this->bindings.insert({name, InputAction(effects)});
return this->bindings[name];
}
void InputMap::process_event(SDL_Event const &evt) {
for(std::pair<std::string const, InputAction> &binding : this->bindings) {
binding.second.process_event(evt);
}
}
}

View File

@ -25,7 +25,7 @@ public:
Signal<InputValue> changed{};
InputAction() = default;
InputAction(InputEffect::Ptr &effect);
InputAction(std::vector<InputEffect::Ptr> &effects);
InputAction(std::vector<InputEffect*> &effects);
void process_event(SDL_Event const &evt); //!< process an incoming OS event
@ -37,8 +37,9 @@ public:
class InputMap {
std::map<std::string, InputAction> bindings{};
public:
void bind_input(std::string const &name, std::vector<InputEffect::Ptr> &binds);
InputAction &bind_input(std::string const &name, std::vector<InputEffect*> &&binds);
InputAction &get_action(std::string const &action_id);
void process_event(SDL_Event const &evt);
};
template <class Effect> Effect *InputAction::get_effect_of_type() {