162 lines
4.7 KiB
C++
162 lines
4.7 KiB
C++
/*
|
|
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
*/
|
|
|
|
#include <glad/glad.h>
|
|
#include <GLFW/glfw3.h>
|
|
#include <imgui_impl_glfw.h>
|
|
|
|
#include <ox/std/defines.hpp>
|
|
|
|
#include <nostalgia/core/config.hpp>
|
|
#include <nostalgia/core/userland/gfx.hpp>
|
|
|
|
#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<int>(key);
|
|
} else {
|
|
id->keysDown &= ~(1llu << static_cast<int>(key));
|
|
}
|
|
}
|
|
|
|
static void handleKeyPress(Context *ctx, int key, bool down) noexcept {
|
|
static constexpr auto keyMap = [] {
|
|
ox::Array<Key, GLFW_KEY_LAST> map = {};
|
|
for (auto i = 0u; i < 26; ++i) {
|
|
map[GLFW_KEY_A + i] = static_cast<Key>(static_cast<unsigned>(Key::Alpha_A) + i);
|
|
}
|
|
for (auto i = 0u; i < 10; ++i) {
|
|
map[GLFW_KEY_0 + i] = static_cast<Key>(static_cast<unsigned>(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<GlfwImplData>();
|
|
const auto k = keyMap[static_cast<std::size_t>(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<Context*>(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<Context*>(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<GlfwImplData>();
|
|
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 (!gladLoadGLES2Loader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress))) {
|
|
return OxError(2, "Could not init Glad");
|
|
}
|
|
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<GlfwImplData>();
|
|
glfwSetWindowTitle(id->window, title);
|
|
}
|
|
|
|
void focusWindow(Context *ctx) noexcept {
|
|
const auto id = ctx->windowerData<GlfwImplData>();
|
|
glfwFocusWindow(id->window);
|
|
}
|
|
|
|
int getScreenWidth(Context *ctx) noexcept {
|
|
auto id = ctx->windowerData<GlfwImplData>();
|
|
int w = 0, h = 0;
|
|
glfwGetFramebufferSize(id->window, &w, &h);
|
|
return w;
|
|
}
|
|
|
|
int getScreenHeight(Context *ctx) noexcept {
|
|
auto id = ctx->windowerData<GlfwImplData>();
|
|
int w = 0, h = 0;
|
|
glfwGetFramebufferSize(id->window, &w, &h);
|
|
return h;
|
|
}
|
|
|
|
geo::Size getScreenSize(Context *ctx) noexcept {
|
|
auto id = ctx->windowerData<GlfwImplData>();
|
|
int w = 0, h = 0;
|
|
glfwGetFramebufferSize(id->window, &w, &h);
|
|
return {w, h};
|
|
}
|
|
|
|
}
|