From 307684348e722efee5f3648bf72f565e620fef47 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 28 Apr 2021 22:27:33 -0500 Subject: [PATCH] [nostalgia/core] Get building with GLFW (it has a better Conan package than SDL) --- conanfile.py | 11 ++-- src/nostalgia/core/CMakeLists.txt | 2 +- src/nostalgia/core/core.hpp | 4 +- src/nostalgia/core/gba/core.cpp | 4 +- src/nostalgia/core/glfw/CMakeLists.txt | 21 ++++++ src/nostalgia/core/glfw/core.cpp | 91 ++++++++++++++++++++++++++ src/nostalgia/core/glfw/core.hpp | 22 +++++++ src/nostalgia/core/glfw/gfx.cpp | 74 +++++++++++++++++++++ src/nostalgia/player/CMakeLists.txt | 2 +- src/nostalgia/player/app.cpp | 2 +- 10 files changed, 220 insertions(+), 13 deletions(-) create mode 100644 src/nostalgia/core/glfw/CMakeLists.txt create mode 100644 src/nostalgia/core/glfw/core.cpp create mode 100644 src/nostalgia/core/glfw/core.hpp create mode 100644 src/nostalgia/core/glfw/gfx.cpp diff --git a/conanfile.py b/conanfile.py index 96ac238c..c5e3caef 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,9 +1,8 @@ from conans import ConanFile, CMake class NostalgiaConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - requires = "jsoncpp/1.9.4", "sdl2/2.0.14@bincrafters/stable" - generators = "cmake", "cmake_find_package", "cmake_paths" - #default_options = { - # "sdl2:nas": False - #} + settings = 'os', 'compiler', 'build_type', 'arch' + requires = 'jsoncpp/1.9.4', 'glfw/3.3.4' + generators = 'cmake', 'cmake_find_package', 'cmake_paths' + default_options = { + } diff --git a/src/nostalgia/core/CMakeLists.txt b/src/nostalgia/core/CMakeLists.txt index cfd34013..1982b985 100644 --- a/src/nostalgia/core/CMakeLists.txt +++ b/src/nostalgia/core/CMakeLists.txt @@ -15,7 +15,7 @@ target_link_libraries( add_subdirectory(gba) if(NOSTALGIA_BUILD_TYPE STREQUAL "Native") - add_subdirectory(sdl) + add_subdirectory(glfw) add_subdirectory(userland) endif() if(NOSTALGIA_BUILD_STUDIO) diff --git a/src/nostalgia/core/core.hpp b/src/nostalgia/core/core.hpp index c989d6e3..b790d0a4 100644 --- a/src/nostalgia/core/core.hpp +++ b/src/nostalgia/core/core.hpp @@ -25,11 +25,11 @@ ox::Error run(Context *ctx) noexcept; // Sets event handler that sleeps for the time given in the return value. The // sleep time is a minimum of ~16 milliseconds. -void setEventHandler(event_handler) noexcept; +void setEventHandler(Context *ctx, event_handler) noexcept; // Returns the number of milliseconds that have passed since the start of the // program. [[nodiscard]] -uint64_t ticksMs() noexcept; +uint64_t ticksMs(Context *ctx) noexcept; } diff --git a/src/nostalgia/core/gba/core.cpp b/src/nostalgia/core/gba/core.cpp index 24cb0f1b..52773b56 100644 --- a/src/nostalgia/core/gba/core.cpp +++ b/src/nostalgia/core/gba/core.cpp @@ -47,11 +47,11 @@ ox::Error init(Context *ctx) noexcept { return OxError(0); } -void setEventHandler(event_handler h) noexcept { +void setEventHandler(Context*, event_handler h) noexcept { g_eventHandler = h; } -uint64_t ticksMs() noexcept { +uint64_t ticksMs(Context*) noexcept { return g_timerMs; } diff --git a/src/nostalgia/core/glfw/CMakeLists.txt b/src/nostalgia/core/glfw/CMakeLists.txt new file mode 100644 index 00000000..70bb2ae1 --- /dev/null +++ b/src/nostalgia/core/glfw/CMakeLists.txt @@ -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 +) diff --git a/src/nostalgia/core/glfw/core.cpp b/src/nostalgia/core/glfw/core.cpp new file mode 100644 index 00000000..5e1ebea5 --- /dev/null +++ b/src/nostalgia/core/glfw/core.cpp @@ -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 + +#include +#include +#include +#include + +#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(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(glfwGetWindowUserPointer(window)); + const auto id = ctx->windowerData(); + 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(); + 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(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(); + id->eventHandler = h; +} + +uint64_t ticksMs(Context *ctx) noexcept { + using namespace std::chrono; + const auto id = ctx->windowerData(); + const auto now = duration_cast(system_clock::now().time_since_epoch()).count(); + return static_cast(now - id->startTime); +} + +bool buttonDown(Key) noexcept { + return false; +} + +} diff --git a/src/nostalgia/core/glfw/core.hpp b/src/nostalgia/core/glfw/core.hpp new file mode 100644 index 00000000..2226e46e --- /dev/null +++ b/src/nostalgia/core/glfw/core.hpp @@ -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 + +namespace nostalgia::core { + +struct GlfwImplData { + class GLFWwindow *window = nullptr; + int64_t startTime = 0; + bool running = false; + event_handler eventHandler = nullptr; +}; + +} diff --git a/src/nostalgia/core/glfw/gfx.cpp b/src/nostalgia/core/glfw/gfx.cpp new file mode 100644 index 00000000..09e7649f --- /dev/null +++ b/src/nostalgia/core/glfw/gfx.cpp @@ -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 + +#include + +#include + +#include +#include + +#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(); + 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(); + glfwDestroyWindow(id->window); + ctx->setWindowerData(nullptr); + delete id; + return OxError(0); +} + +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; +} + +common::Size getScreenSize(Context *ctx) noexcept { + auto id = ctx->windowerData(); + int w = 0, h = 0; + glfwGetFramebufferSize(id->window, &w, &h); + return {w, h}; +} + +} diff --git a/src/nostalgia/player/CMakeLists.txt b/src/nostalgia/player/CMakeLists.txt index faff4d19..f5676528 100644 --- a/src/nostalgia/player/CMakeLists.txt +++ b/src/nostalgia/player/CMakeLists.txt @@ -22,7 +22,7 @@ target_link_libraries( nostalgia NostalgiaWorld $<$:NostalgiaCore-GBA> - $<$:NostalgiaCore-SDL> + $<$:NostalgiaCore-GLFW> ) install( diff --git a/src/nostalgia/player/app.cpp b/src/nostalgia/player/app.cpp index 6684bf16..784812c8 100644 --- a/src/nostalgia/player/app.cpp +++ b/src/nostalgia/player/app.cpp @@ -41,7 +41,7 @@ ox::Error run(ox::FileSystem *fs) noexcept { oxReturnError(core::loadSpriteTileSheet(&ctx, 0, TileSheetAddr, PaletteAddr)); oxReturnError(core::initConsole(&ctx)); core::puts(&ctx, 10, 9, "DOPENESS!!!"); - core::setEventHandler(eventHandler); + core::setEventHandler(&ctx, eventHandler); oxReturnError(core::run(&ctx)); oxReturnError(core::shutdownGfx(&ctx)); return OxError(0);