From 433a2eae15b096eb950aa2ee36547c686386862b Mon Sep 17 00:00:00 2001 From: Stepanov Igor Date: Sun, 5 Oct 2025 02:51:05 +0300 Subject: [PATCH] Fix mouse pos detect --- src/window/detail/input_sdl.cpp | 161 ++++++++++++++++++-------- src/window/detail/input_sdl.hpp | 15 +++ src/window/input.cpp | 54 ++++++--- src/window/input.hpp | 199 +++++++++++++++----------------- 4 files changed, 264 insertions(+), 165 deletions(-) diff --git a/src/window/detail/input_sdl.cpp b/src/window/detail/input_sdl.cpp index 476245b6c..4ed84e415 100644 --- a/src/window/detail/input_sdl.cpp +++ b/src/window/detail/input_sdl.cpp @@ -3,65 +3,119 @@ #include #include #include +#include #include #include -#include - #include "debug/Logger.hpp" +#include "window/input.hpp" static debug::Logger logger("input"); std::string input_util::to_string(Keycode code) { - return {}; + int icode_repr = static_cast(code); + const char* name = SDL_GetKeyName(icode_repr); + logger.info() << icode_repr << ": " << name; + return std::string(name); +} + +Keycode input_util::keycode_from(const std::string& name) { + logger.info() << name << ": " << SDL_GetKeyFromName(name.c_str()); + return static_cast(SDL_GetKeyFromName(name.c_str())); } input_sdl::input_sdl() { + input_util::initialize(); } void input_sdl::pollEvents() { - /* static */ SDL_Event event; + delta.x = 0.0f; + delta.y = 0.0f; + scroll = 0; + currentFrame++; + codepoints.clear(); + pressedKeys.clear(); + + bool prevPressed = false; + + static SDL_Event event; while (SDL_PollEvent(&event)) { - + switch (event.type) { + case SDL_EVENT_QUIT: + break; + case SDL_EVENT_KEY_DOWN: + logger.info() << "Keyboard button: " << event.key.key; + if (event.key.key >= keys_buffer_size) { + // Win key return 1073742051 + break; + } + prevPressed = keys[event.key.key]; + keys[event.key.key] = true; + frames[event.key.key] = currentFrame; + if (!prevPressed) { + keyCallbacks[static_cast(event.key.key)].notify(); + } + pressedKeys.push_back(static_cast(event.key.key)); + break; + case SDL_EVENT_KEY_UP: + if (event.key.key >= keys_buffer_size) { + // Win key return 1073742051 + break; + } + keys[event.key.key] = false; + frames[event.key.key] = currentFrame; + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + prevPressed = keys[event.button.button + mouse_keys_offset]; + keys[event.button.button + mouse_keys_offset] = true; + frames[event.button.button + mouse_keys_offset] = currentFrame; + if (!prevPressed) { + keyCallbacks[static_cast( + event.button.button + mouse_keys_offset + )] + .notify(); + } + break; + case SDL_EVENT_MOUSE_BUTTON_UP: + keys[event.button.button + mouse_keys_offset] = false; + frames[event.button.button + mouse_keys_offset] = currentFrame; + break; + case SDL_EVENT_MOUSE_MOTION: + cursor = {event.motion.x, event.motion.y}; + delta = {event.motion.xrel, event.motion.yrel}; + break; + } } - // delta.x = 0.0f; - // delta.y = 0.0f; - // scroll = 0; - // currentFrame++; - // codepoints.clear(); - // pressedKeys.clear(); - // glfwPollEvents(); + for (auto& [_, binding] : bindings.getAll()) { + if (!binding.enabled) { + binding.state = false; + continue; + } + binding.justChanged = false; - // for (auto& [_, binding] : bindings.getAll()) { - // if (!binding.enabled) { - // binding.state = false; - // continue; - // } - // binding.justChanged = false; + bool newstate = false; + switch (binding.type) { + case InputType::KEYBOARD: + newstate = pressed(static_cast(binding.code)); + break; + case InputType::MOUSE: + newstate = clicked(static_cast(binding.code)); + break; + } - // bool newstate = false; - // switch (binding.type) { - // case InputType::KEYBOARD: - // newstate = pressed(static_cast(binding.code)); - // break; - // case InputType::MOUSE: - // newstate = clicked(static_cast(binding.code)); - // break; - // } - - // if (newstate) { - // if (!binding.state) { - // binding.state = true; - // binding.justChanged = true; - // binding.onactived.notify(); - // } - // } else { - // if (binding.state) { - // binding.state = false; - // binding.justChanged = true; - // } - // } - // } + if (newstate) { + if (!binding.state) { + binding.state = true; + binding.justChanged = true; + binding.onactived.notify(); + } + } else { + if (binding.state) { + binding.state = false; + binding.justChanged = true; + } + } + } } const char* input_sdl::getClipboardText() const { @@ -73,29 +127,38 @@ void input_sdl::setClipboardText(const char* text) { } int input_sdl::getScroll() { - return {}; + return scroll; } bool input_sdl::pressed(Keycode key) const { - return {}; + int keycode = static_cast(key); + if (keycode < 0 || keycode >= keys_buffer_size) { + return false; + } + if (keys[keycode]) logger.info() << "lol"; + return keys[keycode]; } bool input_sdl::jpressed(Keycode keycode) const { - return {}; + return pressed(keycode) && + frames[static_cast(keycode)] == currentFrame; } bool input_sdl::clicked(Mousecode code) const { - return {}; + return pressed( + static_cast(mouse_keys_offset + static_cast(code)) + ); } bool input_sdl::jclicked(Mousecode code) const { - return {}; + return clicked(code) && + frames[static_cast(code) + mouse_keys_offset] == currentFrame; } CursorState input_sdl::getCursor() const { - return {isCursorLocked(), {}, {}}; + return {isCursorLocked(), cursor, delta}; } bool input_sdl::isCursorLocked() const { - return {}; + return cursorLocked; } void input_sdl::toggleCursor() { @@ -117,7 +180,7 @@ const Bindings& input_sdl::getBindings() const { } ObserverHandler input_sdl::addKeyCallback(Keycode key, KeyCallback callback) { - return {}; + return keyCallbacks[key].add(std::move(callback)); } const std::vector& input_sdl::getPressedKeys() const { diff --git a/src/window/detail/input_sdl.hpp b/src/window/detail/input_sdl.hpp index 3d9caa6f0..9bc5c8415 100644 --- a/src/window/detail/input_sdl.hpp +++ b/src/window/detail/input_sdl.hpp @@ -1,9 +1,15 @@ +#include #include "window/input.hpp" +#include "window/window.hpp" + struct SDL_Window; class input_sdl final : public Input { public: + inline static constexpr short keys_buffer_size = 1036; + inline static constexpr short mouse_keys_offset = 1024; + input_sdl(); void pollEvents() override; @@ -33,7 +39,16 @@ public: const std::vector& getPressedKeys() const override; const std::vector& getCodepoints() const override; private: + glm::vec2 delta; + glm::vec2 cursor; + std::int32_t scroll = 0; + std::uint32_t currentFrame = 0; + std::uint32_t frames[keys_buffer_size] {}; + bool keys[keys_buffer_size] {}; + bool cursorLocked = false; + bool cursorDrag = false; Bindings bindings; std::vector codepoints; std::vector pressedKeys; + std::unordered_map> keyCallbacks; }; \ No newline at end of file diff --git a/src/window/input.cpp b/src/window/input.cpp index 73bbe6327..c774c6209 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -4,14 +4,35 @@ #include "debug/Logger.hpp" #include "util/stringutil.hpp" +#include + debug::Logger logger("input"); +static std::unordered_map keynames {}; +static std::unordered_map buttonsnames {}; + +static std::unordered_map mousecodes { + {"left", SDL_BUTTON_LEFT}, + {"right", SDL_BUTTON_RIGHT}, + {"middle", SDL_BUTTON_MIDDLE}, + {"side1", SDL_BUTTON_X1}, + {"side2", SDL_BUTTON_X2}, +}; + std::string input_util::get_name(Mousecode code) { - return {}; + const auto found = buttonsnames.find(static_cast(code)); + if (found == buttonsnames.end()) { + return "unknown"; + } + return found->second; } std::string input_util::get_name(Keycode code) { - return {}; + const auto found = keynames.find(static_cast(code)); + if (found == keynames.end()) { + return "unknown"; + } + return found->second; } void Binding::reset(InputType type, int code) { @@ -27,18 +48,28 @@ void Binding::reset(Mousecode code) { reset(InputType::MOUSE, static_cast(code)); } -void input_util::initialize() { - -} - -Keycode input_util::keycode_from(const std::string& name) { - return {}; -} - Mousecode input_util::mousecode_from(const std::string& name) { return {}; } +void input_util::initialize() { + // for (int i = 0; i <= 9; i++) { + // keycodes[std::to_string(i)] = GLFW_KEY_0 + i; + // } + // for (int i = 0; i < 25; i++) { + // keycodes["f" + std::to_string(i + 1)] = GLFW_KEY_F1 + i; + // } + // for (char i = 'a'; i <= 'z'; i++) { + // keycodes[std::string({i})] = GLFW_KEY_A - 'a' + i; + // } + // for (const auto& entry : keycodes) { + // keynames[entry.second] = entry.first; + // } + for (const auto& entry : mousecodes) { + buttonsnames[entry.second] = entry.first; + } +} + std::string input_util::to_string(Mousecode code) { switch (code) { case Mousecode::BUTTON_1: @@ -49,9 +80,6 @@ std::string input_util::to_string(Mousecode code) { return "MMB"; case Mousecode::BUTTON_4: case Mousecode::BUTTON_5: - case Mousecode::BUTTON_6: - case Mousecode::BUTTON_7: - case Mousecode::BUTTON_8: return "XButton " + std::to_string( static_cast(code) - static_cast(Mousecode::BUTTON_3) diff --git a/src/window/input.hpp b/src/window/input.hpp index c7ffa791b..a3b21f6ba 100644 --- a/src/window/input.hpp +++ b/src/window/input.hpp @@ -1,123 +1,118 @@ #pragma once #include -#include #include +#include #include "util/HandlersList.hpp" + namespace dv { class value; } -enum class BindType { - BIND = 0, - REBIND = 1 -}; +enum class BindType { BIND = 0, REBIND = 1 }; /// @brief Represents sdl scancode values. enum class Keycode : std::int32_t { - SPACE = 32, - APOSTROPHE = 39, - COMMA = 44, - MINUS = 45, - PERIOD = 46, - SLASH = 47, - NUM_0 = 48, - NUM_1 = 49, - NUM_2 = 50, - NUM_3 = 51, - NUM_4 = 52, - NUM_5 = 53, - NUM_6 = 54, - NUM_7 = 55, - NUM_8 = 56, - NUM_9 = 57, - SEMICOLON = 59, - EQUAL = 61, - A = 65, - B = 66, - C = 67, - D = 68, - E = 69, - F = 70, - G = 71, - H = 72, - I = 73, - J = 74, - K = 75, - L = 76, - M = 77, - N = 78, - O = 79, - P = 80, - Q = 81, - R = 82, - S = 83, - T = 84, - U = 85, - V = 86, - W = 87, - X = 88, - Y = 89, - Z = 90, - LEFT_BRACKET = 91, - BACKSLASH = 92, - RIGHT_BRACKET = 93, - GRAVE_ACCENT = 96, - ESCAPE = 256, - ENTER = 257, - TAB = 258, - BACKSPACE = 259, - INSERT = 260, - DELETE = 261, - LEFT = 263, - RIGHT = 262, - DOWN = 264, - UP = 265, - PAGE_UP = 266, - PAGE_DOWN = 267, - HOME = 268, - END = 269, - CAPS_LOCK = 280, - NUM_LOCK = 282, - PRINT_SCREEN = 283, - PAUSE = 284, - F1 = 290, - F2 = 291, - F3 = 292, - F4 = 293, - F5 = 294, - F6 = 295, - F7 = 296, - F8 = 297, - F9 = 298, - F10 = 299, - F11 = 300, - F12 = 301, - LEFT_SHIFT = 340, - LEFT_CONTROL = 341, - LEFT_ALT = 342, - LEFT_SUPER = 343, - RIGHT_SHIFT = 344, - RIGHT_CONTROL = 345, - RIGHT_ALT = 346, - RIGHT_SUPER = 347, - MENU = 348, - UNKNOWN = -1 + SPACE = 0x00000020u, + APOSTROPHE = 0x00000027u, + COMMA = 0x0000002cu, + MINUS = 0x0000002du, + PERIOD = 0x0000002eu, + SLASH = 0x0000002fu, + NUM_0 = 0x40000059u, + NUM_1, + NUM_2, + NUM_3, + NUM_4, + NUM_5, + NUM_6, + NUM_7, + NUM_8, + NUM_9, + SEMICOLON = 0x0000003bu, + EQUAL = 0x0000003du, + A = 0x00000061u, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + LEFT_BRACKET = 0x0000005bu, + BACKSLASH = 0x0000005cu, + RIGHT_BRACKET = 0x0000005du, + GRAVE_ACCENT = 0x00000060u, + ESCAPE = 0x0000001bu, + ENTER = 0x0000000du, + TAB = 0x00000009u, + BACKSPACE = 0x00000008u, + INSERT = 0x40000049u, + DELETE = 0x0000007fu, + LEFT = 0x40000050u, + RIGHT = 0x4000004fu, + DOWN = 0x40000051u, + UP = 0x40000052u, + PAGE_UP = 0x4000004bu, + PAGE_DOWN = 0x4000004eu, + HOME = 0x4000004au, + END = 0x4000004du, + CAPS_LOCK = 0x40000039u, + NUM_LOCK = 0x40000053u, + PRINT_SCREEN = 0x40000046u, + PAUSE = 0x40000048u, + F1 = 0x4000003au, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + LEFT_SHIFT = 0x400000e1u, + LEFT_CONTROL = 0x400000e0u, + LEFT_ALT = 0x400000e2u, + // LEFT_SUPER = 343, + RIGHT_SHIFT = 0x400000e5u, + RIGHT_CONTROL = 0x400000e4u, + RIGHT_ALT = 0x400000e6u, + // RIGHT_SUPER = 347, + MENU = 0x40000076u, + UNKNOWN = 0x00000000u }; -/// @brief Represents glfw3 mouse button IDs. -/// @details There is a subset of glfw3 mouse button IDs. +/// @brief Represents sdl mouse button IDs. +/// @details There is a subset of sdl mouse button IDs. enum class Mousecode : int { BUTTON_1 = 0, // Left mouse button BUTTON_2 = 1, // Right mouse button BUTTON_3 = 2, // Middle mouse button BUTTON_4 = 3, // Side mouse button 1 BUTTON_5 = 4, // Side mouse button 2 - BUTTON_6 = 5, // Side mouse button 3 - BUTTON_7 = 6, // Side mouse button 4 - BUTTON_8 = 7, // Side mouse button 5 UNKNOWN = -1, }; @@ -127,14 +122,10 @@ inline Mousecode mousecodes_all[] { Mousecode::BUTTON_3, Mousecode::BUTTON_4, Mousecode::BUTTON_5, - Mousecode::BUTTON_6, - Mousecode::BUTTON_7, - Mousecode::BUTTON_8 }; namespace input_util { void initialize(); - Keycode keycode_from(const std::string& name); Mousecode mousecode_from(const std::string& name); @@ -285,7 +276,9 @@ public: virtual const Bindings& getBindings() const = 0; - virtual ObserverHandler addKeyCallback(Keycode key, KeyCallback callback) = 0; + virtual ObserverHandler addKeyCallback( + Keycode key, KeyCallback callback + ) = 0; virtual const std::vector& getPressedKeys() const = 0; virtual const std::vector& getCodepoints() const = 0;