/* * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. */ #include #include #include #include #include #include "core.hpp" namespace nostalgia::core { void draw(Context *ctx) noexcept; ox::Result> init(ox::UniquePtr fs, const char *appName) noexcept { auto ctx = ox::make_unique(); ctx->rom = std::move(fs); ctx->appName = appName; 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.get())); return ctx; } ox::Error run(Context *ctx) noexcept { const auto id = ctx->windowerData(); int sleepTime = 0; while (!glfwWindowShouldClose(id->window)) { glfwPollEvents(); const auto ticks = ticksMs(ctx); if (id->eventHandler) { if (id->wakeupTime <= ticks) { sleepTime = id->eventHandler(ctx); if (sleepTime >= 0) { id->wakeupTime = ticks + static_cast(sleepTime); } else { id->wakeupTime = ~uint64_t(0); } } } else { sleepTime = 2; } draw(ctx); glfwSwapBuffers(id->window); glfwWaitEventsTimeout(sleepTime); } // destroy GLFW window renderer::shutdown(ctx, ctx->rendererData()); glfwDestroyWindow(id->window); ctx->setWindowerData(nullptr); delete id; 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; } ox::Error shutdown(Context *ctx) noexcept { const auto id = ctx->windowerData(); glfwSetWindowShouldClose(id->window, true); return OxError(0); } }