/* * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. */ #pragma once #include #include #include #include #include #include "event.hpp" #include "input.hpp" namespace nostalgia::core::gl { void setMainViewEnabled(core::Context *ctx, bool enabled) noexcept; void drawMainView(core::Context*) noexcept; void setRenderSize(core::Context*, int width, int height) noexcept; ox::Size getRenderSize(core::Context*) noexcept; void clearRenderSize(core::Context *ctx) noexcept; } namespace nostalgia::core::renderer { ox::Error init(Context *ctx) noexcept; } namespace ox { class Size; } namespace nostalgia::core { class BaseClipboardObject { public: virtual ~BaseClipboardObject() noexcept = default; [[nodiscard]] virtual ox::String typeId() const noexcept = 0; [[nodiscard]] constexpr auto typeMatch(auto name, auto version) const noexcept { return typeId() == ox::buildTypeId(name, version); } }; template class ClipboardObject: public BaseClipboardObject { [[nodiscard]] ox::String typeId() const noexcept final { return ox::buildTypeId(T::TypeName, T::TypeVersion); } }; class Drawer; struct BgCbbData { unsigned bpp = 4; }; // User Input Output class Context: public keel::Context { friend constexpr void setApplicationData(Context *ctx, void *applicationData) noexcept; template friend constexpr T *applicationData(Context *ctx) noexcept; friend constexpr void setConstantRefresh(Context *ctx, bool) noexcept; friend bool bgStatus(Context *ctx, unsigned bg) noexcept; friend bool buttonDown(Context *ctx, Key) noexcept; friend ox::Size getScreenSize(Context *ctx) noexcept; friend int getScreenHeight(Context *ctx) noexcept; friend int getScreenWidth(Context *ctx) noexcept; friend ox::Error initGfx(Context *ctx) noexcept; friend ox::Error renderer::init(Context *ctx) noexcept; friend ox::Error loadBgTileSheet(Context *ctx, unsigned cbb, const ox::FileAddress &tilesheetPath, const ox::FileAddress &palettePath) noexcept; friend ox::Error loadSpriteTileSheet(Context *ctx, const ox::FileAddress &tilesheetAddr, const ox::FileAddress &paletteAddr) noexcept; friend ox::Result loadTileSheet(Context *ctx, const struct CompactTileSheet &tilesheetAddr) noexcept; friend ox::Error run(Context *ctx) noexcept; friend void shutdown(Context *ctx) noexcept; friend ox::Result> init(ox::UPtr fs, ox::CRStringView appName) noexcept; friend ox::String getClipboardText(Context *ctx) noexcept; friend uint64_t ticksMs(Context *ctx) noexcept; friend uint8_t bgStatus(Context *ctx) noexcept; friend void clearTileLayer(Context *ctx, unsigned bgIdx) noexcept; friend void draw(Context *ctx) noexcept; friend void focusWindow(Context *ctx) noexcept; friend void setBgCbb(Context *ctx, unsigned bgIdx, unsigned cbb) noexcept; friend void setBgStatus(Context *ctx, uint32_t status) noexcept; friend void setBgStatus(Context *ctx, unsigned bg, bool status) noexcept; friend void setUpdateHandler(Context *ctx, UpdateHandler h) noexcept; friend constexpr void setKeyEventHandler(Context *ctx, KeyEventHandler h) noexcept; friend constexpr KeyEventHandler keyEventHandler(Context *ctx) noexcept; friend void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) noexcept; friend void setSprite(Context *ctx, unsigned idx, int x, int y, unsigned tileIdx, unsigned spriteShape, unsigned spriteSize, unsigned flipX) noexcept; friend void hideSprite(Context *ctx, unsigned idx) noexcept; friend void gl::setMainViewEnabled(core::Context *ctx, bool enabled) noexcept; friend void gl::drawMainView(core::Context*) noexcept; friend void gl::setRenderSize(core::Context*, int width, int height) noexcept; friend ox::Size gl::getRenderSize(core::Context*) noexcept; friend void gl::clearRenderSize(core::Context *ctx) noexcept; public: ox::Vector drawers; #ifndef OX_BARE_METAL int uninterruptedRefreshes = 3; ox::UPtr clipboard; #endif protected: #ifndef OX_BARE_METAL // sets screen refresh to constant instead of only on event bool constantRefresh = true; #endif KeyEventHandler m_keyEventHandler = nullptr; void *m_customData = nullptr; private: void *m_windowerData = nullptr; void *m_rendererData = nullptr; public: Context() noexcept = default; Context(Context &other) noexcept = delete; Context(const Context &other) noexcept = delete; Context(const Context &&other) noexcept = delete; template [[nodiscard]] constexpr T *windowerData() noexcept { return static_cast(m_windowerData); } protected: constexpr void setWindowerData(void *windowerData) noexcept { m_windowerData = windowerData; } constexpr void setRendererData(void *rendererData) noexcept { m_rendererData = rendererData; } template [[nodiscard]] constexpr T *rendererData() noexcept { return static_cast(m_rendererData); } }; constexpr void setApplicationData(Context *ctx, void *applicationData) noexcept { ctx->m_customData = applicationData; } template [[nodiscard]] constexpr T *applicationData(Context *ctx) noexcept { return static_cast(ctx->m_customData); } constexpr void setKeyEventHandler(Context *ctx, KeyEventHandler h) noexcept { ctx->m_keyEventHandler = h; } constexpr KeyEventHandler keyEventHandler(Context *ctx) noexcept { return ctx->m_keyEventHandler; } constexpr void setConstantRefresh([[maybe_unused]] Context *ctx, [[maybe_unused]] bool r) noexcept { #ifndef OX_BARE_METAL ctx->constantRefresh = r; #endif } }