#include "nxstl/thread" #include "nxstl/condition_variable" #include "nxstl/mutex" #include "boo/IApplication.hpp" #include "boo/graphicsdev/NX.hpp" #include #include #include namespace boo { static logvisor::Module Log("boo::NXApplication"); std::shared_ptr _WindowNXNew(std::string_view title, NXContext* nxCtx); class ApplicationNX : public IApplication { IApplicationCallback& m_callback; const std::string m_uniqueName; const std::string m_friendlyName; const std::string m_pname; const std::vector m_args; NXContext m_nxCtx; void _deletedWindow(IWindow* window) override {} public: ApplicationNX(IApplicationCallback& callback, std::string_view uniqueName, std::string_view friendlyName, std::string_view pname, const std::vector& args, std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor, bool singleInstance) : m_callback(callback), m_uniqueName(uniqueName), m_friendlyName(friendlyName), m_pname(pname), m_args(args) {} EPlatformType getPlatformType() const override { return EPlatformType::NX; } int run() override { /* Spawn client thread */ int clientReturn = INT_MIN; std::mutex initmt; std::condition_variable initcv; std::unique_lock outerLk(initmt); std::thread clientThread([&]() { std::unique_lock innerLk(initmt); innerLk.unlock(); initcv.notify_one(); std::string thrName = std::string(getFriendlyName()) + " Client"; logvisor::RegisterThreadName(thrName.c_str()); clientReturn = m_callback.appMain(this); }); initcv.wait(outerLk); // Main graphics loop while (clientReturn == INT_MIN && appletMainLoop()) { // Get and process input hidScanInput(); u32 kDown = hidKeysDown(CONTROLLER_P1_AUTO); if (kDown & KEY_PLUS) break; } m_callback.appQuitting(this); if (clientThread.joinable()) clientThread.join(); return 0; } std::string_view getUniqueName() const override { return m_uniqueName; } std::string_view getFriendlyName() const override { return m_friendlyName; } std::string_view getProcessName() const override { return m_pname; } const std::vector& getArgs() const override { return m_args; } std::shared_ptr m_window; std::shared_ptr newWindow(std::string_view title) override { if (m_window) Log.report(logvisor::Fatal, fmt("Only 1 window allowed on NX")); m_window = _WindowNXNew(title, &m_nxCtx); return m_window; } }; IApplication* APP = nullptr; int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, SystemStringView uniqueName, SystemStringView friendlyName, SystemStringView pname, const std::vector& args, std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor, bool singleInstance) { std::string thrName = std::string(friendlyName) + " Main Thread"; logvisor::RegisterThreadName(thrName.c_str()); if (APP) return 1; APP = new ApplicationNX(cb, uniqueName, friendlyName, pname, args, gfxApi, samples, anisotropy, deepColor, singleInstance); int ret = APP->run(); delete APP; APP = nullptr; return ret; } } // namespace boo