From f87c103d8d165db80b5b5ea1d8aec272425547db Mon Sep 17 00:00:00 2001 From: tobid7 Date: Sun, 2 Feb 2025 20:32:07 +0100 Subject: [PATCH] # Stage 1.8 - Renderer now vould use more screen Objects - Register default Top and Bottom Screens (for Overlays and UI7) - Make ToHex an Inline header func - Add GetCompilerVersion - Add Library Compile And Version Info to common - Remove z of vertex object and shader in position - Add Container base and SubContainers to UI7 - Add abillity to Join Multiple Objects in Same Line and Center them - Fix LayerOrder Bug for updating texts in DrawList --- CMakeLists.txt | 18 ++- include/pd/common/app.hpp | 4 + include/pd/common/common.hpp | 8 ++ include/pd/common/strings.hpp | 25 +++- include/pd/graphics/lithium.hpp | 60 ++++----- include/pd/graphics/screen.hpp | 5 +- include/pd/ui7/container/button.hpp | 30 +++++ include/pd/ui7/container/checkbox.hpp | 32 +++++ include/pd/ui7/container/container.hpp | 54 ++++++++ include/pd/ui7/container/image.hpp | 27 ++++ include/pd/ui7/container/label.hpp | 27 ++++ include/pd/ui7/containers.hpp | 6 + include/pd/ui7/menu.hpp | 14 ++ shaders/li7_shader.v.pica | 4 +- source/common/app.cpp | 12 +- source/common/common.cpp | 13 +- source/common/strings.cpp | 7 - source/graphics/li7_shader.cpp | 2 +- source/graphics/lithium.cpp | 148 +++++++++----------- source/overlays/keyboard.cpp | 4 +- source/overlays/message_mgr.cpp | 2 +- source/overlays/performance.cpp | 2 +- source/ui7/container/button.cpp | 36 +++++ source/ui7/container/checkbox.cpp | 38 ++++++ source/ui7/container/container.cpp | 12 ++ source/ui7/container/image.cpp | 13 ++ source/ui7/container/label.cpp | 12 ++ source/ui7/drawlist.cpp | 31 +++-- source/ui7/menu.cpp | 179 +++++++++++++------------ source/ui7/theme.cpp | 2 +- test/app/main.cpp | 77 ++++------- test/bench/main.cpp | 8 +- 32 files changed, 619 insertions(+), 293 deletions(-) create mode 100644 include/pd/ui7/container/button.hpp create mode 100644 include/pd/ui7/container/checkbox.hpp create mode 100644 include/pd/ui7/container/container.hpp create mode 100644 include/pd/ui7/container/image.hpp create mode 100644 include/pd/ui7/container/label.hpp create mode 100644 include/pd/ui7/containers.hpp create mode 100644 source/ui7/container/button.cpp create mode 100644 source/ui7/container/checkbox.cpp create mode 100644 source/ui7/container/container.cpp create mode 100644 source/ui7/container/image.cpp create mode 100644 source/ui7/container/label.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b734d6e..74ef482 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,15 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) endif() endif() +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_SHORT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + # Set Project -project(palladium LANGUAGES C CXX VERSION 1.0.0) +project(palladium LANGUAGES C CXX VERSION 0.1.8) # Enable Compile Command Export set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -27,6 +34,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -fno-rtti -fno-exceptio set(SRC_FILES # Core (common) source/common/app.cpp + source/common/common.cpp source/common/strings.cpp source/common/timetrace.cpp source/common/sys.cpp @@ -56,6 +64,11 @@ set(SRC_FILES source/ui7/menu.cpp source/ui7/theme.cpp source/ui7/ui7.cpp + source/ui7/container/container.cpp + source/ui7/container/button.cpp + source/ui7/container/checkbox.cpp + source/ui7/container/image.cpp + source/ui7/container/label.cpp # External source/external/stb.cpp ) @@ -72,7 +85,8 @@ target_include_directories(${TARGET_NAME} PUBLIC ) target_compile_definitions(${TARGET_NAME} PUBLIC -D_GNU_SOURCE=1 - -DVERSION="${PROJECT_VERSION}" + -DPALLADIUM_VERSION="${PROJECT_VERSION}" + -DPALLADIUM_GIT_COMMIT="${GIT_SHORT_HASH}" -DBUILD_CTR=1 ) diff --git a/include/pd/common/app.hpp b/include/pd/common/app.hpp index f50f841..f8695b0 100644 --- a/include/pd/common/app.hpp +++ b/include/pd/common/app.hpp @@ -66,6 +66,10 @@ class App { Hid::Ref Input() { return input_mgr; } float GetFps() const { return fps; } + protected: + Screen::Ref Top; + Screen::Ref Bottom; + private: void PreInit(); void PostDeinit(); diff --git a/include/pd/common/common.hpp b/include/pd/common/common.hpp index 5de161c..8adff7e 100644 --- a/include/pd/common/common.hpp +++ b/include/pd/common/common.hpp @@ -69,4 +69,12 @@ using u64 = unsigned long long; using u32 = unsigned int; using u16 = unsigned short; using u8 = unsigned char; + +namespace LibInfo { +const std::string CompiledWith(); +const std::string CxxVersion(); +const std::string BuildTime(); +const std::string Version(); +const std::string Commit(); +} // namespace LibInfo } // namespace PD \ No newline at end of file diff --git a/include/pd/common/strings.hpp b/include/pd/common/strings.hpp index db66d14..62bfb49 100644 --- a/include/pd/common/strings.hpp +++ b/include/pd/common/strings.hpp @@ -37,7 +37,30 @@ const std::string GetFileName(const std::string& path, const std::string& saperators = "/\\"); const std::string PathRemoveExtension(const std::string& path); template -const std::string ToHex(const T& v); +inline const std::string ToHex(const T& v) { + std::stringstream s; + s << "0x" << std::setfill('0') << std::setw(sizeof(v) * 2) << std::hex << v; + return s.str(); +} u32 FastHash(const std::string& s); +inline const std::string GetCompilerVersion() { + /// As the function looks like this Project is meant to + /// Be ported to other systems as well + std::stringstream res; +#ifdef __GNUC__ + res << "GCC: " << __GNUC__; + res << "." << __GNUC_MINOR__ << "."; + res << __GNUC_PATCHLEVEL__; +#elif __clang__ + res << "Clang: " << __clang_major__ << "."; + res << __clang_minor__ << "."; + res << __clang_patchlevel__; +#elif _MSC_VER + res << "MSVC: " << _MSC_VER; +#else + res << "Unknown Compiler"; +#endif + return res.str(); +} } // namespace Strings } // namespace PD \ No newline at end of file diff --git a/include/pd/graphics/lithium.hpp b/include/pd/graphics/lithium.hpp index 8747868..6ad3639 100644 --- a/include/pd/graphics/lithium.hpp +++ b/include/pd/graphics/lithium.hpp @@ -113,21 +113,13 @@ class Vertex { Vertex(const vec2& p, const vec2& u, u32 c) { pos[0] = p[0]; pos[1] = p[1]; - pos[2] = 0.f; uv = u; color = c; } ~Vertex() {} - Vertex& Pos(const vec3& v) { - pos = v; - return *this; - } - // Lets support that as well Vertex& Pos(const vec2& v) { - pos[0] = v[0]; - pos[1] = v[1]; - pos[2] = 0.f; + pos = v; return *this; } Vertex& Uv(const vec2& v) { @@ -140,7 +132,7 @@ class Vertex { } // private: - vec3 pos; + vec2 pos; vec2 uv; u32 color; }; @@ -270,7 +262,7 @@ class StaticObject : public SmartCtor { void MoveIt(vec2 off) { for (auto& it : cpy) { for (auto& jt : it->VertexList()) { - jt.pos += vec3(off, 0); + jt.pos += off; } } } @@ -354,27 +346,24 @@ class Renderer : public SmartCtor { StaticObject::Ref text; }; - void Render(); + void PrepareRender(); + void Render(Screen::Ref s); + void FinalizeRender(); - void OnScreen(Screen::Screen_ screen) { - if (screen == Screen::Top) { - bottom = false; - area_size = top->GetSize(); - } else if (screen == Screen::Bottom) { - bottom = true; - area_size = bot->GetSize(); - } else { + void RegisterScreen(bool bottom, Screen::Ref s) { screens[bottom] = s; } + void OnScreen(Screen::Ref s) { + if (!s) { return; } + this->screen = s; + area_size = screen->GetSize(); } - void OnScreen(bool bottom) { - bottom = bottom; - area_size = bottom ? bot->GetSize() : top->GetSize(); - } - - Screen::Screen_ CurrentScreen() const { - return bottom ? Screen::Bottom : Screen::Top; + Screen::Ref CurrentScreen() const { return screen; } + Screen::Ref GetScreen(bool bottom) { + auto res = screens[bottom]; + Assert(res.get(), "Screen is not registered!"); + return res; } void Rotation(float v) { rot = v; } @@ -458,13 +447,17 @@ class Renderer : public SmartCtor { static bool InBox(const vec2& pos, const vec4& rect); static bool InBox(const vec2& alpha, const vec2& bravo, const vec2& charlie, const vec4& rect); + /// @brief Get The Address of a Screen + /// @note IMPORTANT: THIS IS FOR 32Bit System + /// Should find a better way to do this for porting this lib + static u32 Screen32(Screen::Ref s) { return (u32)s.get(); } static void OptiCommandList(std::vector& list); /// @brief Returns Viewport with xy vec4 GetViewport(); /// @brief Push a Self Created command void PushCommand(Command::Ref cmd) { cmd->Index(cmd_idx++); // Indexing - draw_list[bottom].push_back(cmd); + draw_list[Screen32(screen)].push_back(cmd); } /// @brief Automatically sets up a command void SetupCommand(Command::Ref cmd); @@ -487,17 +480,16 @@ class Renderer : public SmartCtor { private: /// Helper Funcitons /// - void RenderOn(bool bottom); void UpdateRenderMode(const RenderMode& mode); - /// @brief Screens /// - Screen::Ref top; - Screen::Ref bot; + /// One Screen Only... /// + Screen::Ref screen; + /// Reference Screens /// + Screen::Ref screens[2]; /// Context Related /// RenderFlags flags = RenderFlags_Default; vec2 area_size; - bool bottom = false; int current_layer = 0; Texture::Ref current_tex = nullptr; Texture::Ref white = nullptr; // Single color @@ -516,7 +508,7 @@ class Renderer : public SmartCtor { float rot = 0.f; /// Rendering /// // Use dual drawlist - std::vector draw_list[2]; + std::unordered_map> draw_list; std::vector> vertex_buf; std::vector> index_buf; u32 vertex_idx = 0; diff --git a/include/pd/graphics/screen.hpp b/include/pd/graphics/screen.hpp index 489e8f4..c249c85 100644 --- a/include/pd/graphics/screen.hpp +++ b/include/pd/graphics/screen.hpp @@ -33,7 +33,7 @@ namespace PD { class Screen : public SmartCtor { public: enum Screen_ { Top, Bottom, TopRight }; - Screen(Screen_ screen) { + Screen(Screen_ screen) : type(screen) { if (screen == Top) { target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); @@ -60,10 +60,13 @@ class Screen : public SmartCtor { return vec2(target->frameBuf.height, target->frameBuf.width); } + Screen_ ScreenType() const { return type; } + C3D_RenderTarget* Get() const { return target; } operator C3D_RenderTarget*() const { return target; } private: + Screen_ type; const u32 DisplayTransferFlags = (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | diff --git a/include/pd/ui7/container/button.hpp b/include/pd/ui7/container/button.hpp new file mode 100644 index 0000000..8515113 --- /dev/null +++ b/include/pd/ui7/container/button.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +namespace PD { +namespace UI7 { +class Button : public Container { + public: + Button(const std::string& label, vec2 pos, LI::Renderer::Ref lr) { + this->screen = lr->CurrentScreen(); + this->label = label; + this->SetPos(pos); + this->tdim = lr->GetTextDimensions(label); + color = UI7Color_Button; + this->SetSize(tdim + vec2(8, 4)); + } + ~Button() {} + + bool IsPressed() { return pressed; } + void HandleInput(Hid::Ref inp) override; + void Draw() override; + + private: + vec2 tdim; + UI7Color color; + std::string label; + bool pressed = false; +}; +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/container/checkbox.hpp b/include/pd/ui7/container/checkbox.hpp new file mode 100644 index 0000000..85674fb --- /dev/null +++ b/include/pd/ui7/container/checkbox.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include + +namespace PD { +namespace UI7 { +class Checkbox : public Container { + public: + Checkbox(const std::string& label, vec2 pos, bool& usr_ref, + LI::Renderer::Ref lr) + : usr_ref(usr_ref) { + this->screen = lr->CurrentScreen(); + this->label = label; + this->SetPos(pos); + this->tdim = lr->GetTextDimensions(label); + color = UI7Color_FrameBackground; + this->SetSize(cbs + vec2(tdim.x() + 5, 0)); + } + ~Checkbox() {} + + void HandleInput(Hid::Ref inp) override; + void Draw() override; + + private: + vec2 tdim; + vec2 cbs = vec2(18); + UI7Color color; + std::string label; + bool& usr_ref; +}; +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/container/container.hpp b/include/pd/ui7/container/container.hpp new file mode 100644 index 0000000..b8ad57a --- /dev/null +++ b/include/pd/ui7/container/container.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace PD { +namespace UI7 { +class Container : public SmartCtor { + public: + Container() {} + Container(const vec2& pos, const vec2& size) : pos(pos), size(size) {} + Container(const vec4& box) : pos(box.xy()), size(box.zw()) {} + ~Container() {} + + void Init(LI::Renderer::Ref r, UI7::DrawList::Ref l, UI7::Theme* lt) { + list = l; + linked_theme = lt; + ren = r; + } + + void SetPos(const vec2& pos) { this->pos = pos; } + void SetSize(const vec2& size) { this->size = size; } + + vec2 GetPos() { return pos; } + vec2 GetSize() { return size; } + + bool Skippable() const { return skippable; } + + void HandleScrolling(vec2 scrolling, vec4 viewport); + virtual void HandleInput(Hid::Ref inp) {} + virtual void Draw() {} + + void UnlockInput() { inp_done = false; } + + u32 GetID() const { return id; } + void SetID(u32 id) { this->id = id; } + + protected: + /// used to skip Input/Render preocessing ot not + bool skippable = false; + bool inp_done = false; + Screen::Ref screen; + vec2 pos; + vec2 size; + UI7::DrawList::Ref list; + UI7::Theme* linked_theme; + LI::Renderer::Ref ren; + u32 id = 0; +}; +} // namespace UI7 +} // namespace PD diff --git a/include/pd/ui7/container/image.hpp b/include/pd/ui7/container/image.hpp new file mode 100644 index 0000000..0bba441 --- /dev/null +++ b/include/pd/ui7/container/image.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace PD { +namespace UI7 { +class Image : public Container { + public: + Image(Texture::Ref img, vec2 pos, LI::Renderer::Ref lr, vec2 size = 0.f) { + this->screen = lr->CurrentScreen(); + this->img = img; + this->SetPos(pos); + if (size.x() != 0 || size.y() != 0) { + this->SetSize(size); + } else { + this->SetSize(img->GetSize()); + } + } + ~Image() {} + + void Draw() override; + + private: + Texture::Ref img; +}; +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/container/label.hpp b/include/pd/ui7/container/label.hpp new file mode 100644 index 0000000..15283b7 --- /dev/null +++ b/include/pd/ui7/container/label.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace PD { +namespace UI7 { +class Label : public Container { + public: + Label(const std::string& label, vec2 pos, LI::Renderer::Ref lr) { + this->screen = lr->CurrentScreen(); + this->label = label; + this->SetPos(pos); + this->tdim = lr->GetTextDimensions(label); + color = UI7Color_Text; + this->SetSize(tdim); + } + ~Label() {} + + void Draw() override; + + private: + vec2 tdim; + UI7Color color; + std::string label; +}; +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/include/pd/ui7/containers.hpp b/include/pd/ui7/containers.hpp new file mode 100644 index 0000000..135a69d --- /dev/null +++ b/include/pd/ui7/containers.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include +#include +#include +#include diff --git a/include/pd/ui7/menu.hpp b/include/pd/ui7/menu.hpp index 203d550..84d3b98 100644 --- a/include/pd/ui7/menu.hpp +++ b/include/pd/ui7/menu.hpp @@ -24,6 +24,7 @@ SOFTWARE. */ #include +#include #include #include #include @@ -56,6 +57,10 @@ class Menu : public SmartCtor { void SameLine(); void Separator(); void SeparatorText(const std::string& label); + void Join(); + /// @brief Horizontal Center Joined objects + void JoinOpHzCenter(); + void AfterAlignCenter(); /// API for Custom Objects bool HandleScrolling(vec2& pos, const vec2& size); @@ -106,6 +111,10 @@ class Menu : public SmartCtor { /// 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; @@ -127,6 +136,11 @@ class Menu : public SmartCtor { Menu::Ref submenu; + /// Objects API + std::vector objects; + std::vector idobjs; + std::vector join; + // DrawLists DrawList::Ref back; DrawList::Ref main; diff --git a/shaders/li7_shader.v.pica b/shaders/li7_shader.v.pica index cf5e218..881405c 100644 --- a/shaders/li7_shader.v.pica +++ b/shaders/li7_shader.v.pica @@ -12,13 +12,13 @@ .out out_uv texcoord0 ; Inputs -.alias in_xyz v0 +.alias in_xy v0 .alias in_uvc v1 .alias in_col v2 .entry vmain .proc vmain - mov r0.xyz, in_xyz.xyz + mov r0.xy, in_xy.xy mov r0.w, ones dp4 out_position.x, projection[0], r0 diff --git a/source/common/app.cpp b/source/common/app.cpp index 0f7cfdd..781f086 100644 --- a/source/common/app.cpp +++ b/source/common/app.cpp @@ -53,7 +53,10 @@ void App::Run() { renderer->Layer(93); msg_mgr->Update(dt); PD::TT::End("Ovl_Update"); - renderer->Render(); + renderer->PrepareRender(); + renderer->Render(Top); + renderer->Render(Bottom); + renderer->FinalizeRender(); } this->Deinit(); this->PostDeinit(); @@ -64,8 +67,14 @@ void App::PreInit() { gfxInitDefault(); cfguInit(); romfsInit(); + C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); 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); } @@ -75,6 +84,7 @@ void App::PostDeinit() { msg_mgr = nullptr; overlay_mgr = nullptr; input_mgr = nullptr; + C3D_Fini(); gfxExit(); cfguExit(); romfsExit(); diff --git a/source/common/common.cpp b/source/common/common.cpp index 5057a6a..6e9c623 100644 --- a/source/common/common.cpp +++ b/source/common/common.cpp @@ -23,10 +23,21 @@ SOFTWARE. */ #include +#include #ifndef PALLADIUM_VERSION #define PALLADIUM_VERSION "unknown" #endif #ifndef PALLADIUM_GIT_COMMIT #define PALLADIUM_GIT_COMMIT "unknown" -#endif \ No newline at end of file +#endif + +const std::string PD::LibInfo::CompiledWith() { + return Strings::GetCompilerVersion(); +} +const std::string PD::LibInfo::CxxVersion() { + return "CPP: " + std::to_string(__cplusplus); +} +const std::string PD::LibInfo::BuildTime() { return __DATE__ " - " __TIME__; } +const std::string PD::LibInfo::Version() { return PALLADIUM_VERSION; } +const std::string PD::LibInfo::Commit() { return PALLADIUM_GIT_COMMIT; } \ No newline at end of file diff --git a/source/common/strings.cpp b/source/common/strings.cpp index 7af85bb..ca9ffd9 100644 --- a/source/common/strings.cpp +++ b/source/common/strings.cpp @@ -121,13 +121,6 @@ const std::string PathRemoveExtension(const std::string& path) { return path; } -template -const std::string ToHex(const T& v) { - std::stringstream s; - s << "0x" << std::setfill('0') << std::setw(sizeof(v) * 2) << std::hex << v; - return s.str(); -} - u32 FastHash(const std::string& s) { u32 hash = 5381; for (auto& it : s) { diff --git a/source/graphics/li7_shader.cpp b/source/graphics/li7_shader.cpp index e9a1174..86f07b5 100644 --- a/source/graphics/li7_shader.cpp +++ b/source/graphics/li7_shader.cpp @@ -28,7 +28,7 @@ SOFTWARE. // clang-format off unsigned char li7_shader[] = { -0x44, 0x56, 0x4c, 0x42, 0x1, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x50, 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x1, 0xf0, 0x7, 0x4e, 0x2, 0x8, 0x2, 0x8, 0x3, 0x18, 0x2, 0x8, 0x4, 0x28, 0x2, 0x8, 0x5, 0x38, 0x2, 0x8, 0x6, 0x10, 0x40, 0x4c, 0x7, 0xf1, 0x27, 0x22, 0x8, 0x10, 0x21, 0x4c, 0x0, 0x0, 0x0, 0x88, 0x4e, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xd5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x45, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x1, 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x13, 0x0, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x0, +0x44, 0x56, 0x4c, 0x42, 0x1, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x50, 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x1, 0xf0, 0x7, 0x4e, 0x2, 0x8, 0x2, 0x8, 0x3, 0x18, 0x2, 0x8, 0x4, 0x28, 0x2, 0x8, 0x5, 0x38, 0x2, 0x8, 0x6, 0x10, 0x40, 0x4c, 0x7, 0xf1, 0x27, 0x22, 0x8, 0x10, 0x21, 0x4c, 0x0, 0x0, 0x0, 0x88, 0xac, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xd5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x45, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x1, 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x13, 0x0, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x0, }; // clang-format on size_t li7_shader_size = 0x124; \ No newline at end of file diff --git a/source/graphics/lithium.cpp b/source/graphics/lithium.cpp index 90be6d4..a2a28cb 100644 --- a/source/graphics/lithium.cpp +++ b/source/graphics/lithium.cpp @@ -220,12 +220,6 @@ void Font::LoadSystemFont() { } Renderer::Renderer(RenderFlags flags) { - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - top = Screen::New(Screen::Top); - bot = Screen::New(Screen::Bottom); - top->Clear(); - bot->Clear(); - vertex_buf.resize(4 * 4096, Vertex()); index_buf.resize(6 * 4096, 0); @@ -237,7 +231,7 @@ Renderer::Renderer(RenderFlags flags) { shaderInstanceGetUniformLocation(shader.vertexShader, "projection"); AttrInfo_Init(&attr); - AttrInfo_AddLoader(&attr, 0, GPU_FLOAT, 3); + AttrInfo_AddLoader(&attr, 0, GPU_FLOAT, 2); AttrInfo_AddLoader(&attr, 1, GPU_FLOAT, 2); AttrInfo_AddLoader(&attr, 2, GPU_UNSIGNED_BYTE, 4); @@ -252,13 +246,10 @@ Renderer::Renderer(RenderFlags flags) { // Not Loading as Systemfont is freezing // font = Font::New(); // font->LoadSystemFont(); - - area_size = top->GetSize(); } Renderer::~Renderer() { shaderProgramFree(&shader); DVLB_Free(dvlb); - C3D_Fini(); } void Renderer::StaticText::Setup(Renderer* ren, const vec2& pos, u32 clr, @@ -475,10 +466,7 @@ void Renderer::TextCommand(std::vector& cmds, const vec2& pos, } } -vec4 Renderer::GetViewport() { - auto screen = bottom ? bot->GetSize() : top->GetSize(); - return vec4(0, 0, screen[0], screen[1]); -} +vec4 Renderer::GetViewport() { return vec4(vec2(), screen->GetSize()); } vec2 Renderer::GetTextDimensions(const std::string& text) { if (!font) { @@ -564,16 +552,68 @@ void Renderer::UpdateRenderMode(const RenderMode& mode) { } } -void Renderer::RenderOn(bool bot) { +void Renderer::PrepareRender() { + if (font_update) { + tms.clear(); + font_update = false; + } + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + TT::Beg("LI_RenderAll"); + vertex_idx = 0; + index_idx = 0; + vertices = 0; + indices = 0; + commands = 0; + drawcalls = 0; + C3D_BindProgram(&shader); + C3D_SetAttrInfo(&attr); +} + +void Renderer::FinalizeRender() { + C3D_FrameEnd(0); + TT::End("LI_RenderAll"); + current_layer = 0; + cmd_idx = 0; + rot = 0.f; + UseTex(); + if (flags & RenderFlags_TMS) { + std::vector rem; + for (auto& it : tms) { + if (Sys::GetTime() - it.second.TimeCreated() > 5) rem.push_back(it.first); + } + for (auto it : rem) tms.erase(it); + } else { + tms.clear(); + } + if (flags & RenderFlags_AST) { + std::vector rem; + for (auto it : ast) { + if (!it.second->Used()) { + rem.push_back(it.first); + } + it.second->SetUnused(); + } + for (auto& it : rem) { + ast.erase(it); + } + } else { + ast.clear(); + } +} + +void Renderer::Render(Screen::Ref s) { + Assert(s.get(), "Expected Screen Address but got nullptr!"); + s->Clear(); + s->Use(); + bool bot = s->ScreenType() == Screen::Bottom; C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, (bot ? &bot_proj : &top_proj)); C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); UpdateRenderMode(RenderMode_RGBA); int total_vertices = 0; int total_indices = 0; - drawcalls = 0; - auto& cmds = draw_list[bot]; - commands = cmds.size(); + auto& cmds = draw_list[Screen32(s)]; + commands += cmds.size(); size_t index = 0; if (flags & RenderFlags_LRS) { OptiCommandList(cmds); @@ -613,66 +653,8 @@ void Renderer::RenderOn(bool bot) { } cmds.clear(); C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); - vertices = total_vertices; - indices = total_indices; -} - -void Renderer::Render() { - if (font_update) { - tms.clear(); - font_update = false; - } - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - TT::Beg("LI_RenderAll"); - top->Clear(); - bot->Clear(); - vertex_idx = 0; - index_idx = 0; - C3D_BindProgram(&shader); - C3D_SetAttrInfo(&attr); - top->Use(); - RenderOn(false); - int dtc = commands; - int dtd = drawcalls; - int dtv = vertices; - int dti = indices; - bot->Use(); - RenderOn(true); - TT::End("LI_RenderAll"); - C3D_FrameEnd(0); - commands += dtc; - drawcalls += dtd; - vertices += dtv; - indices += dti; - current_layer = 0; - cmd_idx = 0; - area_size = top->GetSize(); - bottom = false; - rot = 0.f; - UseTex(); - if (flags & RenderFlags_TMS) { - std::vector rem; - for (auto& it : tms) { - if (Sys::GetTime() - it.second.TimeCreated() > 5) rem.push_back(it.first); - } - for (auto it : rem) tms.erase(it); - } else { - tms.clear(); - } - if (flags & RenderFlags_AST) { - std::vector rem; - for (auto it : ast) { - if (!it.second->Used()) { - rem.push_back(it.first); - } - it.second->SetUnused(); - } - for (auto& it : rem) { - ast.erase(it); - } - } else { - ast.clear(); - } + vertices += total_vertices; + indices += total_indices; } void Renderer::DrawRect(const vec2& pos, const vec2& size, u32 color, @@ -685,7 +667,7 @@ void Renderer::DrawRect(const vec2& pos, const vec2& size, u32 color, auto cmd = Command::New(); SetupCommand(cmd); QuadCommand(cmd, rec, uv, color); - draw_list[bottom].push_back(cmd); + draw_list[Screen32(screen)].push_back(cmd); } void Renderer::DrawRectSolid(const vec2& pos, const vec2& size, u32 color) { @@ -702,7 +684,7 @@ void Renderer::DrawTriangle(const vec2& a, const vec2& b, const vec2& c, auto cmd = Command::New(); SetupCommand(cmd); TriangleCommand(cmd, a, b, c, color); - draw_list[bottom].push_back(cmd); + draw_list[Screen32(screen)].push_back(cmd); } void Renderer::DrawCircle(const vec2& center_pos, float r, u32 color, @@ -725,7 +707,7 @@ void Renderer::DrawCircle(const vec2& center_pos, float r, u32 color, vec2(x, y), vec2((std::cos(a) + 1.f) / 2.f, (std::sin(a) + 1.f) / 2.f), color)); } - draw_list[bottom].push_back(cmd); + draw_list[Screen32(screen)].push_back(cmd); } void Renderer::DrawLine(const vec2& a, const vec2& b, u32 color, int t) { @@ -735,7 +717,7 @@ void Renderer::DrawLine(const vec2& a, const vec2& b, u32 color, int t) { auto cmd = Command::New(); SetupCommand(cmd); QuadCommand(cmd, line, vec4(0.f, 1.f, 1.f, 0.f), color); - draw_list[bottom].push_back(cmd); + draw_list[Screen32(screen)].push_back(cmd); } void Renderer::DrawImage(const vec2& pos, Texture::Ref tex, const vec2& scale) { @@ -760,7 +742,7 @@ void Renderer::DrawText(const vec2& pos, u32 color, const std::string& text, e->second->Draw(); return; } - TextCommand(draw_list[bottom], pos, color, text, flags, ap); + TextCommand(draw_list[Screen32(screen)], pos, color, text, flags, ap); } } // namespace PD::LI \ No newline at end of file diff --git a/source/overlays/keyboard.cpp b/source/overlays/keyboard.cpp index 167eca2..c7c6e7a 100644 --- a/source/overlays/keyboard.cpp +++ b/source/overlays/keyboard.cpp @@ -497,11 +497,11 @@ void Keyboard::Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) { fade.a(fade.a() * flymgr.Progress()); } if (flags & Flags_BlendTop) { - ren->OnScreen(Screen::Top); + ren->OnScreen(ren->GetScreen(false)); ren->DrawRectSolid(0, vec2(400, 240), fade); } if (flags & Flags_BlendBottom) { - ren->OnScreen(Screen::Bottom); + ren->OnScreen(ren->GetScreen(true)); ren->DrawRectSolid(0, vec2(320, 240), fade); } } diff --git a/source/overlays/message_mgr.cpp b/source/overlays/message_mgr.cpp index a9b3949..57e1748 100644 --- a/source/overlays/message_mgr.cpp +++ b/source/overlays/message_mgr.cpp @@ -104,7 +104,7 @@ void MessageMgr::Push(const std::string& title, const std::string& text) { } void MessageMgr::Update(float delta) { - ren->OnScreen(Screen::Top); + ren->OnScreen(ren->GetScreen(false)); for (size_t i = 0; i < msgs.size(); i++) { // Update the Animation Handlers and Move older // Messages up if a new one got pushed diff --git a/source/overlays/performance.cpp b/source/overlays/performance.cpp index 7a794d2..e090ba9 100644 --- a/source/overlays/performance.cpp +++ b/source/overlays/performance.cpp @@ -9,7 +9,7 @@ void Performance::Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) { if (*skill) { Kill(); } - ren->OnScreen(Screen::Top); + ren->OnScreen(ren->GetScreen(false)); ren->TextScale(0.6); vec2 pos; Line(pos, std::format("{:.1f} FPS / {:.2f}ms", 1000.f / delta, delta), ren); diff --git a/source/ui7/container/button.cpp b/source/ui7/container/button.cpp new file mode 100644 index 0000000..6d3f8d8 --- /dev/null +++ b/source/ui7/container/button.cpp @@ -0,0 +1,36 @@ +#include + +namespace PD { +namespace UI7 { +void Button::HandleInput(Hid::Ref inp) { + /// Ensure to only check input once + if (inp_done) { + return; + } + /// Ensure it gets sed to false and stays if not pressed + pressed = false; + color = UI7Color_Button; + Assert(screen.get(), "Screen is not set up!"); + if (screen->ScreenType() == Screen::Bottom) { + if (inp->IsHeld(inp->Touch) && + LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { + color = UI7Color_ButtonHovered; + } + if (inp->IsUp(inp->Touch) && + LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { + color = UI7Color_ButtonActive; + pressed = true; + } + } + inp_done = true; +} +void Button::Draw() { + Assert(ren.get() && list.get() && linked_theme, + "Did you run Container::Init correctly?"); + ren->OnScreen(screen); + list->AddRectangle(pos, size, linked_theme->Get(color)); + list->AddText(pos + size * 0.5 - tdim * 0.5, label, + linked_theme->Get(UI7Color_Text)); +} +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/source/ui7/container/checkbox.cpp b/source/ui7/container/checkbox.cpp new file mode 100644 index 0000000..49a019a --- /dev/null +++ b/source/ui7/container/checkbox.cpp @@ -0,0 +1,38 @@ +#include + +namespace PD { +namespace UI7 { +void Checkbox::HandleInput(Hid::Ref inp) { + /// Ensure to only check input once + if (inp_done) { + return; + } + color = UI7Color_FrameBackground; + /// Ensure it gets sed to false and stays if not pressed + Assert(screen.get(), "Screen is not set up!"); + if (screen->ScreenType() == Screen::Bottom) { + if (inp->IsHeld(inp->Touch) && + LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { + color = UI7Color_FrameBackgroundHovered; + } + if (inp->IsUp(inp->Touch) && + LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { + color = UI7Color_FrameBackgroundHovered; + usr_ref = !usr_ref; + } + } + inp_done = true; +} +void Checkbox::Draw() { + Assert(ren.get() && list.get() && linked_theme, + "Did you run Container::Init correctly?"); + ren->OnScreen(screen); + list->AddRectangle(pos, cbs, linked_theme->Get(color)); + if (usr_ref) { + list->AddRectangle(pos + 2, cbs - 4, linked_theme->Get(UI7Color_Checkmark)); + } + list->AddText(pos + vec2(cbs.x() + 5, cbs.y() * 0.5 - tdim.y() * 0.5), label, + linked_theme->Get(UI7Color_Text)); +} +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/source/ui7/container/container.cpp b/source/ui7/container/container.cpp new file mode 100644 index 0000000..14bffad --- /dev/null +++ b/source/ui7/container/container.cpp @@ -0,0 +1,12 @@ +#include + +namespace PD { +namespace UI7 { +void Container::HandleScrolling(vec2 scrolling, vec4 viewport) { + pos -= vec2(0, scrolling.y()); + if (!LI::Renderer::InBox(pos, size, viewport)) { + skippable = true; + } +} +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/source/ui7/container/image.cpp b/source/ui7/container/image.cpp new file mode 100644 index 0000000..af9e1fa --- /dev/null +++ b/source/ui7/container/image.cpp @@ -0,0 +1,13 @@ +#include + +namespace PD { +namespace UI7 { +void Image::Draw() { + Assert(ren.get() && list.get() && linked_theme, + "Did you run Container::Init correctly?"); + Assert(img.get(), "Image is nullptr!"); + ren->OnScreen(screen); + list->AddImage(pos, img); +} +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/source/ui7/container/label.cpp b/source/ui7/container/label.cpp new file mode 100644 index 0000000..a744c0d --- /dev/null +++ b/source/ui7/container/label.cpp @@ -0,0 +1,12 @@ +#include + +namespace PD { +namespace UI7 { +void Label::Draw() { + Assert(ren.get() && list.get() && linked_theme, + "Did you run Container::Init correctly?"); + ren->OnScreen(screen); + list->AddText(pos, label, linked_theme->Get(UI7Color_Text)); +} +} // namespace UI7 +} // namespace PD \ No newline at end of file diff --git a/source/ui7/drawlist.cpp b/source/ui7/drawlist.cpp index 87bc9a6..26623bd 100644 --- a/source/ui7/drawlist.cpp +++ b/source/ui7/drawlist.cpp @@ -34,10 +34,10 @@ void DrawList::AddRectangle(vec2 pos, vec2 szs, const UI7Color& clr) { auto cmd = LI::Command::New(); ren->UseTex(); ren->SetupCommand(cmd); - cmd->Layer(layer); + cmd->Layer(base + layer); ren->QuadCommand(cmd, rect, vec4(0.f, 1.f, 1.f, 0.f), clr); - commands.push_back( - std::make_pair(ren->CurrentScreen() == Screen::Bottom, cmd)); + commands.push_back(std::make_pair( + ren->CurrentScreen()->ScreenType() == Screen::Bottom, cmd)); } void DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2, @@ -48,10 +48,10 @@ void DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2, auto cmd = LI::Command::New(); ren->UseTex(); ren->SetupCommand(cmd); - cmd->Layer(layer); + cmd->Layer(base + layer); ren->TriangleCommand(cmd, pos0, pos1, pos2, clr); - commands.push_back( - std::make_pair(ren->CurrentScreen() == Screen::Bottom, cmd)); + commands.push_back(std::make_pair( + ren->CurrentScreen()->ScreenType() == Screen::Bottom, cmd)); } void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, @@ -63,11 +63,14 @@ void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, e = static_text.find(id); } if (!e->second->IsSetup()) { + int l = ren->Layer(); + ren->Layer(base); e->second->Setup(&(*ren), pos, clr, text, flags, box); + ren->Layer(l); } e->second->SetPos(pos); e->second->SetColor(clr); - e->second->SetLayer(base + layer); + e->second->SetLayer(layer); e->second->Draw(); ////// STILL LEAVING THE OLD CODE BELOW AS IT IS MAYBE NEEDED ////// @@ -78,13 +81,14 @@ void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr, // Font uses multiple textures // Oh and Handle Layer management here as well // int l = ren->Layer(); - // ren->Layer(layer); + // ren->Layer(base + layer); // std::vector cmds; // ren->TextCommand(cmds, pos, clr, text, flags, box); // ren->Layer(l); // for (auto c : cmds) { // commands.push_back( - // std::make_pair(ren->CurrentScreen() == Screen::Bottom, c)); + // std::make_pair(ren->CurrentScreen()->ScreenType() == Screen::Bottom, + // c)); // } } @@ -97,18 +101,17 @@ void DrawList::AddImage(vec2 pos, Texture::Ref img, vec2 size) { auto cmd = LI::Command::New(); ren->UseTex(img); ren->SetupCommand(cmd); - cmd->Layer(layer); + cmd->Layer(base + layer); ren->QuadCommand(cmd, rect, img->GetUV(), 0xffffffff); - commands.push_back( - std::make_pair(ren->CurrentScreen() == Screen::Bottom, cmd)); + commands.push_back(std::make_pair( + ren->CurrentScreen()->ScreenType() == Screen::Bottom, cmd)); } void DrawList::Clear() { commands.clear(); } void DrawList::Process() { for (auto command : commands) { - command.second->Layer(command.second->Layer() + base); - ren->OnScreen(command.first ? Screen::Bottom : Screen::Top); + ren->OnScreen(ren->GetScreen(command.first)); ren->PushCommand(command.second); } commands.clear(); diff --git a/source/ui7/menu.cpp b/source/ui7/menu.cpp index 78e869f..992fe67 100644 --- a/source/ui7/menu.cpp +++ b/source/ui7/menu.cpp @@ -2,107 +2,57 @@ #include #include -////////////////////////////// -//////// OBJECT SETUP //////// -////// Setup Variables /////// -///////// Move Cursor //////// -//// Check Scrolling State /// -/////// Handle Controls ////// -////////// Render //////////// -////////////////////////////// - namespace PD { namespace UI7 { void UI7::Menu::Label(const std::string& label) { - vec2 size = this->back->GetRenderer()->GetTextDimensions(label); - vec2 pos = Cursor(); - CursorMove(size - vec2(0, 4)); // Fix to make gap not to large - - if (HandleScrolling(pos, size)) { - return; - } - - /// To Draw a Label above the head bar you should - /// use the m->GetFrontList() instead - - main->AddText(pos, label, linked_theme->Get(UI7Color_Text), 0, - vec2(view_area.z(), 20)); + Container::Ref r = + ObjectPush(PD::New(label, Cursor(), this->back->ren)); + CursorMove(r->GetSize()); + r->Init(main->ren, main, linked_theme); + r->HandleScrolling(scrolling_off, view_area); } bool UI7::Menu::Button(const std::string& label) { bool ret = false; - auto tszs = this->back->GetRenderer()->GetTextDimensions(label); - vec2 size = tszs + vec2(8, 4); - vec2 pos = Cursor(); - UI7Color clr = UI7Color_Button; - CursorMove(size); - /////// SCROLLING HANDLER HERE //////// - if (HandleScrolling(pos, size)) { - return false; + u32 id = Strings::FastHash("btn" + label); + Container::Ref r = FindIDObj(id); + if (!r) { + r = ObjectPush(PD::New(label, Cursor(), this->back->ren)); + r->SetID(id); + r->Init(main->ren, main, linked_theme); + } else { + ObjectPush(r); + r->SetPos(Cursor()); } - /// CONTROLS /// - if (has_touch) { - if (inp->IsHeld(inp->Touch) && - LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { - clr = UI7Color_ButtonHovered; - } - if (inp->IsUp(inp->Touch) && - LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { - clr = UI7Color_ButtonActive; - ret = true; - } + CursorMove(r->GetSize()); + r->HandleScrolling(scrolling_off, view_area); + if (!r->Skippable()) { + ret = std::static_pointer_cast(r)->IsPressed(); } - /// Rendering /// - main->AddRectangle(pos, size, linked_theme->Get(clr)); - main->AddText(pos + size * 0.5 - tszs * 0.5, label, - linked_theme->Get(UI7Color_Text)); return ret; } void UI7::Menu::Checkbox(const std::string& label, bool& v) { - vec2 pos = Cursor(); - vec2 tdim = front->ren->GetTextDimensions(label); - vec2 cbs(18); - vec2 size = cbs + vec2(tdim.x() + 5, 0); - CursorMove(size); - - if (HandleScrolling(pos, size)) { - return; + u32 id = Strings::FastHash("cbx" + label); + Container::Ref r = FindIDObj(id); + if (!r) { + r = ObjectPush(PD::New(label, Cursor(), v, this->back->ren)); + r->SetID(id); + r->Init(main->ren, main, linked_theme); + } else { + ObjectPush(r); + r->SetPos(Cursor()); } - - UI7Color cbbg = UI7Color_FrameBackground; - - if (has_touch) { - if (inp->IsHeld(inp->Touch) && - LI::Renderer::InBox(inp->TouchPos(), vec4(pos, size))) { - cbbg = UI7Color_FrameBackgroundHovered; - } - if (inp->IsUp(inp->Touch) && - LI::Renderer::InBox(inp->TouchPosLast(), vec4(pos, size))) { - cbbg = UI7Color_FrameBackgroundHovered; - v = !v; - } - } - - main->AddRectangle(pos, cbs, linked_theme->Get(cbbg)); - if (v) { - main->AddRectangle(pos + 2, cbs - 4, linked_theme->Get(UI7Color_Checkmark)); - } - main->AddText(pos + vec2(cbs.x() + 5, cbs.y() * 0.5 - tdim.y() * 0.5), label, - linked_theme->Get(UI7Color_Text)); + CursorMove(r->GetSize()); + r->HandleScrolling(scrolling_off, view_area); } void UI7::Menu::Image(Texture::Ref img, vec2 size) { - /// Variable Setup Stage /// - size = size == 0.f ? img->GetSize() : size; - vec2 pos = Cursor(); - CursorMove(size); - /// Scrolling Handler /// - if (HandleScrolling(pos, size)) { - return; - } - /// Rendering Stage /// - main->AddImage(pos, img, size); + Container::Ref r = + ObjectPush(PD::New(img, Cursor(), this->back->ren, size)); + CursorMove(r->GetSize()); + r->Init(main->ren, main, linked_theme); + r->HandleScrolling(scrolling_off, view_area); } void UI7::Menu::DebugLabels() { @@ -131,12 +81,21 @@ void UI7::Menu::DebugLabels() { void UI7::Menu::Update(float delta) { TT::Scope st("MUPT_" + name); - this->back->BaseLayer(30); + for (auto& it : objects) { + if (it->GetID() != 0 && !FindIDObj(it->GetID())) { + idobjs.push_back(it); + } + if (!it->Skippable()) { + it->HandleInput(inp); + /// Unlock Input after to ensure nothing is checked twice + it->UnlockInput(); + it->Draw(); + } + } this->back->Process(); - this->main->BaseLayer(40); this->main->Process(); - this->front->BaseLayer(50); this->front->Process(); + this->objects.clear(); } void UI7::Menu::CursorMove(const vec2& size) { @@ -154,13 +113,18 @@ 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); Cursor(vec2(5, 5)); this->flags = flags; this->scrolling[0] = flags & UI7MenuFlags_HzScrolling; this->scrolling[1] = flags & UI7MenuFlags_VtScrolling; - has_touch = main->GetRenderer()->CurrentScreen() == Screen::Bottom; + has_touch = + main->GetRenderer()->CurrentScreen()->ScreenType() == Screen::Bottom; if (!(flags & UI7MenuFlags_NoBackground)) { - back->AddRectangle(0, view_area.zw(), UI7Color_Background); + back->AddRectangle(0, view_area.zw(), + linked_theme->Get(UI7Color_Background)); } if (!(flags & UI7MenuFlags_NoTitlebar)) { tbh = front->GetRenderer()->TextScale() * 30.f; @@ -327,5 +291,42 @@ bool UI7::Menu::HandleScrolling(vec2& pos, const vec2& size) { } return false; } + +Container::Ref UI7::Menu::ObjectPush(Container::Ref obj) { + this->objects.push_back(obj); + return obj; +} + +Container::Ref UI7::Menu::FindIDObj(u32 id) { + for (auto& it : idobjs) { + if (it->GetID() == id) { + return it; + } + } + return nullptr; +} + +void UI7::Menu::Join() { + Assert(objects.size(), "Objects list is empty!"); + join.push_back(objects.back().get()); +} + +void UI7::Menu::JoinOpHzCenter() { + this->Join(); + float spos = join.front()->GetPos().x(); + float szs = join.back()->GetPos().x() + join.back()->GetSize().x() - spos; + float off = (view_area.x() + view_area.z() * 0.5) - (spos + szs * 0.5); + for (auto it : join) { + it->SetPos(it->GetPos() + vec2(off, 0.f)); + } + join.clear(); +} +void UI7::Menu::AfterAlignCenter() { + Container* ref = objects.back().get(); + vec2 p = ref->GetPos(); + vec2 s = ref->GetSize(); + float newx = (view_area.x() + view_area.z() * 0.5) - (p.x() + s.x() * 0.5); + ref->SetPos(vec2(newx, p.y())); +} } // namespace UI7 } // namespace PD \ No newline at end of file diff --git a/source/ui7/theme.cpp b/source/ui7/theme.cpp index 965e71f..55b4db7 100644 --- a/source/ui7/theme.cpp +++ b/source/ui7/theme.cpp @@ -6,7 +6,7 @@ namespace UI7 { void Theme::Default(Theme& theme) { theme.Set(UI7Color_Text, Color("#FFFFFFFF")); theme.Set(UI7Color_TextDead, Color("#AAAAAAFF")); - theme.Set(UI7Color_Background, Color("#EEEEEEFF")); + theme.Set(UI7Color_Background, Color("#222222aa")); theme.Set(UI7Color_Button, Color("#111111FF")); theme.Set(UI7Color_ButtonDead, Color("#080808FF")); theme.Set(UI7Color_ButtonActive, Color("#2A2A2AFF")); diff --git a/test/app/main.cpp b/test/app/main.cpp index 09d9d90..8aedd28 100644 --- a/test/app/main.cpp +++ b/test/app/main.cpp @@ -46,30 +46,44 @@ class Test : public PD::App { } bool MainLoop(float delta, float time) override { + ren->OnScreen(Top); DrawFancyBG(time); - ren->OnScreen(PD::Screen::Bottom); - // ren->DrawRectSolid(0, vec2(320, 240), PD::Color("#222222")); - // ren->Layer(ren->Layer() + 1); - // ren->DrawImage(ren->GetViewport().zw() * 0.5 - test->GetSize() * 0.5, - // test); ren->DrawText(5, 0xffffffff, "Hello World!", LITextFlags_None); + ren->OnScreen(Bottom); if (ui7->BeginMenu("Test", UI7MenuFlags_Scrolling | UI7MenuFlags_CenterTitle)) { auto m = ui7->GetCurrentMenu(); m->SeparatorText("Menu Timings"); m->DebugLabels(); - m->SeparatorText("Lithium Settings"); - FlagBox(m, "LI AST", PD::LI::RenderFlags_AST); - FlagBox(m, "LI LRS", PD::LI::RenderFlags_LRS); - FlagBox(m, "LI TMS", PD::LI::RenderFlags_TMS); + m->SeparatorText("Palladium Info"); + m->Label("Version: " + PD::LibInfo::Version() + " [" + + PD::LibInfo::Commit() + "]"); + m->AfterAlignCenter(); + m->Label("CompileInfo: " + PD::LibInfo::CompiledWith() + " - " + + PD::LibInfo::CxxVersion()); + m->AfterAlignCenter(); + m->Label("Build at " + PD::LibInfo::BuildTime()); + m->AfterAlignCenter(); + m->SeparatorText("Basic Info"); + m->Label("sizeof(size_t): " + std::to_string(sizeof(size_t)) + " -> " + + std::to_string(sizeof(size_t) * 8) + "Bit"); + m->AfterAlignCenter(); + m->Label("__cplusplus=" + std::to_string(__cplusplus)); + m->AfterAlignCenter(); + m->Label(PD::Strings::GetCompilerVersion()); + m->AfterAlignCenter(); + m->Label("sizeof(LI::Vertex): " + std::to_string(sizeof(PD::LI::Vertex))); + m->AfterAlignCenter(); + m->Label("sizeof(PD::u16): " + std::to_string(sizeof(PD::u16))); + m->AfterAlignCenter(); m->SeparatorText("UI7 Tests"); m->Label("This seems to be a label"); + m->Image(test); m->Separator(); - m->Button("Button?"); + if (m->Button("Button?")) { + Messages()->Push("Button", "Pressed..."); + } m->SeparatorText("SeparatorText"); m->Checkbox("Test", cbtest); - for (int i = 0; i < 10; i++) { - m->Label("Label: " + std::to_string(i)); - } ui7->EndMenu(); } ui7->Update(delta); @@ -88,43 +102,6 @@ class Test : public PD::App { void Deinit() override {} - void FlagBox(PD::UI7::Menu::Ref m, const std::string& label, - PD::LI::RenderFlags flag) { - bool has_flag = ren->GetFlags() & flag; - m->Checkbox(label, has_flag); - if (has_flag != (ren->GetFlags() & flag)) { - if (has_flag) { - ren->GetFlags() |= flag; - } else { - ren->GetFlags() &= ~flag; - } - } - } - - void DrawFancyBG(float time) { - ren->DrawRect(vec2(0, 0), vec2(400, 240), 0xff64c9fd); - for (int i = 0; i < 44; i++) Append(i, vec2(0, 0), vec2(400, 240), time); - } - - float Offset(float x) { - float y = cos(x) * 42; - return y - floor(y); - } - void Append(int index, vec2 position, vec2 size, float time) { - float offset = Offset(index) * 62; - float x_position = position.x() + size.x() / 8 * ((index % 11) - 1) + - cos(offset + time) * 10; - float y_position = position.y() + size.y() / 8 * (index / 11) + 40 + - sin(offset + time) * 10 + 30; - float color_effect = 1 - exp(-(index / 11) / 3.0f); - - ren->DrawTriangle( - vec2(x_position, y_position), vec2(x_position + 300, y_position + (90)), - vec2(x_position - 300, y_position + (90)), - PD::Color(.94f - .17f * color_effect, .61f - .25f * color_effect, - .36f + .38f * color_effect)); - } - private: /// Shorter Acess to Renderer / Input PD::LI::Renderer::Ref ren; diff --git a/test/bench/main.cpp b/test/bench/main.cpp index 73fd1bc..57b0c24 100644 --- a/test/bench/main.cpp +++ b/test/bench/main.cpp @@ -76,7 +76,7 @@ class TestBench : public PD::App { void Result(float delta) { UpdateLiTimes(); - ren->OnScreen(PD::Screen::Top); + ren->OnScreen(Top); if (ui7->BeginMenu("TestBench")) { auto m = ui7->GetCurrentMenu(); m->Label("Base Init: " + TTime("BaseInit")); @@ -84,7 +84,7 @@ class TestBench : public PD::App { PD::Strings::FormatNanos(li_stats->GetAverage())); ui7->EndMenu(); } - ren->OnScreen(PD::Screen::Bottom); + ren->OnScreen(Bottom); if (ui7->BeginMenu("Test Results", UI7MenuFlags_Scrolling)) { auto m = ui7->GetCurrentMenu(); for (auto& it : results) { @@ -116,7 +116,11 @@ class TestBench : public PD::App { DrawFancyBG(time); if (ui7->BeginMenu("Test2")) { auto m = ui7->GetCurrentMenu(); + m->Label("Text1"); + m->Label("Text2"); m->Button("Test"); + m->SameLine(); + m->Button("Test2"); m->Separator(); m->Label("Line1"); m->Label("Line2");