From ca26189f529b9ac522b3bc7b7136afbd3e96f960 Mon Sep 17 00:00:00 2001 From: tobid7 Date: Sun, 9 Feb 2025 21:40:31 +0100 Subject: [PATCH] # Stage 1.9 - Add AppInit Flags and AppFlags to COntrol some Individual Stuff (Not using default can run into a crash report if things get used that are disabled) - Create a Test Settings Menu - Make Some Menu functions Public - Add ScrollTo Animation - Make ContainerApi fully public - Remove an else statement (now need to find a way to not set the pos twice) - --- CMakeLists.txt | 5 +- include/pd.hpp | 1 + include/pd/common/app.hpp | 29 +++++++++++ include/pd/overlays/settings.hpp | 13 ++++- include/pd/ui7/menu.hpp | 40 +++++++++++---- include/pd/ui7/ui7.hpp | 5 ++ source/common/app.cpp | 85 +++++++++++++++++++++----------- source/overlays/settings.cpp | 39 +++++++++++++++ source/ui7/menu.cpp | 31 ++++++------ source/ui7/ui7.cpp | 7 ++- test/app/main.cpp | 12 ++++- 11 files changed, 207 insertions(+), 60 deletions(-) create mode 100644 source/overlays/settings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 74ef482..b06026f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ execute_process( ) # Set Project -project(palladium LANGUAGES C CXX VERSION 0.1.8) +project(palladium LANGUAGES C CXX VERSION 0.1.9) # Enable Compile Command Export set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -28,7 +28,7 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) # Set Special C and CXX flags -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-psabi -O3") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-psabi -O2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions") set(SRC_FILES @@ -57,6 +57,7 @@ set(SRC_FILES source/overlays/overlay_mgr.cpp source/overlays/keyboard.cpp source/overlays/performance.cpp + source/overlays/settings.cpp # Tools source/tools/gamepad_icons.cpp # UI7 diff --git a/include/pd.hpp b/include/pd.hpp index 9dcc22a..ceef6f8 100644 --- a/include/pd.hpp +++ b/include/pd.hpp @@ -44,6 +44,7 @@ SOFTWARE. #include #include #include +#include // UI7 #include diff --git a/include/pd/common/app.hpp b/include/pd/common/app.hpp index 18f13b1..61af3e6 100644 --- a/include/pd/common/app.hpp +++ b/include/pd/common/app.hpp @@ -34,6 +34,27 @@ namespace PD { /// @brief Template Class for User Application class App { public: + using AppFlags = u32; + enum AppFlags_ { + AppFlags_None = 0, + AppFLags_UserLoop = 1 << 0, + AppFlags_HandleOverlays = 1 << 1, + AppFlags_HandleMessageMgr = 1 << 2, + AppFlags_HandleRendering = 1 << 3, + AppFlags_Default = AppFlags_HandleMessageMgr | AppFlags_HandleOverlays | + AppFlags_HandleRendering | AppFLags_UserLoop, + }; + using AppInitFlags = u32; + enum AppInitFlags_ { + AppInitFlags_None = 0, + AppInitFlags_MountRomfs = 1 << 0, + AppInitFlags_InitGraphics = 1 << 1, + AppInitFlags_New3dsMode = 1 << 2, + AppInitFlags_InitGraphicsNoC3D = 1 << 3, + AppInitFlags_InitLithium = 1 << 4, + AppInitFlags_Default = AppInitFlags_MountRomfs | AppInitFlags_InitGraphics | + AppInitFlags_New3dsMode | AppInitFlags_InitLithium, + }; App() { if (too) { Error("Only one App can be created at the same time!"); @@ -66,11 +87,19 @@ class App { Hid::Ref Input() { return input_mgr; } float GetFps() const { return fps; } + void FeatureEnable(AppFlags flags) { runtimeflags |= flags; } + void FeatureDisable(AppFlags flags) { runtimeflags &= ~flags; } + AppFlags& GetFeatureSet() { return runtimeflags; } + protected: Screen::Ref Top; Screen::Ref Bottom; + AppInitFlags InitFlags = AppInitFlags_Default; private: + AppFlags runtimeflags = AppFlags_Default; + /// @brief Safe Copy to prevent from editing befor Deinit + AppInitFlags SafeInitFlags = AppInitFlags_Default; void PreInit(); void PostDeinit(); LI::Renderer::Ref renderer; diff --git a/include/pd/overlays/settings.hpp b/include/pd/overlays/settings.hpp index a185647..769cf2c 100644 --- a/include/pd/overlays/settings.hpp +++ b/include/pd/overlays/settings.hpp @@ -23,19 +23,23 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include +#include #include #include -#include +#include namespace PD { class SettingsMenu : public Overlay { public: - SettingsMenu() { + SettingsMenu(PD::App* app) { too++; if (too > 1) { Kill(); return; } + app_ref = app; + app->FeatureDisable(PD::App::AppFLags_UserLoop); flymgr.From(vec2(0, 240)).To(vec2(0, 115)).In(0.3f).As(flymgr.EaseInQuad); } ~SettingsMenu() { too--; } @@ -44,10 +48,12 @@ class SettingsMenu : public Overlay { void Rem() { rem = true; + app_ref->FeatureEnable(App::AppFLags_UserLoop); flymgr.From(vec2(0, 115)).To(vec2(0, 240)).In(0.2f).As(flymgr.EaseOutQuad); } private: + PD::App* app_ref = nullptr; /// Section is used to determinate what /// should be displayed on the top screen int section = 0; @@ -57,5 +63,8 @@ class SettingsMenu : public Overlay { // Some Animation bool rem = false; Tween flymgr; + + // Custom UI7 Context + UI7::Context::Ref ctx; }; } // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/menu.hpp b/include/pd/ui7/menu.hpp index 7c9bb30..0d5cd10 100644 --- a/include/pd/ui7/menu.hpp +++ b/include/pd/ui7/menu.hpp @@ -24,6 +24,7 @@ SOFTWARE. */ #include +#include #include #include #include @@ -73,6 +74,31 @@ class Menu : public SmartCtor { cursor = bcursor; bcursor = vec2(); } + bool HasVerticalScrollbar() { return scrollbar[1]; } + bool HasHorizontalScrollbar() { return scrollbar[0]; } + float TitleBarHeight() { return tbh; } + /// @brief Set a Custom Titlebar heigt + /// @note Could destroy some basic functionality + void TitleBarHeight(float v) { tbh = v; } + /// @brief Init the Cursor + /// @note Useful when using with a Custom TitlebarHeight + void CursorInit() { Cursor(vec2(5, tbh + 5)); } + void CursorMove(const vec2& szs); + + vec4 ViewArea() const { return view_area; } + vec4 MainArea() const { return main_area; } + void MainArea(const vec4& v) { main_area = v; } + vec2 ScrollOffset() const { return scrolling_off; } + void ScrollTo(vec2 pos) { + scroll_anim.From(scrolling_off) + .To(pos) + .In(1.f) + .As(scroll_anim.EaseInOutSine); + } + + /// Objects API + Container::Ref ObjectPush(Container::Ref obj); + Container::Ref FindIDObj(u32 id); /// Draw Lists DrawList::Ref BackList() { return back; } @@ -94,27 +120,17 @@ class Menu : public SmartCtor { void PreHandler(UI7MenuFlags flags); void PostHandler(); /// Basic Settings - vec2 BackupCursor() const { return bcursor; } void BackupCursor(const vec2& v) { bcursor = v; } vec2 SameLineCursor() const { return slcursor; } void SameLineCursor(const vec2& v) { slcursor = v; } - vec4 ViewArea() const { return view_area; } void ViewArea(const vec4& v) { view_area = v; } - vec2 ScrollOffset() const { return scrolling_off; } void ScrollOffset(const vec2& v) { scrolling_off = v; } vec2 ScrollMod() const { return scroll_mod; } void ScrollMod(const vec2& v) { scroll_mod = v; } - /// Advanced - void CursorMove(const vec2& szs); - /// Internal Processing void Update(float delta); - /// Objects API - Container::Ref ObjectPush(Container::Ref obj); - Container::Ref FindIDObj(u32 id); - /// This ability is crazy useful friend class Context; @@ -126,6 +142,7 @@ class Menu : public SmartCtor { vec2 bcursor; vec2 slcursor; vec4 view_area; + vec4 main_area; vec2 scrolling_off; bool scrolling[2]; vec2 scroll_mod; @@ -158,6 +175,9 @@ class Menu : public SmartCtor { // Input Reference Hid::Ref inp; + + // Animations System + Tween scroll_anim; }; } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/ui7.hpp b/include/pd/ui7/ui7.hpp index 524decb..049c68a 100644 --- a/include/pd/ui7/ui7.hpp +++ b/include/pd/ui7/ui7.hpp @@ -58,7 +58,12 @@ class Context : public SmartCtor { DrawList::Ref BackList() { return back; } DrawList::Ref FrontList() { return front; } + void RootLayer(int l) { root_layer = l; } + int RootLayer() const { return root_layer; } + private: + // Used in Overlays + int root_layer = 0; // Linked Renderer / Hid LI::Renderer::Ref ren; Hid::Ref inp; diff --git a/source/common/app.cpp b/source/common/app.cpp index 6332289..d1a2e2a 100644 --- a/source/common/app.cpp +++ b/source/common/app.cpp @@ -41,42 +41,65 @@ void App::Run() { app_time += dt / 1000.f; last_time = current; fps = 1000.f / dt; - PD::TT::Beg("App_MainLoop"); - if (!this->MainLoop(dt, app_time)) { - break; + if (runtimeflags & AppFLags_UserLoop) { + PD::TT::Beg("App_MainLoop"); + if (!this->MainLoop(dt, app_time)) { + break; + } + PD::TT::End("App_MainLoop"); } - PD::TT::End("App_MainLoop"); PD::TT::Beg("Ovl_Update"); - renderer->Layer(90); - overlay_mgr->Update(dt); - /// Messages have their own special Layer - renderer->Layer(93); - msg_mgr->Update(dt); + if (runtimeflags & AppFlags_HandleOverlays && + SafeInitFlags & AppInitFlags_InitLithium) { + renderer->Layer(90); + overlay_mgr->Update(dt); + } + if (runtimeflags & AppFlags_HandleMessageMgr && + SafeInitFlags & AppInitFlags_InitLithium) { + /// Messages have their own special Layer + renderer->Layer(93); + msg_mgr->Update(dt); + } PD::TT::End("Ovl_Update"); - renderer->PrepareRender(); - renderer->Render(Top); - renderer->Render(Bottom); - renderer->FinalizeRender(); + if (runtimeflags & AppFlags_HandleRendering && + SafeInitFlags & AppInitFlags_InitLithium) { + renderer->PrepareRender(); + renderer->Render(Top); + renderer->Render(Bottom); + renderer->FinalizeRender(); + } } this->Deinit(); this->PostDeinit(); } void App::PreInit() { - osSetSpeedupEnable(true); - gfxInitDefault(); + /// Create a Copy that won't get edit + SafeInitFlags = InitFlags; + osSetSpeedupEnable(InitFlags & AppInitFlags_New3dsMode); + if (InitFlags & AppInitFlags_InitGraphics) { + gfxInitDefault(); + if (!(InitFlags & AppInitFlags_InitGraphicsNoC3D)) { + C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + } + } cfguInit(); - romfsInit(); - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + if (InitFlags & AppInitFlags_MountRomfs) { + romfsInit(); + } input_mgr = Hid::New(); - Top = Screen::New(Screen::Top); - Bottom = Screen::New(Screen::Bottom); - renderer = LI::Renderer::New(); - renderer->RegisterScreen(false, Top); - renderer->RegisterScreen(true, Bottom); - renderer->OnScreen(Top); - msg_mgr = MessageMgr::New(renderer); - overlay_mgr = OverlayMgr::New(renderer, input_mgr); + if (InitFlags & AppInitFlags_InitLithium) { + Assert(!(InitFlags & AppInitFlags_InitGraphicsNoC3D), + "InitGraphicsNoC3D is not compatible with InitLithium!"); + Top = Screen::New(Screen::Top); + Bottom = Screen::New(Screen::Bottom); + renderer = LI::Renderer::New(); + renderer->RegisterScreen(false, Top); + renderer->RegisterScreen(true, Bottom); + renderer->OnScreen(Top); + msg_mgr = MessageMgr::New(renderer); + overlay_mgr = OverlayMgr::New(renderer, input_mgr); + } } void App::PostDeinit() { @@ -84,9 +107,15 @@ void App::PostDeinit() { msg_mgr = nullptr; overlay_mgr = nullptr; input_mgr = nullptr; - C3D_Fini(); - gfxExit(); + if (SafeInitFlags & AppInitFlags_InitGraphics) { + if (!(SafeInitFlags & AppInitFlags_InitGraphicsNoC3D)) { + C3D_Fini(); + } + gfxExit(); + } cfguExit(); - romfsExit(); + if (SafeInitFlags & AppInitFlags_MountRomfs) { + romfsExit(); + } } } // namespace PD \ No newline at end of file diff --git a/source/overlays/settings.cpp b/source/overlays/settings.cpp new file mode 100644 index 0000000..541af9c --- /dev/null +++ b/source/overlays/settings.cpp @@ -0,0 +1,39 @@ +#include + +namespace PD { +int SettingsMenu::too = 0; +void SettingsMenu::Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) { + if (!ctx) { + ctx = UI7::Context::New(ren, inp); + ctx->RootLayer(70); + } + flymgr.Update(delta); + if (rem && flymgr.IsFinished()) { + this->Kill(); + } + ren->OnScreen(ren->GetScreen(false)); + if (ctx->BeginMenu("Palladium - Settings", UI7MenuFlags_CenterTitle)) { + auto m = ctx->GetCurrentMenu(); + m->SeparatorText("Library Info"); + m->Label(LibInfo::CompiledWith()); + m->AfterAlignCenter(); + m->Label(LibInfo::CxxVersion()); + m->AfterAlignCenter(); + m->Label("Version: " + LibInfo::Version() + "[" + LibInfo::Commit() + "]"); + m->AfterAlignCenter(); + m->Label("Build Time: " + LibInfo::BuildTime()); + m->AfterAlignCenter(); + ctx->EndMenu(); + } + ren->OnScreen(ren->GetScreen(true)); + if (ctx->BeginMenu("pdovlssettings", UI7MenuFlags_NoTitlebar)) { + auto m = ctx->GetCurrentMenu(); + m->SeparatorText("Settings"); + if (m->Button("Exit")) { + this->Rem(); + } + ctx->EndMenu(); + } + ctx->Update(delta); +} +} // namespace PD \ No newline at end of file diff --git a/source/ui7/menu.cpp b/source/ui7/menu.cpp index d18b14f..aaabab7 100644 --- a/source/ui7/menu.cpp +++ b/source/ui7/menu.cpp @@ -40,13 +40,12 @@ bool UI7::Menu::Button(const std::string& label) { u32 id = Strings::FastHash("btn" + label + std::to_string(count_btn++)); Container::Ref r = FindIDObj(id); if (!r) { - r = ObjectPush(PD::New(label, Cursor(), this->back->ren)); + r = PD::New(label, Cursor(), this->back->ren); r->SetID(id); r->Init(main->ren, main, linked_theme); - } else { - ObjectPush(r); - r->SetPos(Cursor()); } + ObjectPush(r); + r->SetPos(Cursor()); CursorMove(r->GetSize()); r->HandleScrolling(scrolling_off, view_area); if (!r->Skippable()) { @@ -59,13 +58,12 @@ void UI7::Menu::Checkbox(const std::string& label, bool& v) { u32 id = Strings::FastHash("cbx" + label + std::to_string(count_cbx++)); Container::Ref r = FindIDObj(id); if (!r) { - r = ObjectPush(PD::New(label, Cursor(), v, this->back->ren)); + r = PD::New(label, Cursor(), v, this->back->ren); r->SetID(id); r->Init(main->ren, main, linked_theme); - } else { - ObjectPush(r); - r->SetPos(Cursor()); } + ObjectPush(r); + r->SetPos(Cursor()); CursorMove(r->GetSize()); r->HandleScrolling(scrolling_off, view_area); } @@ -104,6 +102,10 @@ void UI7::Menu::DebugLabels() { void UI7::Menu::Update(float delta) { TT::Scope st("MUPT_" + name); + scroll_anim.Update(delta); + if (!scroll_anim.IsFinished()) { + scrolling_off = scroll_anim; + } std::vector tbr; for (int i = 0; i < (int)objects.size(); i++) { auto& it = objects[i]; @@ -146,12 +148,11 @@ void UI7::Menu::CursorMove(const vec2& size) { void UI7::Menu::PreHandler(UI7MenuFlags flags) { TT::Scope st("MPRE_" + name); TT::Beg("MUSR_" + name); - this->back->BaseLayer(30); - this->main->BaseLayer(40); - this->front->BaseLayer(50); count_btn = 0; count_cbx = 0; - Cursor(vec2(5, 5)); + tbh = 0.f; + CursorInit(); + main_area = view_area; this->flags = flags; this->scrolling[0] = flags & UI7MenuFlags_HzScrolling; this->scrolling[1] = flags & UI7MenuFlags_VtScrolling; @@ -173,7 +174,8 @@ void UI7::Menu::PreHandler(UI7MenuFlags flags) { } front->AddText(tpos, this->name, linked_theme->Get(UI7Color_Text), tflags, vec2(view_area.z(), tbh)); - Cursor(vec2(5, tbh + 5)); + main_area[1] = tbh; + CursorInit(); } } @@ -229,8 +231,7 @@ void UI7::Menu::PostHandler() { mouse = vec2(); } if (inp->IsHeld(inp->Touch)) { - if (!front->ren->InBox(tpos, vec4(view_area[2] - 13, tbh + 5, 8, - view_area[3] - tbh - 10))) { + if (front->ren->InBox(tpos, main_area)) { if (scrolling_off[1] < max[1] - view_area[3] + 40 && scrolling_off[1] > -40) { /// Cursor Mod diff --git a/source/ui7/ui7.cpp b/source/ui7/ui7.cpp index 72f646c..324224c 100644 --- a/source/ui7/ui7.cpp +++ b/source/ui7/ui7.cpp @@ -37,12 +37,15 @@ bool UI7::Context::BeginMenu(const ID& id, UI7MenuFlags flags) { this->current = menu->second; if (!this->current->BackList()) { this->current->BackList(DrawList::New(ren)); + this->current->BackList()->BaseLayer(root_layer + 30); } if (!this->current->MainList()) { this->current->MainList(DrawList::New(ren)); + this->current->MainList()->BaseLayer(root_layer + 40); } if (!this->current->FrontList()) { this->current->FrontList(DrawList::New(ren)); + this->current->FrontList()->BaseLayer(root_layer + 50); } this->current->ViewArea(this->ren->GetViewport()); this->current->PreHandler(flags); @@ -63,12 +66,12 @@ void UI7::Context::EndMenu() { void UI7::Context::Update(float delta) { TT::Scope st("UI7_Update"); Assert(current == nullptr, "Still in a Menu!"); - this->back->BaseLayer(10); + this->back->BaseLayer(root_layer + 10); this->back->Process(); for (auto it : amenus) { menus[it]->Update(delta); } - this->front->BaseLayer(60); + this->front->BaseLayer(root_layer + 60); this->front->Process(); this->amenus.clear(); } diff --git a/test/app/main.cpp b/test/app/main.cpp index c2ead3b..3c96783 100644 --- a/test/app/main.cpp +++ b/test/app/main.cpp @@ -29,7 +29,12 @@ SOFTWARE. class Test : public PD::App { public: - Test() = default; + Test() { + /* + Here can be things modified befor Init anything + cause This place gets called befor Internal Init + */ + } ~Test() = default; void Init() override { @@ -82,6 +87,11 @@ class Test : public PD::App { if (m->Button("Button?")) { Messages()->Push("Button", "Pressed..."); } + m->SameLine(); + if (m->Button("Palladium")) { + this->FeatureDisable(AppFLags_UserLoop); + Overlays()->Push(PD::New(this)); + } m->SeparatorText("SeparatorText"); m->Checkbox("Test", cbtest); ui7->EndMenu();