/* * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. */ #include #include #include #include #include #include "core.hpp" namespace nostalgia::core { constexpr auto Scale = 5; static void handleGlfwError(int err, const char *desc) noexcept { oxErrf("GLFW error ({}): {}\n", err, desc); } static auto setKeyDownStatus(GlfwImplData *id, Key key, bool down) noexcept { if (down) { id->keysDown |= 1llu << static_cast(key); } else { id->keysDown &= ~(1llu << static_cast(key)); } } static void handleKeyPress(Context *ctx, int key, bool down) noexcept { static constexpr auto keyMap = [] { ox::Array map = {}; for (auto i = 0u; i < 26; ++i) { map[GLFW_KEY_A + i] = static_cast(static_cast(Key::Alpha_A) + i); } for (auto i = 0u; i < 10; ++i) { map[GLFW_KEY_0 + i] = static_cast(static_cast(Key::Num_0) + i); } map[GLFW_KEY_LEFT_ALT] = Key::Mod_Alt; map[GLFW_KEY_RIGHT_ALT] = Key::Mod_Alt; map[GLFW_KEY_LEFT_CONTROL] = Key::Mod_Ctrl; map[GLFW_KEY_RIGHT_CONTROL] = Key::Mod_Ctrl; map[GLFW_KEY_LEFT_SUPER] = Key::Mod_Super; map[GLFW_KEY_RIGHT_SUPER] = Key::Mod_Super; return map; }(); const auto eventHandler = keyEventHandler(ctx); const auto id = ctx->windowerData(); const auto k = keyMap[static_cast(key)]; setKeyDownStatus(id, k, down); if (eventHandler) { eventHandler(ctx, k, down); } //if constexpr(ox::defines::Debug) { // switch (key) { // case GLFW_KEY_ESCAPE: // case GLFW_KEY_Q: // oxIgnoreError(shutdown(ctx)); // break; // default: // break; // } //} } static void handleGlfwCursorPosEvent(GLFWwindow*, double, double) noexcept { } static void handleGlfwMouseButtonEvent(GLFWwindow *window, int, int, int) noexcept { const auto ctx = static_cast(glfwGetWindowUserPointer(window)); ctx->uninterruptedRefreshes = 10; } static void handleGlfwWindowResize(GLFWwindow*, int, int) noexcept { } static void handleGlfwKeyEvent(GLFWwindow *window, int key, int, int action, int) noexcept { const auto ctx = static_cast(glfwGetWindowUserPointer(window)); ctx->uninterruptedRefreshes = 2; if (action == GLFW_PRESS) { handleKeyPress(ctx, key, true); } else if (action == GLFW_RELEASE) { handleKeyPress(ctx, key, false); } } void ImGui_Impl_NewFrame() noexcept { ImGui_ImplGlfw_NewFrame(); } ox::Error initGfx(Context *ctx) noexcept { auto id = ctx->windowerData(); glfwSetErrorCallback(handleGlfwError); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if constexpr(ox::defines::OS == ox::OS::Darwin) { glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); } glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); id->window = glfwCreateWindow(240 * Scale, 160 * Scale, "nostalgia", nullptr, nullptr); if (id->window == nullptr) { return OxError(1, "Could not open GLFW window"); } glfwSetCursorPosCallback(id->window, handleGlfwCursorPosEvent); glfwSetMouseButtonCallback(id->window, handleGlfwMouseButtonEvent); glfwSetWindowSizeCallback(id->window, handleGlfwWindowResize); glfwSetKeyCallback(id->window, handleGlfwKeyEvent); glfwSetWindowUserPointer(id->window, ctx); glfwMakeContextCurrent(id->window); if constexpr(config::ImGuiEnabled) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); auto &io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; //io.MouseDrawCursor = true; ImGui_ImplGlfw_InitForOpenGL(id->window, true); } void *rendererData = nullptr; oxReturnError(renderer::init(ctx, &rendererData)); ctx->setRendererData(rendererData); return OxError(0); } void setWindowTitle(Context *ctx, const char *title) noexcept { const auto id = ctx->windowerData(); glfwSetWindowTitle(id->window, title); } void focusWindow(Context *ctx) noexcept { const auto id = ctx->windowerData(); glfwFocusWindow(id->window); } int getScreenWidth(Context *ctx) noexcept { auto id = ctx->windowerData(); int w = 0, h = 0; glfwGetFramebufferSize(id->window, &w, &h); return w; } int getScreenHeight(Context *ctx) noexcept { auto id = ctx->windowerData(); int w = 0, h = 0; glfwGetFramebufferSize(id->window, &w, &h); return h; } geo::Size getScreenSize(Context *ctx) noexcept { auto id = ctx->windowerData(); int w = 0, h = 0; glfwGetFramebufferSize(id->window, &w, &h); return {w, h}; } }