This commit is contained in:
2025-09-20 17:57:56 -05:00
parent a896b772fb
commit 90c3b6149e
16 changed files with 469 additions and 74 deletions

View File

@@ -4,57 +4,239 @@
// https://opensource.org/licenses/MIT
#include "Input.hpp"
#include "assert/Assert.hpp"
#include "engine/Engine.hpp"
using namespace Dawn;
Input::Input(void) :
Input::Input(Engine &engine) :
engine(engine),
states({}),
buttons({})
{
engine.console.registerCommand("bind", [this](auto console, auto args) {
if(args.size() == 0) {
this->engine.console.print("Usage: bind <input> [command]");
return;
}
// Find input by name.
auto itButton = this->buttons.begin();
while(itButton != this->buttons.end()) {
if(itButton->getName() == args[0]) break;
++itButton;
}
if(itButton == this->buttons.end()) {
this->engine.console.print("No such input: %s", args[0].c_str());
return;
}
// Is there a second arg?
if(args.size() == 1) {
auto bind = itButton->getBind();
if(bind) {
console.print(bind->getName());
} else {
console.print(itButton->getCommand());
}
return;
}
// Is there a bind for the arg?
auto itBind = InputBind::ALL_BINDS.begin();
while(itBind != InputBind::ALL_BINDS.end()) {
if(strcasecmp((*itBind)->getName().c_str(),args[1].c_str()) == 0) break;
++itBind;
}
// This is a bind?
if(itBind != InputBind::ALL_BINDS.end()) {
itButton->setBind(const_cast<InputBind*>(*itBind));
return;
}
// This is a command then.
itButton->setCommand(args[1]);
});
#if DAWN_SDL2
buttons.push_back(InputButton("esc", InputButtonType::KEY, { .scancode = SDL_SCANCODE_ESCAPE }));
buttons.push_back(InputButton("1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_1 }));
buttons.push_back(InputButton("2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_2 }));
buttons.push_back(InputButton("3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_3 }));
buttons.push_back(InputButton("4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_4 }));
buttons.push_back(InputButton("5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_5 }));
buttons.push_back(InputButton("6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_6 }));
buttons.push_back(InputButton("7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_7 }));
buttons.push_back(InputButton("8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_8 }));
buttons.push_back(InputButton("9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_9 }));
buttons.push_back(InputButton("0", InputButtonType::KEY, { .scancode = SDL_SCANCODE_0 }));
buttons.push_back(InputButton("-", InputButtonType::KEY, { .scancode = SDL_SCANCODE_MINUS }));
buttons.push_back(InputButton("backspace", InputButtonType::KEY, { .scancode = SDL_SCANCODE_BACKSPACE }));
buttons.push_back(InputButton("tab", InputButtonType::KEY, { .scancode = SDL_SCANCODE_TAB }));
buttons.push_back(InputButton("q", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Q }));
buttons.push_back(InputButton("w", InputButtonType::KEY, { .scancode = SDL_SCANCODE_W }));
buttons.push_back(InputButton("e", InputButtonType::KEY, { .scancode = SDL_SCANCODE_E }));
buttons.push_back(InputButton("r", InputButtonType::KEY, { .scancode = SDL_SCANCODE_R }));
buttons.push_back(InputButton("t", InputButtonType::KEY, { .scancode = SDL_SCANCODE_T }));
buttons.push_back(InputButton("y", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Y }));
buttons.push_back(InputButton("u", InputButtonType::KEY, { .scancode = SDL_SCANCODE_U }));
buttons.push_back(InputButton("i", InputButtonType::KEY, { .scancode = SDL_SCANCODE_I }));
buttons.push_back(InputButton("o", InputButtonType::KEY, { .scancode = SDL_SCANCODE_O }));
buttons.push_back(InputButton("p", InputButtonType::KEY, { .scancode = SDL_SCANCODE_P }));
buttons.push_back(InputButton("[", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LEFTBRACKET }));
buttons.push_back(InputButton("]", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RIGHTBRACKET }));
buttons.push_back(InputButton("enter", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RETURN }));
buttons.push_back(InputButton("a", InputButtonType::KEY, { .scancode = SDL_SCANCODE_A }));
buttons.push_back(InputButton("s", InputButtonType::KEY, { .scancode = SDL_SCANCODE_S }));
buttons.push_back(InputButton("d", InputButtonType::KEY, { .scancode = SDL_SCANCODE_D }));
buttons.push_back(InputButton("f", InputButtonType:: KEY, { .scancode = SDL_SCANCODE_F }));
buttons.push_back(InputButton("g", InputButtonType::KEY, { .scancode = SDL_SCANCODE_G }));
buttons.push_back(InputButton("h", InputButtonType::KEY, { .scancode = SDL_SCANCODE_H }));
buttons.push_back(InputButton("j", InputButtonType::KEY, { .scancode = SDL_SCANCODE_J }));
buttons.push_back(InputButton("k", InputButtonType::KEY, { .scancode = SDL_SCANCODE_K }));
buttons.push_back(InputButton("l", InputButtonType::KEY, { .scancode = SDL_SCANCODE_L }));
buttons.push_back(InputButton(";", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SEMICOLON }));
buttons.push_back(InputButton("'", InputButtonType::KEY, { .scancode = SDL_SCANCODE_APOSTROPHE }));
buttons.push_back(InputButton("`", InputButtonType::KEY, { .scancode = SDL_SCANCODE_GRAVE }));
buttons.push_back(InputButton("\\", InputButtonType::KEY, { .scancode = SDL_SCANCODE_BACKSLASH }));
buttons.push_back(InputButton("z", InputButtonType::KEY, { .scancode = SDL_SCANCODE_Z }));
buttons.push_back(InputButton("x", InputButtonType::KEY, { .scancode = SDL_SCANCODE_X }));
buttons.push_back(InputButton("c", InputButtonType::KEY, { .scancode = SDL_SCANCODE_C }));
buttons.push_back(InputButton("v", InputButtonType::KEY, { .scancode = SDL_SCANCODE_V }));
buttons.push_back(InputButton("b", InputButtonType::KEY, { .scancode = SDL_SCANCODE_B }));
buttons.push_back(InputButton("n", InputButtonType::KEY, { .scancode = SDL_SCANCODE_N }));
buttons.push_back(InputButton("m", InputButtonType::KEY, { .scancode = SDL_SCANCODE_M }));
buttons.push_back(InputButton(",", InputButtonType::KEY, { .scancode = SDL_SCANCODE_COMMA }));
buttons.push_back(InputButton(".", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PERIOD }));
buttons.push_back(InputButton("/", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SLASH }));
buttons.push_back(InputButton("space", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SPACE }));
buttons.push_back(InputButton("capslock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_CAPSLOCK }));
buttons.push_back(InputButton("f1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F1 }));
buttons.push_back(InputButton("f2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F2 }));
buttons.push_back(InputButton("f3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F3 }));
buttons.push_back(InputButton("f4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F4 }));
buttons.push_back(InputButton("f5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F5 }));
buttons.push_back(InputButton("f6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F6 }));
buttons.push_back(InputButton("f7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F7 }));
buttons.push_back(InputButton("f8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F8 }));
buttons.push_back(InputButton("f9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F9 }));
buttons.push_back(InputButton("f10", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F10 }));
buttons.push_back(InputButton("f11", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F11 }));
buttons.push_back(InputButton("f12", InputButtonType::KEY, { .scancode = SDL_SCANCODE_F12 }));
buttons.push_back(InputButton("printscreen", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PRINTSCREEN }));
buttons.push_back(InputButton("scrolllock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_SCROLLLOCK }));
buttons.push_back(InputButton("pause", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAUSE }));
buttons.push_back(InputButton("insert", InputButtonType::KEY, { .scancode = SDL_SCANCODE_INSERT }));
buttons.push_back(InputButton("home", InputButtonType::KEY, { .scancode = SDL_SCANCODE_HOME }));
buttons.push_back(InputButton("end", InputButtonType::KEY, { .scancode = SDL_SCANCODE_END }));
buttons.push_back(InputButton("pageup", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAGEUP }));
buttons.push_back(InputButton("pagedown", InputButtonType::KEY, { .scancode = SDL_SCANCODE_PAGEDOWN }));
buttons.push_back(InputButton("delete", InputButtonType::KEY, { .scancode = SDL_SCANCODE_DELETE }));
buttons.push_back(InputButton("right", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RIGHT }));
buttons.push_back(InputButton("left", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LEFT }));
buttons.push_back(InputButton("down", InputButtonType::KEY, { .scancode = SDL_SCANCODE_DOWN }));
buttons.push_back(InputButton("up", InputButtonType::KEY, { .scancode = SDL_SCANCODE_UP }));
buttons.push_back(InputButton("numlock", InputButtonType::KEY, { .scancode = SDL_SCANCODE_NUMLOCKCLEAR }));
buttons.push_back(InputButton("kp_divide", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_DIVIDE }));
buttons.push_back(InputButton("kp_multiply", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_MULTIPLY }));
buttons.push_back(InputButton("kp_minus", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_MINUS }));
buttons.push_back(InputButton("kp_plus", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_PLUS }));
buttons.push_back(InputButton("kp_enter", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_ENTER }));
buttons.push_back(InputButton("kp_1", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_1 }));
buttons.push_back(InputButton("kp_2", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_2 }));
buttons.push_back(InputButton("kp_3", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_3 }));
buttons.push_back(InputButton("kp_4", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_4 }));
buttons.push_back(InputButton("kp_5", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_5 }));
buttons.push_back(InputButton("kp_6", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_6 }));
buttons.push_back(InputButton("kp_7", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_7 }));
buttons.push_back(InputButton("kp_8", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_8 }));
buttons.push_back(InputButton("kp_9", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_9 }));
buttons.push_back(InputButton("kp_0", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_0 }));
buttons.push_back(InputButton("kp_period", InputButtonType::KEY, { .scancode = SDL_SCANCODE_KP_PERIOD }));
buttons.push_back(InputButton("ctrl", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LCTRL }));
buttons.push_back(InputButton("shift", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LSHIFT }));
buttons.push_back(InputButton("alt", InputButtonType::KEY, { .scancode = SDL_SCANCODE_LALT }));
buttons.push_back(InputButton("rctrl", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RCTRL }));
buttons.push_back(InputButton("rshift", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RSHIFT }));
buttons.push_back(InputButton("ralt", InputButtonType::KEY, { .scancode = SDL_SCANCODE_RALT }));
#endif
}
float_t Input::getCurrent(const InputBind &bind) const {
float_t Input::getCurrent(const InputBind *bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
auto it = states.find(bind);
if(it != states.end()) {
return it->second.current;
}
if(it != states.end()) return it->second.current;
return 0.0f;
}
float_t Input::getPrevious(const InputBind &bind) const {
float_t Input::getPrevious(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
auto it = states.find(bind);
if(it != states.end()) {
return it->second.previous;
}
if(it != states.end()) return it->second.previous;
return 0.0f;
}
float_t Input::getWhen(const InputBind &bind) const {
float_t Input::getWhen(const InputBind *bind) const {
auto it = states.find(bind);
if(it != states.end()) {
return it->second.when;
}
if(it != states.end()) return it->second.when;
return 0.0f;
}
bool_t Input::isDown(const InputBind &bind) const {
bool_t Input::isDown(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getCurrent(bind) != 0.0f;
}
bool_t Input::isUp(const InputBind &bind) const {
bool_t Input::isUp(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getCurrent(bind) == 0.0f;
}
bool_t Input::wasPressed(const InputBind &bind) const {
bool_t Input::wasPressed(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getPrevious(bind) == 0.0f && this->getCurrent(bind) != 0.0f;
}
bool_t Input::wasReleased(const InputBind &bind) const {
bool_t Input::wasReleased(const InputBind* bind) const {
assertNotNull(bind, "Input bind cannot be NULL");
return this->getPrevious(bind) != 0.0f && this->getCurrent(bind) == 0.0f;
}
void Input::update(void) {
// Reset all input bind states
for(auto &state : this->states) {
state.second.previous = state.second.current;
state.second.current = 0.0f;
}
// Update button states.
auto itButton = this->buttons.begin();
while(itButton != this->buttons.end()) {
itButton->update();
if(itButton->getCurrent() != 0.0f) {
// Exec command if actuated this tick.
auto cmd = itButton->getCommand();
if(itButton->getPrevious() == 0.0f && cmd.length() > 0) {
engine.console.exec(cmd);
} else {
// If bound to an input, update the bind state.
auto bind = itButton->getBind();
if(bind != nullptr) {
states[bind].when = engine.time.time;
states[bind].current = fmaxf(
states[bind].current, itButton->getCurrent()
);
}
}
}
++itButton;
}
}
Input::~Input(void) {