Squashed 'deps/nostalgia/' changes from 89ae226b..9676ea59
9676ea59 [turbine/glfw] Fix programmatic shutdown to invoke shutdownHandler de8ac106 [turbine/glfw] Fix closing when no shutdown handler is set 88a6cd59 [turbine/glfw] Treat close window event like other events with regard to a mandatory refresh period cd43fb7f [turbine,studio] Fix confirm app close pop up to work with Ctrl-Q 136f4224 [nostalgia] Update release notes e773d6f0 [studio] Rename StudioContext to Context 7da2f68d [nostalgia/sample_project] Add assets d20889ae [nostalgia/gfx/studio] Update for Ox changes 50c8302f [ox] Rename itoa to intToStr d8195d30 [olympic,nostalgia] Address unsafe buffer warnings a8c1387d [ox] Address unsafe buffer warnings ff1e8f26 [studio] Add popup to warn about UUID duplication d4329981 [studio,nostalgia] Cleanup 00034543 [studio,nostalgia/gfx/studio] Cleanup 8c6b2234 [olympic/util] Make pkg-gba script check return code of subprocesses aad4b8a4 [studio] Cleanup 7cab1331 [keel] Add ability to log UUID duplication 640ac85d [nostalgia/gfx/studio/palette] Make page rename dialog accept on enter if input focused b8d76586 [nostalgia/studio] Update generated icondata.cpp with Clang fix 2503bb3b [nostalgia/sample_project] Update type descriptors e5dd448f [turbine,studio] Make Studio confirm with user before closing app if any unsaved changes 4770bb6a [olympic/util] Cleanup c0bac696 [nostalgia/gfx/studio/paletteeditor] Fix color number key range 95f7c334 [studio] Change Studio font 535d8876 [keel] Cleanup 845e4332 [turbine] Fix Mac build 5169a607 [turbine] Disable useless window icon on Mac, it causes GLFW warning 8f03af99 [keel] Style updates ee63a4a1 [keel] Cleanup git-subtree-dir: deps/nostalgia git-subtree-split: 9676ea59787215b01498dfa82f88d426363b3cfd
This commit is contained in:
@@ -19,8 +19,6 @@ class Context;
|
||||
|
||||
void safeDelete(Context *p);
|
||||
|
||||
void shutdown(Context &ctx) noexcept;
|
||||
|
||||
keel::Context const&keelCtx(Context const&ctx) noexcept;
|
||||
|
||||
keel::Context &keelCtx(Context &ctx) noexcept;
|
||||
|
||||
@@ -27,6 +27,10 @@ ox::Error run(Context &ctx) noexcept;
|
||||
[[nodiscard]]
|
||||
TimeMs ticksMs(Context const&ctx) noexcept;
|
||||
|
||||
void requestShutdown(Context &ctx) noexcept;
|
||||
void requestShutdown(Context &ctx, bool force = false) noexcept;
|
||||
|
||||
using ShutdownHandler = bool (*)(Context&);
|
||||
|
||||
void setShutdownHandler(Context &ctx, ShutdownHandler handler) noexcept;
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace turbine {
|
||||
|
||||
class Context {
|
||||
class Context final {
|
||||
public:
|
||||
UpdateHandler updateHandler = [](Context&) -> int {return 0;};
|
||||
keel::Context keelCtx;
|
||||
@@ -27,10 +27,6 @@ class Context {
|
||||
Context(Context const&other) noexcept = delete;
|
||||
Context(Context const&&other) noexcept = delete;
|
||||
|
||||
virtual inline ~Context() noexcept {
|
||||
shutdown(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ static ox::Result<std::size_t> findPreloadSection() noexcept {
|
||||
// media section
|
||||
constexpr auto headerP2 = "DER_____________";
|
||||
constexpr auto headerP1 = "KEEL_PRELOAD_HEA";
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
constexpr auto headerP1Len = ox::strlen(headerP2);
|
||||
constexpr auto headerP2Len = ox::strlen(headerP1);
|
||||
constexpr auto headerLen = headerP1Len + headerP2Len;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
for (auto current = MEM_ROM; current < reinterpret_cast<char*>(0x0a000000); current += headerLen) {
|
||||
if (memcmp(current, headerP1, headerP1Len) == 0 &&
|
||||
memcmp(current + headerP1Len, headerP2, headerP2Len) == 0) {
|
||||
@@ -82,8 +82,11 @@ bool buttonDown(Context const&, Key k) noexcept {
|
||||
return k <= Key::GamePad_L && !(REG_GAMEPAD & (1 << static_cast<int>(k)));
|
||||
}
|
||||
|
||||
void requestShutdown(Context &ctx) noexcept {
|
||||
void requestShutdown(Context &ctx, bool) noexcept {
|
||||
ctx.running = false;
|
||||
}
|
||||
|
||||
void setShutdownHandler(Context&, ShutdownHandler) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@ ox::String getClipboardText(Context &ctx) noexcept {
|
||||
|
||||
void setClipboardText(Context &ctx, ox::StringViewCR text) noexcept {
|
||||
auto cstr = ox_malloca(text.bytes() + 1, char);
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
ox::strncpy(cstr.get(), text.data(), text.bytes());
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
glfwSetClipboardString(ctx.window, cstr.get());
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ class Context {
|
||||
uint64_t keysDown = 0;
|
||||
uint64_t prevFpsCheckTime = 0;
|
||||
uint64_t draws = 0;
|
||||
bool running{};
|
||||
ShutdownHandler shutdownHandler{};
|
||||
|
||||
Context() noexcept = default;
|
||||
|
||||
|
||||
@@ -93,6 +93,14 @@ static void handleGlfwKeyEvent(GLFWwindow *window, int key, int, int action, int
|
||||
}
|
||||
}
|
||||
|
||||
static void handleGlfwWindowCloseEvent(GLFWwindow *window) noexcept {
|
||||
auto &ctx = *static_cast<Context*>(glfwGetWindowUserPointer(window));
|
||||
ctx.mandatoryRefreshPeriodEnd = ticksMs(ctx) + config::MandatoryRefreshPeriod;
|
||||
ctx.running = ctx.shutdownHandler ? !ctx.shutdownHandler(ctx) : false;
|
||||
glfwSetWindowShouldClose(window, !ctx.running);
|
||||
glfwPostEmptyEvent();
|
||||
}
|
||||
|
||||
#if TURBINE_USE_IMGUI
|
||||
static void themeImgui() noexcept {
|
||||
// Dark Ruda style by Raikiri from ImThemes
|
||||
@@ -210,6 +218,7 @@ ox::Error initGfx(Context &ctx) noexcept {
|
||||
glfwSetCursorPosCallback(ctx.window, handleGlfwCursorPosEvent);
|
||||
glfwSetMouseButtonCallback(ctx.window, handleGlfwMouseButtonEvent);
|
||||
glfwSetKeyCallback(ctx.window, handleGlfwKeyEvent);
|
||||
glfwSetWindowCloseCallback(ctx.window, handleGlfwWindowCloseEvent);
|
||||
glfwSetWindowUserPointer(ctx.window, &ctx);
|
||||
glfwMakeContextCurrent(ctx.window);
|
||||
if (!gladLoadGLES2Loader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress))) {
|
||||
@@ -235,6 +244,7 @@ struct IconData {
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
[[maybe_unused]]
|
||||
static ox::Result<IconData> toGlfwImgPixels(ox::SpanView<uint8_t> const &iconPng) noexcept {
|
||||
ox::Result<IconData> out;
|
||||
unsigned w{}, h{};
|
||||
@@ -247,24 +257,28 @@ static ox::Result<IconData> toGlfwImgPixels(ox::SpanView<uint8_t> const &iconPng
|
||||
}
|
||||
|
||||
ox::Error setWindowIcon(Context &ctx, ox::SpanView<ox::SpanView<uint8_t>> const &iconPngs) noexcept {
|
||||
ox::Vector<IconData, 8> src;
|
||||
ox::Vector<GLFWimage, 8> imgs;
|
||||
for (auto const &iconPng : iconPngs) {
|
||||
OX_RETURN_ERROR(toGlfwImgPixels(iconPng).moveTo(src.emplace_back()));
|
||||
auto &icon = *src.back().unwrap();
|
||||
imgs.emplace_back(GLFWimage{
|
||||
.width = icon.w,
|
||||
.height = icon.h,
|
||||
.pixels = icon.pixels.data(),
|
||||
});
|
||||
if constexpr(ox::defines::OS != ox::OS::Darwin) {
|
||||
ox::Vector<IconData, 8> src;
|
||||
ox::Vector<GLFWimage, 8> imgs;
|
||||
for (auto const &iconPng : iconPngs) {
|
||||
OX_RETURN_ERROR(toGlfwImgPixels(iconPng).moveTo(src.emplace_back()));
|
||||
auto &icon = *src.back().unwrap();
|
||||
imgs.emplace_back(GLFWimage{
|
||||
.width = icon.w,
|
||||
.height = icon.h,
|
||||
.pixels = icon.pixels.data(),
|
||||
});
|
||||
}
|
||||
glfwSetWindowIcon(ctx.window, static_cast<int>(imgs.size()), imgs.data());
|
||||
}
|
||||
glfwSetWindowIcon(ctx.window, static_cast<int>(imgs.size()), imgs.data());
|
||||
return {};
|
||||
}
|
||||
|
||||
void setWindowTitle(Context &ctx, ox::StringViewCR title) noexcept {
|
||||
auto cstr = ox_malloca(title.bytes() + 1, char);
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
ox::strncpy(cstr.get(), title.data(), title.bytes());
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
glfwSetWindowTitle(ctx.window, cstr.get());
|
||||
}
|
||||
|
||||
|
||||
@@ -68,9 +68,21 @@ static void tickFps(Context &ctx, uint64_t const nowMs) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
static void shutdown(Context &ctx) noexcept {
|
||||
if (ctx.window) {
|
||||
#if TURBINE_USE_IMGUI
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
#endif
|
||||
glfwDestroyWindow(ctx.window);
|
||||
ctx.window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ox::Error run(Context &ctx) noexcept {
|
||||
uint64_t sleepTime = 0;
|
||||
while (!glfwWindowShouldClose(ctx.window)) {
|
||||
ctx.running = true;
|
||||
while (ctx.running) {
|
||||
ctx.refreshWithinMs = 10 * 1000; // refresh within 10 seconds
|
||||
glfwPollEvents();
|
||||
auto const ticks = ticksMs(ctx);
|
||||
@@ -80,7 +92,7 @@ ox::Error run(Context &ctx) noexcept {
|
||||
ctx.wakeupTime = ticks + static_cast<unsigned>(st);
|
||||
sleepTime = static_cast<uint64_t>(st);
|
||||
} else {
|
||||
ctx.wakeupTime = ~uint64_t(0);
|
||||
ctx.wakeupTime = ~uint64_t{0};
|
||||
sleepTime = ctx.wakeupTime - ticks;
|
||||
}
|
||||
} else {
|
||||
@@ -97,17 +109,6 @@ ox::Error run(Context &ctx) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
void shutdown(Context &ctx) noexcept {
|
||||
if (ctx.window) {
|
||||
#if TURBINE_USE_IMGUI
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
#endif
|
||||
glfwDestroyWindow(ctx.window);
|
||||
ctx.window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TimeMs ticksMs(Context const&ctx) noexcept {
|
||||
using namespace std::chrono;
|
||||
auto const now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
|
||||
@@ -118,8 +119,17 @@ bool buttonDown(Context const&ctx, Key const key) noexcept {
|
||||
return (ctx.keysDown >> static_cast<int>(key)) & 1;
|
||||
}
|
||||
|
||||
void requestShutdown(Context &ctx) noexcept {
|
||||
void requestShutdown(Context &ctx, bool const force) noexcept {
|
||||
glfwSetWindowShouldClose(ctx.window, true);
|
||||
if (force) {
|
||||
ctx.running = false;
|
||||
} else {
|
||||
ctx.running = ctx.shutdownHandler ? !ctx.shutdownHandler(ctx) : false;
|
||||
}
|
||||
}
|
||||
|
||||
void setShutdownHandler(Context &ctx, ShutdownHandler const handler) noexcept {
|
||||
ctx.shutdownHandler = handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user