diff --git a/include/Orange/Core/Bitset.h b/include/Orange/Core/Bitset.h index 89cda0a..0c7e538 100644 --- a/include/Orange/Core/Bitset.h +++ b/include/Orange/Core/Bitset.h @@ -73,12 +73,12 @@ namespace orange if constexpr (BitCount % 32u == 0u) { for (size_t i = 0; i < DwordCount; i++) - dwords[i] = std::numeric_limits::max(); + dwords[i] = ~(0u); } else { for (size_t i = 0; i < DwordCount - 1u; i++) - dwords[i] = std::numeric_limits::max(); + dwords[i] = ~(0u); dwords[DwordCount - 1] = (1u << (BitCount % 32u)) - 1u; } diff --git a/include/Orange/Core/Traits.h b/include/Orange/Core/Traits.h index 57fc1fc..5bd9cfc 100644 --- a/include/Orange/Core/Traits.h +++ b/include/Orange/Core/Traits.h @@ -5,9 +5,13 @@ // Needed for placement new/delete. #include #include +#include namespace orange { + template + using Function = std::function; + struct FalseType { static constexpr bool Value = false; }; struct TrueType { static constexpr bool Value = true; }; diff --git a/include/Orange/Math/Vector.h b/include/Orange/Math/Vector.h index 63a1ee6..663cfbc 100644 --- a/include/Orange/Math/Vector.h +++ b/include/Orange/Math/Vector.h @@ -138,17 +138,17 @@ namespace orange constexpr Vec& operator+=(const Vec& other) { - return TransformInPlace(Math::Add); + return TransformInPlace(other, Math::Add); } constexpr Vec& operator-=(const Vec& other) { - return TransformInPlace(Math::Subtract); + return TransformInPlace(other, Math::Subtract); } constexpr Vec& operator*=(const Vec& other) { - return TransformInPlace(Math::Multiply); + return TransformInPlace(other, Math::Multiply); } constexpr Vec& operator*=(const T& scalar) @@ -158,7 +158,7 @@ namespace orange constexpr Vec& operator/=(const Vec& other) { - return TransformInPlace(Math::Divide); + return TransformInPlace(other, Math::Divide); } constexpr Vec& operator/=(const T& scalar) @@ -168,7 +168,7 @@ namespace orange constexpr Vec& operator%=(const Vec& other) { - return TransformInPlace(Math::Modulo); + return TransformInPlace(other, Math::Modulo); } constexpr Vec& operator%=(const T& scalar) diff --git a/include/Orange/Render/Input.h b/include/Orange/Render/Input.h new file mode 100644 index 0000000..3690e43 --- /dev/null +++ b/include/Orange/Render/Input.h @@ -0,0 +1,166 @@ +#pragma once + +#include + +namespace orange::Input +{ + namespace ButtonCodes + { + enum ButtonCode + { + Invalid = -1, + None = 0, + + Key_0, + Key_1, + Key_2, + Key_3, + Key_4, + Key_5, + Key_6, + Key_7, + Key_8, + Key_9, + Key_A, + Key_B, + Key_C, + Key_D, + Key_E, + Key_F, + Key_G, + Key_H, + Key_I, + Key_J, + Key_K, + Key_L, + Key_M, + Key_N, + Key_O, + Key_P, + Key_Q, + Key_R, + Key_S, + Key_T, + Key_U, + Key_V, + Key_W, + Key_X, + Key_Y, + Key_Z, + Key_Numpad_0, + Key_Numpad_1, + Key_Numpad_2, + Key_Numpad_3, + Key_Numpad_4, + Key_Numpad_5, + Key_Numpad_6, + Key_Numpad_7, + Key_Numpad_8, + Key_Numpad_9, + Key_Numpad_Divide, + Key_Numpad_Multiply, + Key_Numpad_Minus, + Key_Numpad_Plus, + Key_Numpad_Enter, + Key_Numpad_Decimal, + Key_LBracket, + Key_RBracket, + Key_Semicolon, + Key_Apostrophe, + Key_Backquote, + Key_Comma, + Key_Period, + Key_Slash, + Key_Backslash, + Key_Minus, + Key_Equal, + Key_Enter, + Key_Space, + Key_Backspace, + Key_Tab, + Key_CapsLock, + Key_NumLock, + Key_Escape, + Key_ScrollLock, + Key_Insert, + Key_Delete, + Key_Home, + Key_End, + Key_PageUp, + Key_PageDown, + Key_Break, + Key_LShift, + Key_RShift, + Key_LAlt, + Key_RAlt, + Key_LControl, + Key_RControl, + Key_LSuper, + Key_RSuper, + Key_App, + Key_Up, + Key_Left, + Key_Down, + Key_Right, + Key_F1, + Key_F2, + Key_F3, + Key_F4, + Key_F5, + Key_F6, + Key_F7, + Key_F8, + Key_F9, + Key_F10, + Key_F11, + Key_F12, + Key_CapsLockToggle, + Key_NumLockToggle, + Key_ScrollLockToggle, + + Mouse_1, // Left Click + Mouse_2, // Right Click + Mouse_3, // Middle Click + Mouse_4, + Mouse_5, + Mouse_WheelUp, + Mouse_WheelDown, + + Count, + }; + } + using ButtonCode = ButtonCodes::ButtonCode; + + class InputHandler + { + public: + bool get(ButtonCode code) + { + return m_pressed.get(code); + } + + // Returns true for first window update + // it was pressed on, not if held. + // For like, shooting, etc. + bool getFirst(ButtonCode code) + { + return m_firstPressed.get(code); + } + + void set(ButtonCode code, bool pressed) + { + m_firstPressed.set(code, pressed); + m_pressed.set(code, pressed); + } + + void flushKeys() + { + m_firstPressed.clearAll(); + } + private: + Bitset m_pressed; + Bitset m_firstPressed; + }; + + ButtonCode SDLScancodeToButton(int scancode); +} diff --git a/include/Orange/Render/Window.h b/include/Orange/Render/Window.h index df8ce31..d6cf1da 100644 --- a/include/Orange/Render/Window.h +++ b/include/Orange/Render/Window.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include struct SDL_Window; @@ -26,7 +28,7 @@ namespace orange static Result Create(); - bool Update(); + bool Update(Input::InputHandler& handler); void EnableRelativeMouse(bool relative); diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/CubeTest.cpp index 98faea7..0bc8442 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/CubeTest.cpp @@ -606,10 +606,12 @@ int main(int argc, char** argv) memcpy((uint8_t*)(r_buffer->ptr) + uniformSlice.offset, &uniformData, sizeof(uniformData)); + Input::InputHandler handler; + r_window->EnableRelativeMouse(true); auto t1 = Time::now(); - while (r_window->Update()) + while (r_window->Update(handler)) { const auto t2 = Time::now(); const float dt = Seconds(t2 - t1).count(); @@ -627,11 +629,24 @@ int main(int argc, char** argv) camera.offsetOrientation( -sensitivity * dt * Radian( mouseDelta.x ), sensitivity * dt * Radian( mouseDelta.y )); + UniformData uniformData { .projection = camera.projection(), .view = camera.view(), }; + + const float movementSpeed = handler.get(Input::ButtonCodes::Key_LShift) ? 64.0f : 16.0f; + + if (handler.get(Input::ButtonCodes::Key_W)) + camera.transform.position += camera.forward() * movementSpeed * dt; + else if (handler.get(Input::ButtonCodes::Key_S)) + camera.transform.position += camera.backward() * movementSpeed * dt; + + if (handler.get(Input::ButtonCodes::Key_A)) + camera.transform.position += camera.left() * movementSpeed * dt; + else if (handler.get(Input::ButtonCodes::Key_D)) + camera.transform.position += camera.right() * movementSpeed * dt; // NEED TO SYNCHRONIZE THIS memcpy((uint8_t*)(r_buffer->ptr) + uniformSlice.offset, &uniformData, sizeof(uniformData)); } diff --git a/src/Orange/Render/Input.cpp b/src/Orange/Render/Input.cpp new file mode 100644 index 0000000..84f658e --- /dev/null +++ b/src/Orange/Render/Input.cpp @@ -0,0 +1,72 @@ +#include +#include + +#include + +namespace orange::Input +{ + static constexpr Array s_scancodeToKey = + []() + { + Array scanToKey; + + for (int i = SDL_SCANCODE_A; i <= SDL_SCANCODE_Z; i++) scanToKey[i] = ButtonCode(ButtonCodes::Key_A + (i - SDL_SCANCODE_A)); + for (int i = SDL_SCANCODE_1; i <= SDL_SCANCODE_9; i++) scanToKey[i] = ButtonCode(ButtonCodes::Key_1 + (i - SDL_SCANCODE_1)); + for (int i = SDL_SCANCODE_F1; i <= SDL_SCANCODE_F12; i++) scanToKey[i] = ButtonCode(ButtonCodes::Key_F1 + (i - SDL_SCANCODE_F1)); + for (int i = SDL_SCANCODE_KP_1; i <= SDL_SCANCODE_KP_9; i++) scanToKey[i] = ButtonCode(ButtonCodes::Key_Numpad_1 + (i - SDL_SCANCODE_KP_1)); + + scanToKey[SDL_SCANCODE_0] = ButtonCodes::Key_0; + scanToKey[SDL_SCANCODE_KP_0] = ButtonCodes::Key_Numpad_0; + scanToKey[SDL_SCANCODE_RETURN] = ButtonCodes::Key_Enter; + scanToKey[SDL_SCANCODE_ESCAPE] = ButtonCodes::Key_Escape; + scanToKey[SDL_SCANCODE_BACKSPACE] = ButtonCodes::Key_Backspace; + scanToKey[SDL_SCANCODE_TAB] = ButtonCodes::Key_Tab; + scanToKey[SDL_SCANCODE_SPACE] = ButtonCodes::Key_Space; + scanToKey[SDL_SCANCODE_MINUS] = ButtonCodes::Key_Minus; + scanToKey[SDL_SCANCODE_EQUALS] = ButtonCodes::Key_Equal; + scanToKey[SDL_SCANCODE_LEFTBRACKET] = ButtonCodes::Key_LBracket; + scanToKey[SDL_SCANCODE_RIGHTBRACKET] = ButtonCodes::Key_RBracket; + scanToKey[SDL_SCANCODE_BACKSLASH] = ButtonCodes::Key_Backslash; + scanToKey[SDL_SCANCODE_SEMICOLON] = ButtonCodes::Key_Semicolon; + scanToKey[SDL_SCANCODE_APOSTROPHE] = ButtonCodes::Key_Apostrophe; + scanToKey[SDL_SCANCODE_GRAVE] = ButtonCodes::Key_Backquote; + scanToKey[SDL_SCANCODE_COMMA] = ButtonCodes::Key_Comma; + scanToKey[SDL_SCANCODE_PERIOD] = ButtonCodes::Key_Period; + scanToKey[SDL_SCANCODE_SLASH] = ButtonCodes::Key_Slash; + scanToKey[SDL_SCANCODE_CAPSLOCK] = ButtonCodes::Key_CapsLock; + scanToKey[SDL_SCANCODE_SCROLLLOCK] = ButtonCodes::Key_ScrollLock; + scanToKey[SDL_SCANCODE_INSERT] = ButtonCodes::Key_Insert; + scanToKey[SDL_SCANCODE_HOME] = ButtonCodes::Key_Home; + scanToKey[SDL_SCANCODE_PAGEUP] = ButtonCodes::Key_PageUp; + scanToKey[SDL_SCANCODE_DELETE] = ButtonCodes::Key_Delete; + scanToKey[SDL_SCANCODE_END] = ButtonCodes::Key_End; + scanToKey[SDL_SCANCODE_PAGEDOWN] = ButtonCodes::Key_PageDown; + scanToKey[SDL_SCANCODE_RIGHT] = ButtonCodes::Key_Right; + scanToKey[SDL_SCANCODE_LEFT] = ButtonCodes::Key_Left; + scanToKey[SDL_SCANCODE_DOWN] = ButtonCodes::Key_Down; + scanToKey[SDL_SCANCODE_UP] = ButtonCodes::Key_Up; + scanToKey[SDL_SCANCODE_NUMLOCKCLEAR] = ButtonCodes::Key_NumLock; + scanToKey[SDL_SCANCODE_KP_DIVIDE] = ButtonCodes::Key_Numpad_Divide; + scanToKey[SDL_SCANCODE_KP_MULTIPLY] = ButtonCodes::Key_Numpad_Multiply; + scanToKey[SDL_SCANCODE_KP_MINUS] = ButtonCodes::Key_Numpad_Minus; + scanToKey[SDL_SCANCODE_KP_PLUS] = ButtonCodes::Key_Numpad_Plus; + scanToKey[SDL_SCANCODE_KP_ENTER] = ButtonCodes::Key_Numpad_Enter; + scanToKey[SDL_SCANCODE_KP_PERIOD] = ButtonCodes::Key_Numpad_Decimal; + scanToKey[SDL_SCANCODE_APPLICATION] = ButtonCodes::Key_App; + scanToKey[SDL_SCANCODE_LCTRL] = ButtonCodes::Key_LControl; + scanToKey[SDL_SCANCODE_LSHIFT] = ButtonCodes::Key_LShift; + scanToKey[SDL_SCANCODE_LALT] = ButtonCodes::Key_LAlt; + scanToKey[SDL_SCANCODE_LGUI] = ButtonCodes::Key_LSuper; + scanToKey[SDL_SCANCODE_RCTRL] = ButtonCodes::Key_RControl; + scanToKey[SDL_SCANCODE_RSHIFT] = ButtonCodes::Key_RShift; + scanToKey[SDL_SCANCODE_RALT] = ButtonCodes::Key_RAlt; + scanToKey[SDL_SCANCODE_RGUI] = ButtonCodes::Key_RSuper; + + return scanToKey; + }(); + + ButtonCode SDLScancodeToButton(int scancode) + { + return s_scancodeToKey[scancode]; + } +} diff --git a/src/Orange/Render/Window.cpp b/src/Orange/Render/Window.cpp index f84d468..b0e995b 100644 --- a/src/Orange/Render/Window.cpp +++ b/src/Orange/Render/Window.cpp @@ -58,8 +58,10 @@ namespace orange return SDL_GetError(); } - bool Window::Update() + bool Window::Update(Input::InputHandler& handler) { + handler.flushKeys(); + bool quit = false; SDL_Event e; @@ -76,6 +78,7 @@ namespace orange break; case SDL_KEYDOWN: case SDL_KEYUP: + handler.set(Input::SDLScancodeToButton(e.key.keysym.scancode), e.type == SDL_KEYDOWN); break; case SDL_WINDOWEVENT: switch (e.window.event) diff --git a/src/Orange/meson.build b/src/Orange/meson.build index e1d92f7..369d8a5 100644 --- a/src/Orange/meson.build +++ b/src/Orange/meson.build @@ -8,6 +8,7 @@ orange_src = files([ 'Core/Filesystem.cpp', 'Core/Log.cpp', + 'Render/Input.cpp', 'Render/RenderContext_Init.cpp', 'Render/RenderContext_Util.cpp', 'Render/Swapchain.cpp',