#include "client/input.hh" namespace { std::vector event_callbacks; struct keystate { bool pressed; bool toggled; // !'ed each keypress. }; std::unordered_map keystates; } // namespace namespace client { namespace input { void set_mouse_position(const glm::ivec2& d) noexcept { SDL_WarpMouseInWindow(client::render::get_sdl_window(), d.x, d.y); } void set_text_input(const bool should_start) noexcept { if (should_start) { SDL_StartTextInput(); } else { SDL_StopTextInput(); state.text_input.clear(); } state.typing = should_start; } void set_mouse_relative(const bool b) noexcept { if (const int status = SDL_SetRelativeMouseMode(b ? SDL_TRUE : SDL_FALSE); status != 0) { throw std::runtime_error(SDL_GetError()); } } static void handle_press(const SDL_Event& event) noexcept { keystate& ks = ::keystates[event.key.keysym.sym]; ks.pressed = true; if (!event.key.repeat) { ks.toggled = !ks.toggled; } } static void handle_lift(const SDL_Event& event) noexcept { keystate& ks = ::keystates[event.key.keysym.sym]; ks.pressed = false; } static void handle_windowevent(const SDL_Event& event) noexcept { switch (event.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: state.focused = true; break; case SDL_WINDOWEVENT_FOCUS_LOST: state.focused = false; break; } } static void handle_textinput(const SDL_Event& event) noexcept { state.text_input += event.text.text; } static void handle_quit(const SDL_Event&) noexcept { state.quit = true; } bool is_key_pressed(const SDL_Keycode& key) noexcept { return ::keystates[key].pressed; } bool is_key_toggled(const SDL_Keycode& key) noexcept { return ::keystates[key].toggled; } void register_event_handler(const event_callback& ec) noexcept { ::event_callbacks.push_back(ec); } // definition of a fun function (not as fun anymore) void update() noexcept { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_WINDOWEVENT: handle_windowevent(event); break; case SDL_TEXTINPUT: handle_textinput(event); break; case SDL_QUIT: handle_quit(event); break; case SDL_KEYDOWN: handle_press(event); break; case SDL_KEYUP: handle_lift(event); break; } for (auto& callback : ::event_callbacks) { callback(event); } } } } // namespace input } // namespace client