From f62bd09fb21e62a073ec68707a3ffbd0d7c48c08 Mon Sep 17 00:00:00 2001 From: Stepanov Igor Date: Sat, 4 Oct 2025 21:08:03 +0300 Subject: [PATCH] Unimpl gl --- src/CMakeLists.txt | 4 +- src/engine/Engine.cpp | 2 +- src/engine/Mainloop.cpp | 2 +- src/frontend/hud.cpp | 2 +- src/frontend/screens/LevelScreen.cpp | 2 +- src/frontend/screens/MenuScreen.cpp | 2 +- src/graphics/core/DrawContext.cpp | 2 +- src/graphics/render/BlocksPreview.cpp | 2 +- src/graphics/render/Skybox.cpp | 2 +- src/graphics/render/WorldRenderer.cpp | 2 +- src/graphics/ui/GUI.cpp | 4 +- src/graphics/ui/elements/ModelViewer.cpp | 2 +- src/graphics/ui/elements/TextBox.cpp | 2 +- src/logic/PlayerController.cpp | 2 +- src/window/detail/SDLWindow.cpp | 716 ----------------------- src/window/detail/input_sdl.cpp | 125 ++++ src/window/detail/input_sdl.hpp | 39 ++ src/window/detail/window_sdl.cpp | 290 +++++++++ src/window/detail/window_sdl.hpp | 51 ++ src/window/input.cpp | 201 +------ src/window/input.hpp | 10 +- src/window/{Window.hpp => window.hpp} | 15 +- 22 files changed, 547 insertions(+), 932 deletions(-) delete mode 100644 src/window/detail/SDLWindow.cpp create mode 100644 src/window/detail/input_sdl.cpp create mode 100644 src/window/detail/input_sdl.hpp create mode 100644 src/window/detail/window_sdl.cpp create mode 100644 src/window/detail/window_sdl.hpp rename src/window/{Window.hpp => window.hpp} (78%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 77c1f0195..38d00b63c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ project(VoxelEngineSrc) -file(GLOB_RECURSE headers ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) -file(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB_RECURSE headers CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +file(GLOB_RECURSE sources CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) list(REMOVE_ITEM sources ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) add_library(VoxelEngineSrc STATIC ${sources} ${headers}) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 6596733f0..a3eec44da 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -34,7 +34,7 @@ #include "util/platform.hpp" #include "window/Camera.hpp" #include "window/input.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "world/Level.hpp" #include "Mainloop.hpp" #include "ServerMainloop.hpp" diff --git a/src/engine/Mainloop.cpp b/src/engine/Mainloop.cpp index ecfd17bca..547fc79cb 100644 --- a/src/engine/Mainloop.cpp +++ b/src/engine/Mainloop.cpp @@ -4,7 +4,7 @@ #include "debug/Logger.hpp" #include "frontend/screens/MenuScreen.hpp" #include "frontend/screens/LevelScreen.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "world/Level.hpp" static debug::Logger logger("mainloop"); diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 08dfcf401..e853b6da5 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -41,7 +41,7 @@ #include "voxels/GlobalChunks.hpp" #include "window/Camera.hpp" #include "window/input.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "world/Level.hpp" #include "world/World.hpp" #include "debug/Logger.hpp" diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index ca80ed11e..6bbbd6676 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -29,7 +29,7 @@ #include "util/stringutil.hpp" #include "voxels/Chunks.hpp" #include "window/Camera.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "world/Level.hpp" #include "world/World.hpp" diff --git a/src/frontend/screens/MenuScreen.cpp b/src/frontend/screens/MenuScreen.cpp index be114ed3c..6420966ac 100644 --- a/src/frontend/screens/MenuScreen.cpp +++ b/src/frontend/screens/MenuScreen.cpp @@ -8,7 +8,7 @@ #include "graphics/core/Texture.hpp" #include "assets/Assets.hpp" #include "maths/UVRegion.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "window/Camera.hpp" #include "engine/Engine.hpp" diff --git a/src/graphics/core/DrawContext.cpp b/src/graphics/core/DrawContext.cpp index fc37fd46d..67814de02 100644 --- a/src/graphics/core/DrawContext.cpp +++ b/src/graphics/core/DrawContext.cpp @@ -6,7 +6,7 @@ #include "Batch2D.hpp" #include "Framebuffer.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" static void set_blend_mode(BlendMode mode) { switch (mode) { diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index 9a1bf97dd..971748436 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -6,7 +6,7 @@ #include "frontend/ContentGfxCache.hpp" #include "voxels/Block.hpp" #include "window/Camera.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "graphics/core/Atlas.hpp" #include "graphics/core/Batch3D.hpp" #include "graphics/core/Framebuffer.hpp" diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index eb90feef8..64bbf71db 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -7,7 +7,7 @@ #include "graphics/core/Cubemap.hpp" #include "graphics/core/Framebuffer.hpp" #include "graphics/core/DrawContext.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "window/Camera.hpp" #include "maths/UVRegion.hpp" diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index e8511fa5a..a3cfb1985 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -27,7 +27,7 @@ #include "voxels/Block.hpp" #include "voxels/Chunk.hpp" #include "voxels/Chunks.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "world/Level.hpp" #include "world/LevelEvents.hpp" #include "world/World.hpp" diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 0cea8a663..828c0a8c8 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -20,7 +20,7 @@ #include "graphics/core/Shader.hpp" #include "gui_util.hpp" #include "window/Camera.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "window/input.hpp" #include @@ -166,7 +166,7 @@ void GUI::actMouse(float delta, const CursorState& cursor) { } if (hover) { - for (Mousecode code : MOUSECODES_ALL) { + for (Mousecode code : mousecodes_all) { if (input.jclicked(code)) { hover->clicked(code); } diff --git a/src/graphics/ui/elements/ModelViewer.cpp b/src/graphics/ui/elements/ModelViewer.cpp index acc8170c1..4dd514ab9 100644 --- a/src/graphics/ui/elements/ModelViewer.cpp +++ b/src/graphics/ui/elements/ModelViewer.cpp @@ -10,7 +10,7 @@ #include "graphics/core/Shader.hpp" #include "graphics/core/Framebuffer.hpp" #include "graphics/core/DrawContext.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "../GUI.hpp" // TODO: remove diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 0ed758823..fbd4b3d29 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -16,7 +16,7 @@ #include "graphics/core/Font.hpp" #include "graphics/ui/markdown.hpp" #include "util/stringutil.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "devtools/actions.hpp" #include "../markdown.hpp" diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index df471c36d..f69049d79 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -23,7 +23,7 @@ #include "voxels/Chunks.hpp" #include "voxels/voxel.hpp" #include "window/Camera.hpp" -#include "window/Window.hpp" +#include "window/window.hpp" #include "window/input.hpp" #include "world/Level.hpp" diff --git a/src/window/detail/SDLWindow.cpp b/src/window/detail/SDLWindow.cpp deleted file mode 100644 index f6f4366a7..000000000 --- a/src/window/detail/SDLWindow.cpp +++ /dev/null @@ -1,716 +0,0 @@ -#include "window/Window.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "debug/Logger.hpp" -#include "graphics/core/ImageData.hpp" -#include "graphics/core/Texture.hpp" -#include "settings.hpp" -#include "util/platform.hpp" -#include "window/input.hpp" - -static debug::Logger logger("window"); - -static std::unordered_set supported_gl_extensions; - -static void init_gl_extensions_list() { - GLint numExtensions = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); - - for (GLint i = 0; i < numExtensions; ++i) { - const char *ext = reinterpret_cast(glGetStringi(GL_EXTENSIONS, i)); - if (ext) { - supported_gl_extensions.insert(ext); - } - } -} - -static bool is_gl_extension_supported(const char *extension) { - if (!extension || !*extension) { - return false; - } - return supported_gl_extensions.find(extension) != supported_gl_extensions.end(); -} - -static const char* gl_error_name(int error) { - switch (error) { - case GL_DEBUG_TYPE_ERROR: return "ERROR"; - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "DEPRECATED_BEHAVIOR"; - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "UNDEFINED_BEHAVIOR"; - case GL_DEBUG_TYPE_PORTABILITY: return "PORTABILITY"; - case GL_DEBUG_TYPE_PERFORMANCE: return "PERFORMANCE"; - case GL_DEBUG_TYPE_OTHER: return "OTHER"; - } - return "UNKNOWN"; -} - -static const char* gl_severity_name(int severity) { - switch (severity) { - case GL_DEBUG_SEVERITY_LOW: return "LOW"; - case GL_DEBUG_SEVERITY_MEDIUM: return "MEDIUM"; - case GL_DEBUG_SEVERITY_HIGH: return "HIGH"; - case GL_DEBUG_SEVERITY_NOTIFICATION: return "NOTIFICATION"; - } - return "UNKNOWN"; -} - -static void GLAPIENTRY gl_message_callback( - GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam -) { - if (severity == GL_DEBUG_SEVERITY_NOTIFICATION) { - return; - } - if (!ENGINE_DEBUG_BUILD && severity != GL_DEBUG_SEVERITY_HIGH) { - return; - } - logger.warning() << "GL:" << gl_error_name(type) << ":" - << gl_severity_name(severity) << ": " << message; -} - -static bool initialize_gl(int width, int height) { - glewExperimental = GL_TRUE; - - GLenum glewErr = glewInit(); - if (glewErr != GLEW_OK) { - if (glewErr == GLEW_ERROR_NO_GLX_DISPLAY) { - // see issue #240 - logger.warning() - << "glewInit() returned GLEW_ERROR_NO_GLX_DISPLAY; ignored"; - } else { - logger.error() << "failed to initialize GLEW:\n" - << glewGetErrorString(glewErr); - return true; - } - } - -#ifndef __APPLE__ - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(gl_message_callback, 0); -#endif - - glViewport(0, 0, width, height); - glClearColor(0.0f, 0.0f, 0.0f, 1); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - GLint maxTextureSize[1] {static_cast(Texture::MAX_RESOLUTION)}; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxTextureSize); - if (maxTextureSize[0] > 0) { - Texture::MAX_RESOLUTION = maxTextureSize[0]; - logger.info() << "max texture size is " << Texture::MAX_RESOLUTION; - } - - const GLubyte* vendor = glGetString(GL_VENDOR); - const GLubyte* renderer = glGetString(GL_RENDERER); - logger.info() << "GL Vendor: " << reinterpret_cast(vendor); - logger.info() << "GL Renderer: " << reinterpret_cast(renderer); - logger.info() << "SDL: " << SDL_GetVersion(); - return false; -} - - -inline constexpr short KEYS_BUFFER_SIZE = 1036; -inline constexpr short MOUSE_KEYS_OFFSET = 1024; - -class SDLInput : public Input { -public: - int scroll = 0; - uint currentFrame = 0; - uint frames[KEYS_BUFFER_SIZE] {}; - std::vector codepoints; - std::vector pressedKeys; - Bindings bindings; - bool keys[KEYS_BUFFER_SIZE] {}; - std::unordered_map> keyCallbacks; - - SDLInput(SDL_Window* window) - : window(window) { - } - - void pollEvents() override { - delta.x = 0.0f; - delta.y = 0.0f; - scroll = 0; - codepoints.clear(); - pressedKeys.clear(); - - SDL_Event event; - - while(SDL_PollEvent(&event)) - { - switch (event.type) { - case SDL_EVENT_QUIT: - // window->setShouldClose(true); - break; - case SDL_EVENT_KEY_DOWN: - break; - case SDL_EVENT_KEY_UP: - break; - case SDL_EVENT_MOUSE_BUTTON_DOWN: - break; - case SDL_EVENT_MOUSE_MOTION: - break; - } - // 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; - // } - - // if (newstate) { - // if (!binding.state) { - // binding.state = true; - // binding.justChanged = true; - // binding.onactived.notify(); - // } - // } else { - // if (binding.state) { - // binding.state = false; - // binding.justChanged = true; - // } - // } - } - } - - void onKeyCallback(int key, bool pressed) { - bool prevPressed = keys[key]; - keys[key] = pressed; - frames[key] = currentFrame; - if (pressed && !prevPressed) { - const auto& callbacks = keyCallbacks.find(static_cast(key)); - if (callbacks != keyCallbacks.end()) { - callbacks->second.notify(); - } - } - if (pressed && key < MOUSE_KEYS_OFFSET) { - pressedKeys.push_back(static_cast(key)); - } - } - - void onMouseCallback(int button, bool pressed) { - int key = button + MOUSE_KEYS_OFFSET; - onKeyCallback(key, pressed); - } - - const char* getClipboardText() const override { - /*todo free*/ - return SDL_GetClipboardText(); - } - - void setClipboardText(const char* text) override { - SDL_SetClipboardText(text); - } - - int getScroll() override { - return scroll; - } - - bool pressed(Keycode key) const override { - int keycode = static_cast(key); - if (keycode < 0 || keycode >= KEYS_BUFFER_SIZE) { - return false; - } - return keys[keycode]; - } - bool jpressed(Keycode keycode) const override { - return pressed(keycode) && - frames[static_cast(keycode)] == currentFrame; - } - - bool clicked(Mousecode code) const override { - return pressed( - static_cast(MOUSE_KEYS_OFFSET + static_cast(code)) - ); - } - bool jclicked(Mousecode code) const override { - return clicked(code) && - frames[static_cast(code) + MOUSE_KEYS_OFFSET] == - currentFrame; - } - - CursorState getCursor() const override { - return {isCursorLocked(), cursor, delta}; - } - - bool isCursorLocked() const override { - return cursorLocked; - } - - void toggleCursor() override { - cursorDrag = false; - SDL_SetWindowMouseGrab(window, cursorLocked); - cursorLocked = !cursorLocked; - } - - void setCursorPosition(double xpos, double ypos) { - if (cursorDrag) { - delta.x += xpos - cursor.x; - delta.y += ypos - cursor.y; - } else { - cursorDrag = true; - } - cursor.x = xpos; - cursor.y = ypos; - } - - Bindings& getBindings() override { - return bindings; - } - - const Bindings& getBindings() const override { - return bindings; - } - - ObserverHandler addKeyCallback(Keycode key, KeyCallback callback) override { - return keyCallbacks[key].add(std::move(callback)); - } - - const std::vector& getPressedKeys() const override { - return pressedKeys; - } - - const std::vector& getCodepoints() const override { - return codepoints; - } -private: - SDL_Window* window; - bool cursorLocked = false; - bool cursorDrag = false; - glm::vec2 delta; - glm::vec2 cursor; -}; -static_assert(!std::is_abstract()); - -class WindowSdlImpl final : public Window { -public: - SDLInput& input; - - DisplaySettings* settings; - - WindowSdlImpl( - SDLInput& glfwInput, - SDL_Window* window, - SDL_GLContext context, - DisplaySettings* settings, - int width, - int height - ) - : Window({width, height}), - input(glfwInput), - settings(settings), - window(window), - glcontext(context) { - } - - ~WindowSdlImpl() override { - SDL_GL_DestroyContext(glcontext); - } - - double time() override { - return SDL_GetTicks(); - } - - void swapBuffers() override { - SDL_GL_SwapWindow(window); - resetScissor(); - if (framerate > 0) { - auto elapsedTime = time() - prevSwap; - auto frameTime = 1.0 / framerate; - if (elapsedTime < frameTime) { - platform::sleep( - static_cast((frameTime - elapsedTime) * 1000) - ); - } - } - prevSwap = time(); - } - - bool isMaximized() const override { - return (SDL_GetWindowFlags(window) & SDL_WINDOW_MAXIMIZED) != 0; - } - - bool isFocused() const override { - Uint32 flags = SDL_GetWindowFlags(window); - return (flags & SDL_WINDOW_INPUT_FOCUS) != 0 || (flags & SDL_WINDOW_MOUSE_FOCUS) != 0; - } - - bool isIconified() const override { - return (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0; - } - - - bool isShouldClose() const override - { - return toClose; - } - - void setShouldClose(bool flag) override - { - toClose = flag; - } - - void setCursor(CursorShape shape) override { - // if (cursor == shape) { - // return; - // } - // cursor = shape; - // // NULL cursor is valid for GLFW - // glfwSetCursor(window, standard_cursors[static_cast(shape)]); - } - - void toggleFullscreen() override { - fullscreen = !fullscreen; - - if (!SDL_SetWindowFullscreen(window, fullscreen)) { - // SDL_Log("Failed to toggle fullscreen: %s", SDL_GetError()); - } - } - - bool isFullscreen() const override { - return fullscreen; - } - - void setIcon(const ImageData* image) override { - if (image == nullptr) { - SDL_SetWindowIcon(window, nullptr); - return; - } - - // Create SDL_Surface from ImageData - SDL_Surface* iconSurface = SDL_CreateSurface( - image->getWidth(), - image->getHeight(), - SDL_PIXELFORMAT_RGBA32 // Adjust format based on your ImageData - ); - - if (!iconSurface) { - // SDL_Log("Failed to create surface for window icon: %s", SDL_GetError()); - return; - } - - memcpy(iconSurface->pixels, image->getData(), - image->getWidth() * image->getHeight() * 4); - - if (!SDL_SetWindowIcon(window, iconSurface)) { - // SDL_Log("Failed to set window icon: %s", SDL_GetError()); - } - - SDL_DestroySurface(iconSurface); - } - - - void setSize(int width, int height) { - glViewport(0, 0, width, height); - size = {width, height}; - - if (!isFullscreen() && !isMaximized()) { - settings->width.set(width); - settings->height.set(height); - } - } - - void pushScissor(glm::vec4 area) override { - if (scissorStack.empty()) { - glEnable(GL_SCISSOR_TEST); - } - scissorStack.push(scissorArea); - - area.z += glm::ceil(area.x); - area.w += glm::ceil(area.y); - - area.x = glm::max(area.x, scissorArea.x); - area.y = glm::max(area.y, scissorArea.y); - - area.z = glm::min(area.z, scissorArea.z); - area.w = glm::min(area.w, scissorArea.w); - - if (area.z < 0.0f || area.w < 0.0f) { - glScissor(0, 0, 0, 0); - } else { - glScissor( - area.x, - size.y - area.w, - std::max(0, static_cast(glm::ceil(area.z - area.x))), - std::max(0, static_cast(glm::ceil(area.w - area.y))) - ); - } - scissorArea = area; - } - - void resetScissor() override { - scissorArea = glm::vec4(0.0f, 0.0f, size.x, size.y); - scissorStack = std::stack(); - glDisable(GL_SCISSOR_TEST); - } - - void popScissor() override { - if (scissorStack.empty()) { - logger.warning() << "extra Window::popScissor call"; - return; - } - glm::vec4 area = scissorStack.top(); - scissorStack.pop(); - if (area.z < 0.0f || area.w < 0.0f) { - glScissor(0, 0, 0, 0); - } else { - glScissor( - area.x, - size.y - area.w, - std::max(0, static_cast(area.z - area.x)), - std::max(0, static_cast(area.w - area.y)) - ); - } - if (scissorStack.empty()) { - glDisable(GL_SCISSOR_TEST); - } - scissorArea = area; - } - - std::unique_ptr takeScreenshot() override { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - auto data = std::make_unique(size.x * size.y * 3); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, 0, size.x, size.y, GL_RGB, GL_UNSIGNED_BYTE, data.get()); - return std::make_unique( - ImageFormat::rgb888, size.x, size.y, data.release() - ); - } - - void setFramerate(int framerate) override { - if ((framerate != -1) != (this->framerate != -1)) { - SDL_GL_SetSwapInterval(framerate == -1); - } - this->framerate = framerate; - } - -private: - SDL_Window* window; - SDL_GLContext glcontext; - CursorShape cursor = CursorShape::ARROW; - bool fullscreen = false; - bool toClose = false; - int framerate = -1; - std::stack scissorStack; - glm::vec4 scissorArea; - double prevSwap = 0.0; - int posX = 0; - int posY = 0; -}; - -// static void mouse_button_callback(GLFWwindow* window, int button, int action, int) { -// auto handler = static_cast(glfwGetWindowUserPointer(window)); -// handler->input.onMouseCallback(button, action == GLFW_PRESS); -// } - -// static void character_callback(GLFWwindow* window, unsigned int codepoint) { -// auto handler = static_cast(glfwGetWindowUserPointer(window)); -// handler->input.codepoints.push_back(codepoint); -// } - -// static void key_callback( -// GLFWwindow* window, int key, int /*scancode*/, int action, int /*mode*/ -// ) { -// auto handler = static_cast(glfwGetWindowUserPointer(window)); -// auto& input = handler->input; -// if (key == GLFW_KEY_UNKNOWN) { -// return; -// } -// if (action == GLFW_PRESS) { -// input.onKeyCallback(key, true); - -// } else if (action == GLFW_RELEASE) { -// input.onKeyCallback(key, false); -// } else if (action == GLFW_REPEAT) { -// input.onKeyCallback(key, true); -// } -// } - -// static void window_size_callback(GLFWwindow* window, int width, int height) { -// auto handler = static_cast(glfwGetWindowUserPointer(window)); -// if (width && height) { -// handler->setSize(width, height); -// } -// handler->resetScissor(); -// } - -// static void scroll_callback(GLFWwindow* window, double, double yoffset) { -// auto handler = static_cast(glfwGetWindowUserPointer(window)); -// handler->input.scroll += yoffset; -// } - -// static void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) { -// auto handler = static_cast(glfwGetWindowUserPointer(window)); -// handler->input.setCursorPosition(xpos, ypos); -// } - -// static void iconify_callback(GLFWwindow* window, int iconified) { -// auto handler = static_cast(glfwGetWindowUserPointer(window)); -// if (handler->isFullscreen() && iconified == 0) { -// GLFWmonitor* monitor = glfwGetPrimaryMonitor(); -// const GLFWvidmode* mode = glfwGetVideoMode(monitor); -// glfwSetWindowMonitor( -// window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate -// ); -// } -// } - -// static void create_standard_cursors() { -// for (int i = 0; i <= static_cast(CursorShape::LAST); i++) { -// int cursor = GLFW_ARROW_CURSOR + i; -// // GLFW 3.3 does not support some cursors -// if (GLFW_VERSION_MAJOR <= 3 && GLFW_VERSION_MINOR <= 3 && -// cursor > GLFW_VRESIZE_CURSOR) { -// break; -// } -// standard_cursors[i] = glfwCreateStandardCursor(cursor); -// } -// } - -// static void setup_callbacks(GLFWwindow* window) { -// glfwSetKeyCallback(window, key_callback); -// glfwSetMouseButtonCallback(window, mouse_button_callback); -// glfwSetCursorPosCallback(window, cursor_pos_callback); -// glfwSetWindowSizeCallback(window, window_size_callback); -// glfwSetCharCallback(window, character_callback); -// glfwSetScrollCallback(window, scroll_callback); -// glfwSetWindowIconifyCallback(window, iconify_callback); -// } - -std::tuple< - std::unique_ptr, - std::unique_ptr -> Window::initialize(DisplaySettings* settings, std::string title) { - int width = settings->width.get(); - int height = settings->height.get(); - - if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS)) { - logger.error() << "failed to initialize SDL"; - return {nullptr, nullptr}; - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); -// #if GLFW_VERSION_MAJOR >= 3 && GLFW_VERSION_MINOR >= 4 -// // see issue #465 -// // glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GL_FALSE); -// #endif -#ifdef __APPLE__ - // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - // glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_FALSE); -#else - // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE); -#endif - // glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); - // glfwWindowHint(GLFW_SAMPLES, settings->samples.get()); - - auto window = SDL_CreateWindow(title.c_str(), width, height, SDL_WINDOW_OPENGL); - if (window == nullptr) { - logger.error() << "failed to create GLFW window"; - return {nullptr, nullptr}; - } - SDL_GLContext glcontext = SDL_GL_CreateContext(window); - SDL_GL_MakeCurrent(window, glcontext); - - glewExperimental = GL_TRUE; - - GLenum glewErr = glewInit(); - if (glewErr != GLEW_OK) { - if (glewErr == GLEW_ERROR_NO_GLX_DISPLAY) { - // see issue #240 - logger.warning() - << "glewInit() returned GLEW_ERROR_NO_GLX_DISPLAY; ignored"; - } else { - logger.error() << "failed to initialize GLEW:\n" - << glewGetErrorString(glewErr); - SDL_DestroyWindow(window); - return {nullptr, nullptr}; - } - } - - init_gl_extensions_list(); - - #ifndef __APPLE__ - if (is_gl_extension_supported("GL_KHR_debug")) { - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback(gl_message_callback, nullptr); - } - #endif - - glViewport(0, 0, width, height); - glClearColor(0.0f, 0.0f, 0.0f, 1); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - GLint maxTextureSize[1] {static_cast(Texture::MAX_RESOLUTION)}; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxTextureSize); - if (maxTextureSize[0] > 0) { - Texture::MAX_RESOLUTION = maxTextureSize[0]; - logger.info() << "max texture size is " << Texture::MAX_RESOLUTION; - } - // setup_callbacks(window); - - SDL_GL_SetSwapInterval(1); - input_util::initialize(); - // create_standard_cursors(); - - glm::vec2 scale; - // SDL_SetDisplayContentScale(SDL_GetPrimaryDisplay(), &scale.x, &scale.y); - logger.info() << "monitor content scale: " << scale.x << "x" << scale.y; - - if (initialize_gl(width, height)) { - return {nullptr, nullptr}; - } - - auto inputPtr = std::make_unique(window); - auto windowPtr = std::make_unique( - *inputPtr, window, glcontext, settings, width, height - ); - // glfwSetWindowUserPointer(window, windowPtr.get()); - return {std::move(windowPtr), std::move(inputPtr)}; -} - -void display::clear() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -void display::clearDepth() { - glClear(GL_DEPTH_BUFFER_BIT); -} - -void display::setBgColor(glm::vec3 color) { - glClearColor(color.r, color.g, color.b, 1.0f); -} - -void display::setBgColor(glm::vec4 color) { - glClearColor(color.r, color.g, color.b, color.a); -} diff --git a/src/window/detail/input_sdl.cpp b/src/window/detail/input_sdl.cpp new file mode 100644 index 000000000..826ad8df6 --- /dev/null +++ b/src/window/detail/input_sdl.cpp @@ -0,0 +1,125 @@ +#include "window/detail/input_sdl.hpp" + +#include +#include +#include +#include +#include + +#include + +#include "debug/Logger.hpp" + +static debug::Logger logger("input"); + +std::string input_util::to_string(Keycode code) { + return {}; +} + +input_sdl::input_sdl() { +} + +void input_sdl::pollEvents() { + // 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; + + // 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; + // } + // } + // } +} + +const char* input_sdl::getClipboardText() const { + return SDL_GetClipboardText(); +} + +void input_sdl::setClipboardText(const char* text) { + SDL_SetClipboardText(text); +} + +int input_sdl::getScroll() { + return {}; +} + +bool input_sdl::pressed(Keycode key) const { + return {}; +} +bool input_sdl::jpressed(Keycode keycode) const { + return {}; +} + +bool input_sdl::clicked(Mousecode code) const { + return {}; +} +bool input_sdl::jclicked(Mousecode code) const { + return {}; +} + +CursorState input_sdl::getCursor() const { + return {isCursorLocked(), {}, {}}; +} + +bool input_sdl::isCursorLocked() const { + return {}; +} + +void input_sdl::toggleCursor() { + // cursorDrag = false; + // if (cursorLocked) { + // glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + // } else { + // glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + // } + // cursorLocked = !cursorLocked; +} + +Bindings& input_sdl::getBindings() { + return bindings; +} + +const Bindings& input_sdl::getBindings() const { + return bindings; +} + +ObserverHandler input_sdl::addKeyCallback(Keycode key, KeyCallback callback) { + return {}; +} + +const std::vector& input_sdl::getPressedKeys() const { + return pressedKeys; +} + +const std::vector& input_sdl::getCodepoints() const { + return codepoints; +} diff --git a/src/window/detail/input_sdl.hpp b/src/window/detail/input_sdl.hpp new file mode 100644 index 000000000..3d9caa6f0 --- /dev/null +++ b/src/window/detail/input_sdl.hpp @@ -0,0 +1,39 @@ +#include "window/input.hpp" + +struct SDL_Window; + +class input_sdl final : public Input { +public: + input_sdl(); + + void pollEvents() override; + + const char* getClipboardText() const override; + void setClipboardText(const char* str) override; + + int getScroll() override; + + bool pressed(Keycode keycode) const override; + bool jpressed(Keycode keycode) const override; + + bool clicked(Mousecode mousecode) const override; + bool jclicked(Mousecode mousecode) const override; + + CursorState getCursor() const override; + + bool isCursorLocked() const override; + void toggleCursor() override; + + Bindings& getBindings() override; + + const Bindings& getBindings() const override; + + ObserverHandler addKeyCallback(Keycode key, KeyCallback callback) override; + + const std::vector& getPressedKeys() const override; + const std::vector& getCodepoints() const override; +private: + Bindings bindings; + std::vector codepoints; + std::vector pressedKeys; +}; \ No newline at end of file diff --git a/src/window/detail/window_sdl.cpp b/src/window/detail/window_sdl.cpp new file mode 100644 index 000000000..ffa7c8962 --- /dev/null +++ b/src/window/detail/window_sdl.cpp @@ -0,0 +1,290 @@ +#include "window/detail/window_sdl.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "debug/Logger.hpp" +#include "graphics/core/ImageData.hpp" +#include "graphics/core/Texture.hpp" +#include "settings.hpp" +#include "window/detail/input_sdl.hpp" + +static debug::Logger logger("window"); + +static std::unordered_set supported_gl_extensions; +static void init_gl_extensions_list() { + GLint numExtensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + + for (GLint i = 0; i < numExtensions; ++i) { + const char *ext = + reinterpret_cast(glGetStringi(GL_EXTENSIONS, i)); + if (ext) { + supported_gl_extensions.insert(ext); + } + } +} + +static bool is_gl_extension_supported(const char *extension) { + if (!extension || !*extension) { + return false; + } + return supported_gl_extensions.find(extension) != + supported_gl_extensions.end(); +} + +static const char *gl_error_name(int error) { + switch (error) { + case GL_DEBUG_TYPE_ERROR: + return "ERROR"; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + return "DEPRECATED_BEHAVIOR"; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + return "UNDEFINED_BEHAVIOR"; + case GL_DEBUG_TYPE_PORTABILITY: + return "PORTABILITY"; + case GL_DEBUG_TYPE_PERFORMANCE: + return "PERFORMANCE"; + case GL_DEBUG_TYPE_OTHER: + return "OTHER"; + } + return "UNKNOWN"; +} + +static const char *gl_severity_name(int severity) { + switch (severity) { + case GL_DEBUG_SEVERITY_LOW: + return "LOW"; + case GL_DEBUG_SEVERITY_MEDIUM: + return "MEDIUM"; + case GL_DEBUG_SEVERITY_HIGH: + return "HIGH"; + case GL_DEBUG_SEVERITY_NOTIFICATION: + return "NOTIFICATION"; + } + return "UNKNOWN"; +} + +static void GLAPIENTRY gl_message_callback( + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *message, + const void *userParam +) { + if (severity == GL_DEBUG_SEVERITY_NOTIFICATION) { + return; + } + if (!ENGINE_DEBUG_BUILD && severity != GL_DEBUG_SEVERITY_HIGH) { + return; + } + logger.warning() << "GL:" << gl_error_name(type) << ":" + << gl_severity_name(severity) << ": " << message; +} + +static bool initialize_gl(int width, int height) { + glewExperimental = GL_TRUE; + + GLenum glewErr = glewInit(); + if (glewErr != GLEW_OK) { + if (glewErr == GLEW_ERROR_NO_GLX_DISPLAY) { + // see issue #240 + logger.warning() + << "glewInit() returned GLEW_ERROR_NO_GLX_DISPLAY; ignored"; + } else { + logger.error() << "failed to initialize GLEW:\n" + << glewGetErrorString(glewErr); + return true; + } + } + +#ifndef __APPLE__ + glEnable(GL_DEBUG_OUTPUT); + // glDebugMessageCallback(gl_message_callback, 0); +#endif + + glViewport(0, 0, width, height); + glClearColor(0.0f, 0.0f, 0.0f, 1); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + GLint maxTextureSize[1] {static_cast(Texture::MAX_RESOLUTION)}; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxTextureSize); + if (maxTextureSize[0] > 0) { + Texture::MAX_RESOLUTION = maxTextureSize[0]; + logger.info() << "max texture size is " << Texture::MAX_RESOLUTION; + } + + const GLubyte *vendor = glGetString(GL_VENDOR); + const GLubyte *renderer = glGetString(GL_RENDERER); + logger.info() << "GL Vendor: " << reinterpret_cast(vendor); + logger.info() << "GL Renderer: " + << reinterpret_cast(renderer); + logger.info() << "SDL: " << SDL_GetVersion(); + return false; +} + +window_sdl::window_sdl(DisplaySettings *settings, std::string title) noexcept { + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS)) { + logger.error() << "failed to initialize SDL: " << SDL_GetError(); + isSuccessfull = false; + return; + } + + SDL_WindowFlags flags = SDL_WINDOW_OPENGL; + + if (settings->fullscreen.get()) { + flags |= SDL_WINDOW_FULLSCREEN; + } + + window = SDL_CreateWindow( + title.c_str(), settings->width.get(), settings->height.get(), flags + ); + if (!window) { + logger.error() << "failed to create SDL Window: " << SDL_GetError(); + isSuccessfull = false; + return; + } + context = SDL_GL_CreateContext(window); + if (!context) { + logger.error() << "failed to create GL context: " << SDL_GetError(); + isSuccessfull = false; + return; + } +} +window_sdl::~window_sdl() { + SDL_DestroyWindow(window); + if (!SDL_GL_DestroyContext(context)) { + logger.error() << "Cant destroy gl context: " << SDL_GetError(); + } +} + +void window_sdl::swapBuffers() const noexcept { + if (!SDL_GL_SwapWindow(window)) [[unlikely]] { + logger.error() << "Cant swap buffer: " << SDL_GetError(); + } +} +bool window_sdl::isMaximized() const { + return maximized; +} +bool window_sdl::isFocused() const { + return focused; +} +bool window_sdl::isIconified() const { + return iconified; +} + +bool window_sdl::isShouldClose() const { + return toClose; +} +void window_sdl::setShouldClose(bool flag) { + toClose = flag; +} + +void window_sdl::setCursor(CursorShape shape) { +} +void window_sdl::toggleFullscreen() { + fullscreen = !fullscreen; + if (SDL_SetWindowFullscreen(window, fullscreen)) { + logger.error() << "Cant toggle fullscreen window: " << SDL_GetError(); + } +} +bool window_sdl::isFullscreen() const { + return fullscreen; +} + +void window_sdl::setIcon(const ImageData *image) { + if (image == nullptr) { + logger.error() << "Image is nullptr"; + return; + } + + SDL_Surface *iconSurface = SDL_CreateSurface( + image->getWidth(), image->getHeight(), SDL_PIXELFORMAT_RGBA32 + ); + + if (!iconSurface) { + logger.error() << "Failed to create surface for app icon: " + << SDL_GetError(); + return; + } + + memcpy( + iconSurface->pixels, + image->getData(), + image->getWidth() * image->getHeight() * 4 + ); + + if (!SDL_SetWindowIcon(window, iconSurface)) { + logger.error() << "Failed to set icon: " << SDL_GetError(); + } + + SDL_DestroySurface(iconSurface); +} + +void window_sdl::pushScissor(glm::vec4 area) { +} +void window_sdl::popScissor() { +} +void window_sdl::resetScissor() { +} + +double window_sdl::time() { + return static_cast(SDL_GetTicks()) / 1000; +} + +void window_sdl::setFramerate(int framerate) { + /*todo*/ + if (!SDL_GL_SetSwapInterval(framerate)) { + logger.error() << "Failed to set framerate: " + << SDL_GetError(); +} +} + +// todo: move somewhere +std::unique_ptr window_sdl::takeScreenshot() { + return {}; +} + +[[nodiscard]] bool window_sdl::isValid() const { + return isSuccessfull; +} + +std::tuple, std::unique_ptr> Window::initialize( + DisplaySettings *settings, std::string title +) { + auto window = std::make_unique(settings, title); + if (!window->isValid()) { + return {nullptr, nullptr}; + } + auto input = std::make_unique(); + + return {std::move(window), std::move(input)}; +} + +void display::clear() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void display::clearDepth() { + glClear(GL_DEPTH_BUFFER_BIT); +} + +void display::setBgColor(glm::vec3 color) { + glClearColor(color.r, color.g, color.b, 1.0f); +} + +void display::setBgColor(glm::vec4 color) { + glClearColor(color.r, color.g, color.b, color.a); +} diff --git a/src/window/detail/window_sdl.hpp b/src/window/detail/window_sdl.hpp new file mode 100644 index 000000000..368e2698f --- /dev/null +++ b/src/window/detail/window_sdl.hpp @@ -0,0 +1,51 @@ +#include +#include "window/window.hpp" + +struct SDL_Window; + +class window_sdl final : public Window { +public: + window_sdl(DisplaySettings *settings, std::string title) noexcept; + ~window_sdl(); + window_sdl(const window_sdl &) = delete; + window_sdl(window_sdl &&) = default; + window_sdl &operator=(const window_sdl &) = delete; + window_sdl &operator=(window_sdl &&) = default; + + void swapBuffers() const noexcept override; + bool isMaximized() const override; + bool isFocused() const override; + bool isIconified() const override; + + bool isShouldClose() const override; + void setShouldClose(bool flag) override; + + void setCursor(CursorShape shape) override; + void toggleFullscreen() override; + bool isFullscreen() const override; + + void setIcon(const ImageData *image) override; + + void pushScissor(glm::vec4 area) override; + void popScissor() override; + void resetScissor() override; + + double time() override; + + void setFramerate(int framerate) override; + + // todo: move somewhere + std::unique_ptr takeScreenshot() override; + + [[nodiscard]] bool isValid() const override; +private: + bool isSuccessfull = true; + bool maximized = false; + bool focused = false; + bool iconified = false; + bool toClose = false; + bool fullscreen = false; + + SDL_Window *window; + SDL_GLContext context; +}; \ No newline at end of file diff --git a/src/window/input.cpp b/src/window/input.cpp index f3dbea53c..73bbe6327 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -1,79 +1,17 @@ -#include "input.hpp" - -#include - -#include -#include -#include -#include -#include +#include "window/input.hpp" +#include "coders/toml.hpp" #include "debug/Logger.hpp" -#include "data/dv.hpp" #include "util/stringutil.hpp" -#ifdef _WIN32 -#include -#endif // _WIN32 - -static debug::Logger logger("input"); - -static std::unordered_map keycodes { - {"enter", SDLK_RETURN }, - {"space", SDLK_SPACE }, - {"backspace", SDLK_BACKSPACE }, - {"caps-lock", SDLK_CAPSLOCK }, - {"escape", SDLK_ESCAPE }, - {"delete", SDLK_DELETE }, - {"home", SDLK_HOME }, - {"end", SDLK_END }, - {"tab", SDLK_TAB }, - {"insert", SDLK_INSERT }, - {"page-down", SDLK_PAGEDOWN }, - {"page-up", SDLK_PAGEUP }, - {"left-shift", SDLK_LSHIFT }, - {"right-shift", SDLK_RSHIFT }, - {"left-ctrl", SDLK_LCTRL }, - {"right-ctrl", SDLK_RCTRL}, - {"left-alt", SDLK_LALT }, - {"right-alt", SDLK_RALT }, - {"left-super", 0 /*todo*/ }, - {"right-super", 0 /*todo*/ }, - {"grave-accent", SDLK_GRAVE }, - {"left", SDLK_LEFT }, - {"right", SDLK_RIGHT }, - {"down", SDLK_DOWN }, - {"up", SDLK_UP }, -}; -SDL_Event s; -static std::unordered_map mousecodes { - {"left", SDL_BUTTON_LEFT }, - {"right", SDL_BUTTON_RIGHT }, - {"middle", SDL_BUTTON_MIDDLE }, - {"side1", SDL_BUTTON_MASK(4) /*todo*/}, - {"side2", SDL_BUTTON_MASK(5) /*todo*/}, - {"side3", SDL_BUTTON_MASK(6) /*todo*/}, - {"side4", SDL_BUTTON_MASK(7) /*todo*/}, - {"side5", SDL_BUTTON_MASK(8) /*todo*/}, -}; - -static std::unordered_map keynames {}; -static std::unordered_map buttonsnames{}; +debug::Logger logger("input"); std::string input_util::get_name(Mousecode code) { - const auto found = buttonsnames.find(static_cast(code)); - if (found == buttonsnames.end()) { - return "unknown"; - } - return found->second; + return {}; } std::string input_util::get_name(Keycode code) { - const auto found = keynames.find(static_cast(code)); - if (found == keynames.end()) { - return "unknown"; - } - return found->second; + return {}; } void Binding::reset(InputType type, int code) { @@ -90,125 +28,15 @@ void Binding::reset(Mousecode code) { } void input_util::initialize() { - for (std::uint32_t i = 0; i <= 9; i++) { - keycodes[std::to_string(i)] = SDLK_0 + i; - } - for (std::uint32_t i = 0; i < 25; i++) { - keycodes["f" + std::to_string(i + 1)] = SDLK_F1 + i; - } - for (char i = 'a'; i <= 'z'; i++) { - keycodes[std::string({i})] = SDLK_A - 'a' + i; - } - for (const auto& entry : keycodes) { - keynames[entry.second] = entry.first; - } - for (const auto& entry : mousecodes) { - buttonsnames[entry.second] = entry.first; - } + } Keycode input_util::keycode_from(const std::string& name) { - const auto& found = keycodes.find(name); - if (found == keycodes.end()) { - return Keycode::UNKNOWN; - } - return static_cast(found->second); + return {}; } Mousecode input_util::mousecode_from(const std::string& name) { - const auto& found = mousecodes.find(name); - if (found == mousecodes.end()) { - return Mousecode::UNKNOWN; - } - return static_cast(found->second); -} - -std::string input_util::to_string(Keycode code) { - SDL_Scancode scancode = static_cast(code); - switch (scancode) { - case SDLK_TAB: - return "Tab"; - case SDL_SCANCODE_LCTRL: - return "Left Ctrl"; - case SDL_SCANCODE_RCTRL: - return "Right Ctrl"; - case SDL_SCANCODE_LALT: - return "Left Alt"; - case SDL_SCANCODE_RALT: - return "Right Alt"; - case SDL_SCANCODE_LSHIFT: - return "Left Shift"; - case SDL_SCANCODE_RSHIFT: - return "Right Shift"; - case SDL_SCANCODE_CAPSLOCK: - return "Caps-Lock"; - case SDL_SCANCODE_SPACE: - return "Space"; - case SDL_SCANCODE_ESCAPE: - return "Esc"; - case SDL_SCANCODE_RETURN: - return "Enter"; - case SDL_SCANCODE_UP: - return "Up"; - case SDL_SCANCODE_DOWN: - return "Down"; - case SDL_SCANCODE_LEFT: - return "Left"; - case SDL_SCANCODE_RIGHT: - return "Right"; - case SDL_SCANCODE_BACKSPACE: - return "Backspace"; - case SDL_SCANCODE_F1: - return "F1"; - case SDL_SCANCODE_F2: - return "F2"; - case SDL_SCANCODE_F3: - return "F3"; - case SDL_SCANCODE_F4: - return "F4"; - case SDL_SCANCODE_F5: - return "F5"; - case SDL_SCANCODE_F6: - return "F6"; - case SDL_SCANCODE_F7: - return "F7"; - case SDL_SCANCODE_F8: - return "F8"; - case SDL_SCANCODE_F9: - return "F9"; - case SDL_SCANCODE_F10: - return "F10"; - case SDL_SCANCODE_F11: - return "F11"; - case SDL_SCANCODE_F12: - return "F12"; - case SDL_SCANCODE_DELETE: - return "Delete"; - case SDL_SCANCODE_HOME: - return "Home"; - case SDL_SCANCODE_END: - return "End"; - case SDL_SCANCODE_LGUI: - return "Left Super"; - case SDL_SCANCODE_RGUI: - return "Right Super"; - case SDL_SCANCODE_PAGEUP: - return "Page Up"; - case SDL_SCANCODE_PAGEDOWN: - return "Page Down"; - case SDL_SCANCODE_INSERT: - return "Insert"; - case SDL_SCANCODE_PRINTSCREEN: - return "Print Screen"; - case SDL_SCANCODE_NUMLOCKCLEAR: - return "Num Lock"; - case SDL_SCANCODE_APPLICATION: - return "Menu"; - case SDL_SCANCODE_PAUSE: - return "Pause"; - default: - return "Unknown"; - } + return {}; } std::string input_util::to_string(Mousecode code) { @@ -224,8 +52,10 @@ std::string input_util::to_string(Mousecode code) { 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)); + return "XButton " + std::to_string( + static_cast(code) - + static_cast(Mousecode::BUTTON_3) + ); default: return "unknown button"; } @@ -259,9 +89,8 @@ void Bindings::read(const dv::value& map, BindType bindType) { type = InputType::MOUSE; code = static_cast(input_util::mousecode_from(codename)); } else { - logger.error() - << "unknown input type: " << prefix << " (binding " - << util::quote(key) << ")"; + logger.error() << "unknown input type: " << prefix + << " (binding " << util::quote(key) << ")"; continue; } if (bindType == BindType::BIND) { @@ -273,8 +102,6 @@ void Bindings::read(const dv::value& map, BindType bindType) { } } -#include "coders/toml.hpp" - std::string Bindings::write() const { auto obj = dv::object(); for (auto& entry : bindings) { diff --git a/src/window/input.hpp b/src/window/input.hpp index 2edfe4c78..c7ffa791b 100644 --- a/src/window/input.hpp +++ b/src/window/input.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -14,8 +15,8 @@ enum class BindType { REBIND = 1 }; -/// @brief Represents glfw3 keycode values. -enum class Keycode : int { +/// @brief Represents sdl scancode values. +enum class Keycode : std::int32_t { SPACE = 32, APOSTROPHE = 39, COMMA = 44, @@ -120,7 +121,7 @@ enum class Mousecode : int { UNKNOWN = -1, }; -inline Mousecode MOUSECODES_ALL[] { +inline Mousecode mousecodes_all[] { Mousecode::BUTTON_1, Mousecode::BUTTON_2, Mousecode::BUTTON_3, @@ -128,7 +129,8 @@ inline Mousecode MOUSECODES_ALL[] { Mousecode::BUTTON_5, Mousecode::BUTTON_6, Mousecode::BUTTON_7, - Mousecode::BUTTON_8}; + Mousecode::BUTTON_8 +}; namespace input_util { void initialize(); diff --git a/src/window/Window.hpp b/src/window/window.hpp similarity index 78% rename from src/window/Window.hpp rename to src/window/window.hpp index 8800be8c8..d19ab5087 100644 --- a/src/window/Window.hpp +++ b/src/window/window.hpp @@ -4,7 +4,6 @@ #include #include "graphics/core/commons.hpp" -#include "typedefs.hpp" class ImageData; class Input; @@ -12,10 +11,8 @@ struct DisplaySettings; class Window { public: - Window(glm::ivec2 size) : size(std::move(size)) {} - virtual ~Window() = default; - virtual void swapBuffers() = 0; + virtual void swapBuffers() const noexcept = 0; virtual bool isMaximized() const = 0; virtual bool isFocused() const = 0; @@ -41,14 +38,14 @@ public: // todo: move somewhere virtual std::unique_ptr takeScreenshot() = 0; - const glm::ivec2& getSize() const { + [[nodiscard]] virtual bool isValid() const = 0; + + virtual const glm::ivec2& getSize() const { return size; } - static std::tuple< - std::unique_ptr, - std::unique_ptr - > initialize(DisplaySettings* settings, std::string title); + static std::tuple, std::unique_ptr> + initialize(DisplaySettings* settings, std::string title); protected: glm::ivec2 size; };