[nostalgia/core] Get building with GLFW (it has a better Conan package than SDL)

This commit is contained in:
2021-04-28 22:27:33 -05:00
parent a17bc04ee7
commit 307684348e
10 changed files with 220 additions and 13 deletions

View File

@@ -0,0 +1,21 @@
add_library(
NostalgiaCore-GLFW
core.cpp
gfx.cpp
)
find_package(glfw3 REQUIRED)
target_link_libraries(
NostalgiaCore-GLFW PUBLIC
glfw::glfw
NostalgiaCore-Userspace
)
install(
TARGETS
NostalgiaCore-GLFW
DESTINATION
LIBRARY DESTINATION lib/nostalgia
ARCHIVE DESTINATION lib/nostalgia
)

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2016 - 2021 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <GLFW/glfw3.h>
#include <nostalgia/core/config.hpp>
#include <nostalgia/core/core.hpp>
#include <nostalgia/core/gfx.hpp>
#include <nostalgia/core/input.hpp>
#include "core.hpp"
namespace nostalgia::core {
static event_handler g_eventHandler = nullptr;
static uint64_t g_wakeupTime;
void draw(Context *ctx);
ox::Error init(Context *ctx) noexcept {
const auto id = new GlfwImplData;
ctx->setWindowerData(id);
using namespace std::chrono;
id->startTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
glfwInit();
oxReturnError(initGfx(ctx));
return OxError(0);
}
static void handleGlfwKeyEvent(GLFWwindow *window, int key, int, int action, int) {
const auto ctx = ox::bit_cast<Context*>(glfwGetWindowUserPointer(window));
const auto id = ctx->windowerData<GlfwImplData>();
switch (action) {
case GLFW_PRESS:
switch (key) {
case GLFW_KEY_Q:
id->running = false;
break;
}
break;
}
}
ox::Error run(Context *ctx) noexcept {
const auto id = ctx->windowerData<GlfwImplData>();
id->running = true;
// try adaptive vsync
//if (SDL_GL_SetSwapInterval(config::SdlVsyncOption) < 0) {
// oxTrace("nostalgia::core::sdl", "Could not enable adaptive vsync, falling back on vsync");
// SDL_GL_SetSwapInterval(1); // fallback on normal vsync
//}
glfwSetKeyCallback(id->window, handleGlfwKeyEvent);
while (id->running && !glfwWindowShouldClose(id->window)) {
glfwPollEvents();
const auto ticks = ticksMs(ctx);
if (g_wakeupTime <= ticks && g_eventHandler) {
auto sleepTime = g_eventHandler(ctx);
if (sleepTime >= 0) {
g_wakeupTime = ticks + static_cast<unsigned>(sleepTime);
} else {
g_wakeupTime = ~uint64_t(0);
}
}
draw(ctx);
glfwSwapBuffers(id->window);
}
return OxError(0);
}
void setEventHandler(Context *ctx, event_handler h) noexcept {
const auto id = ctx->windowerData<GlfwImplData>();
id->eventHandler = h;
}
uint64_t ticksMs(Context *ctx) noexcept {
using namespace std::chrono;
const auto id = ctx->windowerData<GlfwImplData>();
const auto now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
return static_cast<uint64_t>(now - id->startTime);
}
bool buttonDown(Key) noexcept {
return false;
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2016 - 2021 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <nostalgia/core/core.hpp>
namespace nostalgia::core {
struct GlfwImplData {
class GLFWwindow *window = nullptr;
int64_t startTime = 0;
bool running = false;
event_handler eventHandler = nullptr;
};
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2016 - 2021 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <array>
#include <GLFW/glfw3.h>
#include <ox/claw/read.hpp>
#include <nostalgia/core/gfx.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) {
oxErrf("GLFW error ({}): {}", err, desc);
}
ox::Error initGfx(Context *ctx) noexcept {
auto id = ctx->windowerData<GlfwImplData>();
glfwSetErrorCallback(handleGlfwError);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
id->window = glfwCreateWindow(240 * Scale, 160 * Scale, "nostalgia", nullptr, nullptr);
if (id->window == nullptr) {
return OxError(1, "Could not open GLFW window");
}
glfwSetWindowUserPointer(id->window, ctx);
glfwMakeContextCurrent(id->window);
oxReturnError(renderer::init(ctx));
return OxError(0);
}
ox::Error shutdownGfx(Context *ctx) noexcept {
oxReturnError(renderer::shutdown(ctx));
auto id = ctx->windowerData<GlfwImplData>();
glfwDestroyWindow(id->window);
ctx->setWindowerData(nullptr);
delete id;
return OxError(0);
}
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;
}
common::Size getScreenSize(Context *ctx) noexcept {
auto id = ctx->windowerData<GlfwImplData>();
int w = 0, h = 0;
glfwGetFramebufferSize(id->window, &w, &h);
return {w, h};
}
}