From 224daffaf7d7a23f4f20582847c90e7f176d27f6 Mon Sep 17 00:00:00 2001 From: tobid7 Date: Fri, 30 Aug 2024 14:54:49 +0200 Subject: [PATCH] Changes: - Start Restructuring Project - Add Makefile for Testbuilds - Optimize Lithium as much as possible - Remove Render2 to get wasted time - Optimize UI7 for LRS --- CHANGELOG.md | 6 +- Makefile | 152 +++++ doxide.yaml | 4 +- include/pd.hpp | 9 +- include/pd/Font.hpp | 36 - include/pd/Hid.hpp | 2 +- include/pd/Image.hpp | 4 +- include/pd/LI7.hpp | 166 ----- include/pd/Lithium.hpp | 236 +++++++ include/pd/Logger.hpp | 35 - include/pd/Message.hpp | 4 +- include/pd/NVec.hpp | 105 --- include/pd/Overlays.hpp | 29 +- include/pd/Render2.hpp | 83 --- include/pd/Sheet.hpp | 51 +- include/pd/Sprite.hpp | 12 +- include/pd/SpriteAnimation.hpp | 43 -- include/pd/Texture.hpp | 10 +- include/pd/UI7.hpp | 31 +- include/pd/{ => base}/Allocator.hpp | 0 include/pd/{ => base}/Color.hpp | 408 +++++------ include/pd/{ => base}/FileSystem.hpp | 46 +- include/pd/{ => base}/FunctionTrace.hpp | 213 +++--- include/pd/{lang.hpp => base/Lang.hpp} | 48 +- include/pd/{ => base}/Memory.hpp | 52 +- include/pd/{ => base}/stringtool.hpp | 199 +++--- include/pd/global_db.hpp | 47 +- include/pd/internal_db.hpp | 11 +- include/pd/maths/NMat.hpp | 45 ++ include/pd/maths/NVec.hpp | 366 ++++++++++ include/pd/palladium.hpp | 17 +- source/Error.cpp | 8 +- source/Image.cpp | 4 +- source/LI7.cpp | 489 ------------- source/Lithium.cpp | 767 +++++++++++++++++++++ source/Logger.cpp | 44 -- source/Message.cpp | 64 +- source/Overlays.cpp | 324 ++++++--- source/Render2.cpp | 325 --------- source/Rubidium.cpp | 2 +- source/Sheet.cpp | 59 +- source/Sound.cpp | 4 - source/Sprite.cpp | 4 +- source/SpriteSheetAnimation.cpp | 29 - source/Texture.cpp | 33 +- source/ThemeEditor.cpp | 4 +- source/UI7.cpp | 866 ++++++++++++++---------- source/{ => base}/Color.cpp | 456 ++++++------- source/{ => base}/FileSystem.cpp | 140 ++-- source/{ => base}/FunctionTrace.cpp | 4 +- source/{lang.cpp => base/Lang.cpp} | 234 +++---- source/{ => base}/Memory.cpp | 111 ++- source/internal_db.cpp | 33 +- source/palladium.cpp | 356 +++++----- 54 files changed, 3723 insertions(+), 3107 deletions(-) create mode 100644 Makefile delete mode 100644 include/pd/Font.hpp delete mode 100644 include/pd/LI7.hpp create mode 100644 include/pd/Lithium.hpp delete mode 100644 include/pd/Logger.hpp delete mode 100644 include/pd/NVec.hpp delete mode 100644 include/pd/Render2.hpp delete mode 100644 include/pd/SpriteAnimation.hpp rename include/pd/{ => base}/Allocator.hpp (100%) rename include/pd/{ => base}/Color.hpp (96%) rename include/pd/{ => base}/FileSystem.hpp (96%) rename include/pd/{ => base}/FunctionTrace.hpp (58%) rename include/pd/{lang.hpp => base/Lang.hpp} (96%) rename include/pd/{ => base}/Memory.hpp (96%) rename include/pd/{ => base}/stringtool.hpp (77%) create mode 100644 include/pd/maths/NMat.hpp create mode 100644 include/pd/maths/NVec.hpp delete mode 100644 source/LI7.cpp create mode 100644 source/Lithium.cpp delete mode 100644 source/Logger.cpp delete mode 100644 source/Render2.cpp delete mode 100644 source/SpriteSheetAnimation.cpp rename source/{ => base}/Color.cpp (97%) rename source/{ => base}/FileSystem.cpp (94%) rename source/{ => base}/FunctionTrace.cpp (67%) rename source/{lang.cpp => base/Lang.cpp} (94%) rename source/{ => base}/Memory.cpp (76%) diff --git a/CHANGELOG.md b/CHANGELOG.md index c89f95e..fc3ff5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Palladium Changelog ## 1.0.0 +- Rename Everyting to PD +- R7Vec -> NVec - Switch from C2D to Lithium (LI7) - For the Rest See RenderD7 Changelog below - swr -> Rubidium @@ -8,7 +10,9 @@ - Larger Mesaage Box - Add Texture Loader - Update Image/Error and other sytems to Lithium -- Optimize Render2 for Lithium +- Remove Render2 +- Add Deltatime to every moving object +- Restructure Project # RenderD7 Changelog ## 0.9.5 - Remove Npi Intro and NVID Api diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b625922 --- /dev/null +++ b/Makefile @@ -0,0 +1,152 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/3ds_rules + +export PD_MAJOR := 1 +export PD_MINOR := 0 +export PD_PATCH := 0 + +VERSION := $(PD_MAJOR).$(PD_MINOR).$(PD_PATCH) + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#--------------------------------------------------------------------------------- +TARGET := palladium +SOURCES := source source/base +DATA := data +INCLUDES := include + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft + +CFLAGS := -g -Wall -Wno-psabi -Werror -mword-relocations \ + -ffunction-sections -fdata-sections \ + -fomit-frame-pointer -ffast-math \ + $(ARCH) $(BUILD_CFLAGS) + +CFLAGS += $(INCLUDE) -D__3DS__ -D_GNU_SOURCE=1 + +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=c++20 + +ASFLAGS := -g $(ARCH) $(DEFINES) + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) $(CTRULIB) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I. + +.PHONY: clean all doc + +#--------------------------------------------------------------------------------- +all: lib/libpalladium.a lib/libpalladiumd.a + +dist-bin: all + @tar --exclude=*~ -cjf palladium-$(VERSION).tar.bz2 include lib + +dist-src: + @tar --exclude=*~ -cjf palladium-src-$(VERSION).tar.bz2 include source Makefile + +dist: dist-src dist-bin + +install: dist-bin + mkdir -p $(DESTDIR)$(DEVKITPRO)/libctru + bzip2 -cd palladium-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/libctru + +lib: + @[ -d $@ ] || mkdir -p $@ + +release: + @[ -d $@ ] || mkdir -p $@ + +debug: + @[ -d $@ ] || mkdir -p $@ + +lib/libpalladium.a : lib release $(SOURCES) $(INCLUDES) + @$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \ + BUILD_CFLAGS="-DNDEBUG=1 -O3 -fomit-frame-pointer -fno-math-errno" \ + DEPSDIR=$(CURDIR)/release \ + --no-print-directory -C release \ + -f $(CURDIR)/Makefile + +lib/libpalladiumd.a : lib debug $(SOURCES) $(INCLUDES) + @$(MAKE) BUILD=debug OUTPUT=$(CURDIR)/$@ \ + BUILD_CFLAGS="-DDEBUG=1 -Og" \ + DEPSDIR=$(CURDIR)/debug \ + --no-print-directory -C debug \ + -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr release debug lib + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT) : $(OFILES) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/doxide.yaml b/doxide.yaml index 737cf4c..6292407 100644 --- a/doxide.yaml +++ b/doxide.yaml @@ -3,7 +3,7 @@ description: files: - "include/*.hpp" - "include/pd/*.hpp" - - "include/pd/music/*.hpp" + - "include/pd/base/*.hpp" - "include/*.h" - "include/pd/*.h" - - "include/pd/music/*.h" \ No newline at end of file + - "include/pd/base/*.h" \ No newline at end of file diff --git a/include/pd.hpp b/include/pd.hpp index c9f9dc1..63c0821 100644 --- a/include/pd.hpp +++ b/include/pd.hpp @@ -1,25 +1,26 @@ #pragma once -#include +#include #include -#include +#include #include #include #include -#include +#include #include #include #include #include #include #include +#include #include #include #include #include namespace Palladium { -using Render2 = R2; +using Lithium = LI; using RB = Rubidium; } // namespace Palladium diff --git a/include/pd/Font.hpp b/include/pd/Font.hpp deleted file mode 100644 index c4f313c..0000000 --- a/include/pd/Font.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -namespace Palladium { -class Font { - public: - Font() = default; - Font(const std::string& path) { Load(path); }; - ~Font() { Unload(); } - PD_SMART_CTOR(Font) - - void Load(const std::string& path) { - std::ifstream ft(path, std::ios::in | std::ios::binary); - bool io = ft.is_open(); - ft.close(); - Palladium::InlineAssert(io, "File not Found!"); - fnt = C2D_FontLoad(path.c_str()); - Palladium::InlineAssert(fnt, "Font could not be loaded!"); - } - C2D_Font Ptr() { return fnt; } - void Unload() { - if (!fnt) return; - C2D_FontFree(fnt); - fnt = nullptr; - } - - private: - C2D_Font fnt = nullptr; -}; -} // namespace Palladium diff --git a/include/pd/Hid.hpp b/include/pd/Hid.hpp index 9d56805..5194ddc 100644 --- a/include/pd/Hid.hpp +++ b/include/pd/Hid.hpp @@ -5,7 +5,7 @@ #pragma once -#include +#include #include namespace Palladium { diff --git a/include/pd/Image.hpp b/include/pd/Image.hpp index ff7d9ab..79086b7 100644 --- a/include/pd/Image.hpp +++ b/include/pd/Image.hpp @@ -2,7 +2,7 @@ #include <3ds.h> -#include +#include #include #include #include @@ -23,7 +23,7 @@ class Image { void Set(Texture::Ref i, NVec4 uvs = NVec4(-1, -1, -1, -1)); NVec2 GetSize(); NVec4 GetUV() { - return (custom_uvs.x != -1) ? custom_uvs : img->GetUV(); + return (custom_uvs.x() != -1) ? custom_uvs : img->GetUV(); } bool Loadet(); diff --git a/include/pd/LI7.hpp b/include/pd/LI7.hpp deleted file mode 100644 index d821d3d..0000000 --- a/include/pd/LI7.hpp +++ /dev/null @@ -1,166 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#include -#include -#include -#include - -#define MAKEFLAG(x) (1 << x) - -using PDTextFlags = unsigned int; - -enum PDTextFlags_ { - PDTextFlags_None = 0, //< Align is Left and Other things are disabled - PDTextFlags_AlignRight = MAKEFLAG(0), - PDTextFlags_AlignMid = MAKEFLAG(1), - PDTextFlags_Shaddow = MAKEFLAG(2), // TextBuf Killer lol (doubled Text) - PDTextFlags_Wrap = MAKEFLAG(3), - PDTextFlags_Short = MAKEFLAG(4), - PDTextFlags_Scroll = MAKEFLAG(5), -}; - -namespace Palladium { -class LIFont { - public: - struct CPI { - unsigned char codepoint; - NVec4 uv; - Texture::Ref tex; - NVec2 szs; - float off; - }; - LIFont() = default; - ~LIFont() = default; - PD_SMART_CTOR(LIFont) - - void LoadTFF(const std::string path, int px_size = 32); - void LoadBitmapFont(const std::string& path); - void LoadSystemFont(); - - int GetPixelHeight(); - CPI GetCodepoint(char c); - std::string GetName() { return name; }; - - void Dump(); - - private: - std::string name; - int pixel_height; - std::vector cpmap; - std::vector tex; -}; -class LI7 { - public: - struct Vtx { - Vtx() {} - Vtx(NVec2 xy, float u, float v, unsigned int clr) { - // Coords - xyz[0] = xy.x; - xyz[1] = xy.y; - xyz[2] = 0.5f; // Always 0 - // UV - uv[0] = u; - uv[1] = v; - col = clr; - } - float xyz[3]; - float uv[2]; - unsigned int col; - }; - /// CMD TYPES /// - /// 0 = SKIP - /// 1 = TRIANGLE - /// 2 = RECT - /// 3 = RECT2P (2 Positions instead of pos,szs) - ///////////////// - struct Cmd { - NVec2 ppos; - NVec2 pszs; - NVec2 apos; - NVec4 top; - NVec4 bot; - NVec4 uv; - int layer = 0; - int cmd_type = 0; - unsigned int clr = 0; - Texture::Ref tex = nullptr; - }; - LI7() = default; - ~LI7() = default; - - static void Init(); - static void Exit(); - - static void OnScreen(bool bottom); - static void Render(C3D_RenderTarget* top, C3D_RenderTarget* bot); - static void Scale(float i) { m_scale = i; } - static float Scale() { return m_scale; } - static void BindTexture(Texture::Ref tex); - static NVec2 ScreenSize() { return NVec2(m_width, m_height); } - static LIFont::Ref GetFont() { return m_font; } - - static void ColorRect(NVec2 pos, NVec2 szs, NVec4 uvs, unsigned int clr); - static void Rect(NVec2 pos, NVec2 szs, NVec4 uvs); - static void ColorRect(NVec2 pos, NVec2 szs, unsigned int clr); - static void Rect(NVec2 pos, NVec2 szs); - static void TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce); - static void Line(NVec2 a, NVec2 b, unsigned int clr, int t = 1); - static void Triangle(NVec2 a, NVec2 b, NVec2 c, unsigned int clr); - static void UseTexture(Texture::Ref tex = nullptr) { - m_current_texture = tex ? tex : m_white; - } - - static NVec2 GetTextDimensions(const std::string& text); - static void DrawText(NVec2 pos, unsigned int color, const std::string& text, - PDTextFlags flags = 0, NVec2 ap = NVec2()); - - static float GetTextScale() { return m_txt_scale; } - static void SetTextScale(float scale) { m_txt_scale = scale; } - static void DefaultTextScale() { m_txt_scale = m_dts; } - - static int Vertices() { return m_d_vertices; } - static int Drawcalls() { return m_d_drawcalls; } - static int DarwCommands() { return m_d_commands; } - - private: - static bool CompareCommands(const Cmd& a, const Cmd& b); - static void RenderFrame(bool bottom); - - // Default Font Size in (px) - static const float m_dffs; - static const float m_dts; - static float m_txt_scale; - - static int m_uLoc_proj; - static float m_scale; - static int m_width, m_height; - - static int m_d_vertices; - static int m_d_drawcalls; - static int m_d_commands; - - static const int m_char_height; // Constant - - // UI Stuff - static std::vector m_top_draw_cmds; - static std::vector m_bot_draw_cmds; - static Texture::Ref m_current_texture; - static Texture::Ref m_white; - static std::vector> m_vtx_list[2]; - // static Font* m_font; - static LIFont::Ref m_font; - static std::vector m_text_buffer; - - // Ctx Stuff - static bool m_bottom_active; - - // Shader - static DVLB_s* li7_dvlb; - static shaderProgram_s li7_prog; - static C3D_AttrInfo li7_attr; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Lithium.hpp b/include/pd/Lithium.hpp new file mode 100644 index 0000000..8e70d93 --- /dev/null +++ b/include/pd/Lithium.hpp @@ -0,0 +1,236 @@ +#pragma once +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MAKEFLAG(x) (1 << x) + +using PDTextFlags = unsigned int; + +enum PDTextFlags_ { + PDTextFlags_None = 0, //< Align is Left and Other things are disabled + PDTextFlags_AlignRight = MAKEFLAG(0), + PDTextFlags_AlignMid = MAKEFLAG(1), + PDTextFlags_Shaddow = MAKEFLAG(2), // TextBuf Killer lol (doubled Text) + PDTextFlags_Wrap = MAKEFLAG(3), + PDTextFlags_Short = MAKEFLAG(4), + PDTextFlags_Scroll = MAKEFLAG(5), +}; + +using PDLithiumFlags = unsigned int; + +enum PDLithiumFlags_ { + PDLithiumFlags_None = 0, + PDLithiumFlags_TMS = MAKEFLAG(0), // Text Map System + PDLithiumFlags_LRS = MAKEFLAG(1), // Layer Render System + PDLithiumFlags_Default = PDLithiumFlags_TMS, +}; + +namespace Palladium { +class LIFont { + public: + struct CPI { + CPI() + : codepoint(0), + uv(NVec4()), + tex(nullptr), + szs(NVec2()), + off(0.f), + invalid(false) {} + CPI(bool iv) + : codepoint(0), + uv(NVec4()), + tex(nullptr), + szs(NVec2()), + off(0.f), + invalid(iv) {} + unsigned int codepoint; + NVec4 uv; + Texture::Ref tex; + NVec2 szs; + float off; + bool invalid; + }; + LIFont() = default; + ~LIFont() = default; + PD_SMART_CTOR(LIFont) + + void LoadTFF(const std::string path, int px_size = 32); + void LoadBitmapFont(const std::string& path); + void LoadSystemFont(); + + int GetPixelHeight(); + CPI GetCodepoint(unsigned int c); + std::string GetName() { return name; }; + + bool IsSystemFont() { return sysfnt; } + + void Dump(); + + private: + bool sysfnt = false; + std::string name; + int pixel_height; + std::map cpmap; + std::vector tex; +}; + +class LI { + public: + struct Vtx { + Vtx() {} + Vtx(NVec2 xy, float u, float v, unsigned int clr) { + // Coords + pos[0] = xy[0]; + pos[1] = xy[1]; + pos[2] = 0.f; + // UV + uv[0] = u; + uv[1] = v; + col = clr; + } + NVec3 pos; + NVec2 uv; + unsigned int col; + }; + /// CMD TYPES /// + /// 0 = SKIP + /// 2 = TRIANGLE + /// 1 = RECT + /// 3 = Circle + ///////////////// + struct Cmd { + NVec4 top; + NVec4 bot; + NVec4 uv; + int layer = 0; + int cmd_type = 0; + unsigned int clr = 0; + bool sfr = false; // SysFontRender + Texture::Ref tex = nullptr; + int index = 0; + }; + /// Text Box /// + /// System to Make GetTextDiemnsions + /// and Short/Wrap faster + struct TextBox { + NVec2 size; + float time_created; + // Optional + bool optinal = false; + std::string text; + }; + LI() = default; + ~LI() = default; + + static void Init(); + static void Exit(); + + // Settings + static void EnableFeature(PDLithiumFlags flag) { flags |= flag; } + static void DisableFeature(PDLithiumFlags flag) { flags &= ~flag; } + static PDLithiumFlags& GetFeatures() { return flags; } + + static void OnScreen(bool bottom); + static void Render(C3D_RenderTarget* top, C3D_RenderTarget* bot); + static NVec2 GetScreenSize() { return screen_size; } + static LIFont::Ref GetFont() { return font; } + static void SetFont(LIFont::Ref i) { + font_update = true; + font = i; + } + static void UseTexture(Texture::Ref tex = nullptr) { + active_texture = tex ? tex : single_color; + } + static bool IsBottomScreen() { return bottom_screen; } + static float GetTextScale() { return text_scale; } + static void SetTextScale(float scale) { + font_update = true; + text_scale = scale; + } + static void DefaultTextScale() { + font_update = true; + text_scale = default_text_size; + } + static void Layer(int v) { layer = v; } + static int Layer() { return layer; } + static void NewLayer() { layer++; } + static NVec2 GetTextDimensions(const std::string& text); + static std::string ShortText(const std::string& in, int maxlen, NVec2& dim); + static std::string WrapText(const std::string& in, int maxlen, NVec2& dim); + + // Drawing Functions + static void DrawRect(NVec2 pos, NVec2 size, unsigned int color, NVec4 uvs); + static void DrawLine(NVec2 a, NVec2 b, unsigned int clr, int t = 1); + static void DrawCircle(NVec2 pos, float r, unsigned int color, int segments); + static void DrawRect(NVec2 pos, NVec2 size, unsigned int color) { + UseTexture(); + DrawRect(pos, size, color, NVec4(0, 1, 1, 0)); + } + static void DrawTriangle(NVec2 a, NVec2 b, NVec2 c, unsigned int color); + static void DrawImage(NVec2 pos, Texture::Ref tex, NVec2 size, NVec4 uvs) { + UseTexture(tex); + DrawRect(pos, size, 0xffffffff, uvs); + } + static void DrawText(NVec2 pos, unsigned int color, const std::string& text, + PDTextFlags flags = 0, NVec2 ap = NVec2()); + + static int Vertices() { return num_vertices; } + static int Indices() { return num_indices; } + static int Drawcalls() { return num_drawcalls; } + static int DarwCommands() { return num_commands; } + static size_t GetMaxVerticesNum() { return vertex_buffer.size(); } + + private: + static void RotateCorner(NVec2& v, float s, float c); + static void MakeRect(NVec4& top, NVec4& bot, NVec2 pos, NVec2 szs, + float angle = 0.f); + static bool CompareCommands(const Cmd& a, const Cmd& b); + static void RenderFrame(bool bottom); + + /// CTX /// + static PDLithiumFlags flags; + // Font Stuff + // Default Font Size in (px) + static const float default_font_size; + static const float default_text_size; + static float text_scale; + + // Renderer Stuff + static NVec2 screen_size; + static bool bottom_screen; + static int layer; + static std::vector draw_lists[2]; + static Texture::Ref active_texture; + static Texture::Ref single_color; + static std::vector> vertex_buffer; + static std::vector> + idx_buffer; + static size_t vertex_index; + static size_t idx_index; + static LIFont::Ref font; + static bool font_update; + static bool sysfont_render; + static std::map text_sizes; + static int cmd_index; + + // Debug + static int num_vertices; + static int num_drawcalls; + static int num_commands; + static int num_indices; + + // Shader + static DVLB_s* li7_dvlb; + static shaderProgram_s li7_prog; + static C3D_AttrInfo li7_attr; + static int uLoc_proj; +}; +} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Logger.hpp b/include/pd/Logger.hpp deleted file mode 100644 index 5b21df6..0000000 --- a/include/pd/Logger.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include -#include -#include -#include - -namespace Palladium { - -/// @brief Logger base Class -class LoggerBase { - public: - /// @brief Constructor - LoggerBase() = default; - /// @brief Deconstructor - ~LoggerBase(); - PD_SMART_CTOR(LoggerBase) - /// @brief Init the Logger - /// @param filename name[_date_time.txt] - void Init(const std::string& name, bool fileless = false); - /// @brief Write a String - /// @param debug_text string - /// @param lvl Logger LVL 0 = ERR, 1 =WARNING, >=2= Default - void Write(const std::string& debug_text, int lvl = 2); - void SetLvl(int lvl) { writelvl = lvl; } - const std::vector& Lines(); - - private: - /// \param filename the name of the logfile - std::string filename; - std::string log_path; - std::ofstream _log; - int writelvl = 1; // Only log errors/Warnings - std::vector lines; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Message.hpp b/include/pd/Message.hpp index 817599a..0770135 100644 --- a/include/pd/Message.hpp +++ b/include/pd/Message.hpp @@ -7,12 +7,12 @@ struct Message { Message(std::string t, std::string m) { title = t; message = m; - animationframe = 0; + animtime = 0.f; } std::string title; std::string message; - int animationframe; + float animtime; }; void ProcessMessages(); diff --git a/include/pd/NVec.hpp b/include/pd/NVec.hpp deleted file mode 100644 index e81c5b9..0000000 --- a/include/pd/NVec.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -struct NVec2 { - // Init Funcs - NVec2() : x(0), y(0) {} - NVec2(float i0, float i1) : x(i0), y(i1) {} - NVec2(const NVec2 &i) { - x = i.x; - y = i.y; - } - - // Operators - // Add - NVec2 &operator+=(const NVec2 &i) { - x += i.x; - y += i.y; - return *this; - } - - NVec2 operator+(const NVec2 &i) const { return NVec2(x + i.x, y + i.y); } - - // Sub - NVec2 &operator-=(const NVec2 &i) { - x -= i.x; - y -= i.y; - return *this; - } - - NVec2 operator-(const NVec2 &i) const { return NVec2(x - i.x, y - i.y); } - - // Compare - bool operator==(const NVec2 &in) const { return x == in.x && y == in.y; } - - bool operator!=(const NVec2 &in) const { - // use the first comparefuncs result - // and swap it lol - return !(*this == in); - } - - // Internal Values - float x; - float y; -}; - -struct NVec4 { - // Init Funcs - NVec4() : x(0), y(0), z(0), w(0) {} - NVec4(float i0, float i1, float i2, float i3) : x(i0), y(i1), z(i2), w(i3) {} - NVec4(const NVec4 &i) { - x = i.x; - y = i.y; - z = i.z; - w = i.w; - } - - NVec4(const NVec2 &i0, const NVec2 &i1) { - x = i0.x; - y = i0.y; - z = i1.x; - w = i1.y; - } - - // Operators - // Add - NVec4 &operator+=(const NVec4 &i) { - x += i.x; - y += i.y; - z += i.z; - w += i.w; - return *this; - } - - NVec4 operator+(const NVec4 &i) const { - return NVec4(x + i.x, y + i.y, z + i.z, w + i.w); - } - - // Sub - NVec4 &operator-=(const NVec4 &i) { - x -= i.x; - y -= i.y; - z -= i.z; - w -= i.w; - return *this; - } - - NVec4 operator-(const NVec4 &i) const { - return NVec4(x - i.x, y - i.y, z - i.z, w - i.w); - } - - // Compare - bool operator==(const NVec4 &in) const { - return x == in.x && y == in.y && z == in.z && w == in.w; - } - - bool operator!=(const NVec4 &in) const { - // use the first comparefuncs result - // and swap it lol - return !(*this == in); - } - // Internal Values - float x; - float y; - float z; - float w; -}; \ No newline at end of file diff --git a/include/pd/Overlays.hpp b/include/pd/Overlays.hpp index 3cc1163..1e21a71 100644 --- a/include/pd/Overlays.hpp +++ b/include/pd/Overlays.hpp @@ -1,6 +1,9 @@ #pragma once #include +#include +#include +#include #include typedef int PDKeyboard; @@ -17,6 +20,16 @@ enum PDKeyboardState { PDKeyboardState_Confirm = 2, }; +using PDKeyboardFlags = unsigned int; +enum PDKeyboardFlags_ { + PDKeyboardFlags_None = 0, + PDKeyboardFlags_BlendTop = 1 << 0, + PDKeyboardFlags_BlendBottom = 1 << 1, + PDKeyboardFlags_LockControls = 1 << 2, + PDKeyboardFlags_Default = + PDKeyboardFlags_BlendTop | PDKeyboardFlags_BlendBottom | PDKeyboardFlags_LockControls, +}; + namespace Palladium { class Ovl_Ftrace : public Palladium::Ovl { public: @@ -34,8 +47,8 @@ class Ovl_Ftrace : public Palladium::Ovl { class Ovl_Metrik : public Palladium::Ovl { public: /// @brief Constructor - Ovl_Metrik(bool* is_enabled, bool* screen, uint32_t* mt_color, - uint32_t* txt_color, float* txt_size); + Ovl_Metrik(bool* is_enabled, bool* screen, unsigned int* mt_color, + unsigned int* txt_color, float* txt_size); /// @brief Override for Draw void Draw(void) const override; /// @brief Override for Logic @@ -49,6 +62,7 @@ class Ovl_Metrik : public Palladium::Ovl { mutable std::string mt_cmd; mutable std::string mt_lfr; mutable std::string mt_vtx; + mutable std::string mt_idx; mutable std::string mt_drc; mutable std::string mt_dmc; mutable std::string mt_mem; @@ -56,9 +70,12 @@ class Ovl_Metrik : public Palladium::Ovl { // Importand Adresses bool* i_is_enabled; bool* i_screen; - uint32_t* i_mt_color; - uint32_t* i_txt_color; + unsigned int* i_mt_color; + unsigned int* i_txt_color; float* i_txt_size; + mutable Ftrace::TimeStats cpu_stats; + mutable Ftrace::TimeStats gpu_stats; + mutable Timer v_update; }; class Ovl_Keyboard : public Palladium::Ovl { @@ -66,7 +83,8 @@ class Ovl_Keyboard : public Palladium::Ovl { /// @brief Constructor /// Keyboard Type not Supported for now Ovl_Keyboard(std::string& ref, PDKeyboardState& state, - const std::string& hint = "", PDKeyboard type = 0); + const std::string& hint = "", PDKeyboard type = 0, + PDKeyboardFlags flags = PDKeyboardFlags_Default); /// @brief Deconstructor ~Ovl_Keyboard(); /// @brief Override for Draw @@ -83,5 +101,6 @@ class Ovl_Keyboard : public Palladium::Ovl { PDKeyboard type; int mode = 0; int ft3 = 0; + PDKeyboardFlags flags; }; } // namespace Palladium \ No newline at end of file diff --git a/include/pd/Render2.hpp b/include/pd/Render2.hpp deleted file mode 100644 index 5f0bb20..0000000 --- a/include/pd/Render2.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -enum R2Screen { - R2Screen_Bottom, - R2Screen_Top, - // TopRight, -}; - -namespace Palladium { -class R2 { - public: - struct R2Cmd { - NVec2 pos; //< Position - NVec2 pszs; //< Position or (TextBox) Size - NVec2 ap; //< Additional Pos - unsigned int clr; //< Color - bool Screen; //< TopScreen - Image::Ref img; //< Image Reference - Sprite::Ref spr; //< Sprite Reference - // 0 = skip, 1 = rect, 2 = tri, 3 = text, - // 4 = image, 5 = sprite, 6 = Line - int type; //< Command Type - bool lined = false; //< Draw Lined Rect/Tri - // Text Specific - PDTextFlags flags; // Text Flags - std::string text; // Text - PD_SMART_CTOR(R2Cmd) - }; - R2() = default; - ~R2() = default; - - static void Init(); - - // Settings - static void SetFont(Font::Ref fnt); - static Font::Ref GetFont(); - static void DefaultFont(); - static void DrawNextLined(); - static void OnScreen(R2Screen screen); - static R2Screen GetCurrentScreen(); - static void SetTextSize(float szs); - static void DefaultTextSize(); - static float GetTextSize(); - static NVec2 GetCurrentScreenSize(); - // Processing - static void Process(); - static NVec2 GetTextDimensions(const std::string& text); - static std::string WrapText(const std ::string& in, int maxlen); - static std::string ShortText(const std::string& in, int maxlen); - // Draw Functions - static void AddRect(NVec2 pos, NVec2 size, PDColor clr); - static void AddRect(NVec2 pos, NVec2 size, unsigned int clr); - static void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr); - static void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, unsigned int clr); - static void AddText(NVec2 pos, const std::string& text, PDColor clr, - PDTextFlags flags = 0, NVec2 tmb = NVec2()); - static void AddText(NVec2 pos, const std::string& text, unsigned int clr, - PDTextFlags flags = 0, NVec2 tmb = NVec2()); - static void AddImage(NVec2 pos, Image::Ref img); - static void AddSprite(Sprite::Ref spr); - static void AddLine(NVec2 pos_a, NVec2 pos_b, PDColor clr, int t = 1); - static void AddLine(NVec2 pos_a, NVec2 pos_b, unsigned int clr, int t = 1); - - private: - static const float default_text_size; - static float text_size; - static Font::Ref font; - static std::map ts; - static std::map mln; - static bool next_lined; - static std::vector commands; - static R2Screen current_screen; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Sheet.hpp b/include/pd/Sheet.hpp index 3f05388..7b38af4 100644 --- a/include/pd/Sheet.hpp +++ b/include/pd/Sheet.hpp @@ -1,35 +1,24 @@ #pragma once -#include <3ds.h> // Result -#include -#include - -#include #include -#include +#include +#include -namespace Palladium { -/// @brief SpriteSheet Class -class Sheet { - public: - /// @brief Constructor - Sheet() = default; - Sheet(const std::string& path) { this->Load(path); } - /// @brief Deconstructor - ~Sheet() { - if (spritesheet) Free(); - } - PD_SMART_CTOR(Sheet); - /// @brief Load A Spritesheet File - /// @param path Path to the t3x - /// @return Result Code - Result Load(const std::string& path); - /// @brief Unload the Sheet - void Free(); - C2D_Image GetImage(int idx); - C2D_SpriteSheet Get() { return this->spritesheet; } +#include - private: - /// \param spritesheet The Sheet - C2D_SpriteSheet spritesheet; -}; -} // namespace Palladium \ No newline at end of file +namespace Palladium +{ + class Sheet { + public: + Sheet() = default; + ~Sheet() = default; + PD_SMART_CTOR(Sheet) + void LoadT3X(const std::string& path); + Texture::Ref Get(int idx); + Image::Ref GetImage(int idx); + + private: + std::vector sprites; + Tex3DS_Texture sheet; + C3D_Tex* sheet_tex = nullptr; + }; +} // namespace Palladium diff --git a/include/pd/Sprite.hpp b/include/pd/Sprite.hpp index 27eda17..31e134b 100644 --- a/include/pd/Sprite.hpp +++ b/include/pd/Sprite.hpp @@ -1,10 +1,8 @@ #pragma once -#include #include #include -#include #include namespace Palladium { @@ -17,10 +15,6 @@ class Sprite { ~Sprite() = default; PD_SMART_CTOR(Sprite) /// \brief Load a Sprite From SpriteSheet - /// \param sheet the Sheet to load from.(Palladium::Sheet) - /// \param index the number of the Sprite in the Sheet - void FromSheet(Palladium::Sheet::Ref sheet, size_t index); - /// \brief Load a Sprite From SpriteSheet /// \param img the Image to load from.(Palladium::Image) void FromImage(Palladium::Image::Ref img); /// @brief Draw the Sprite @@ -63,9 +57,7 @@ class Sprite { void SetRotCenter(NVec2 percentage); private: - /// @param tint ImageTint (unused) - C2D_ImageTint tint; - /// @param sprite The Sprite - C2D_Sprite sprite; + ///// @param sprite The Sprite + //C2D_Sprite sprite; }; } // namespace Palladium \ No newline at end of file diff --git a/include/pd/SpriteAnimation.hpp b/include/pd/SpriteAnimation.hpp deleted file mode 100644 index e2a9dd1..0000000 --- a/include/pd/SpriteAnimation.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include - -namespace Palladium { -/// @brief SpriteSheetAnimation Class -class SpriteSheetAnimation : public Palladium::Sprite { - public: - /// @brief Constructor - SpriteSheetAnimation() = default; - /// @brief Deconstructor - ~SpriteSheetAnimation() = default; - PD_SMART_CTOR(SpriteSheetAnimation); - /// @brief Setup an Animation - /// @param sheet Input Spritesheet - /// @param imagecount Count of Images - /// @param startimage Where to Start the Loop - /// @param frame_begin Current Time (Should be 0) - /// @param frame_finish Time Length - void Setup(Palladium::Sheet::Ref sheet, size_t imagecount, size_t startimage, - float frame_begin, float frame_finish); - /// @brief Play the Animation - /// @param timespeed Speed of the animation - void Play(float timespeed); - - private: - /// @param images Count of Images - size_t images; - /// @param imgs Another Count of images ??? - size_t imgs = 0; - /// @param D_totaltime Current Time - float D_totaltime; - /// @param sheet The Sheet of Images - Palladium::Sheet::Ref sheet; - /// @param time Total Time from frame_finish - float time; -}; -} // namespace Palladium \ No newline at end of file diff --git a/include/pd/Texture.hpp b/include/pd/Texture.hpp index 524ef28..d33ae9e 100644 --- a/include/pd/Texture.hpp +++ b/include/pd/Texture.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include @@ -19,10 +19,10 @@ class Texture { }; Texture() { // Set Default UV - this->uvs.x = 0.0f; - this->uvs.y = 1.0f; - this->uvs.z = 1.0f; - this->uvs.w = 0.0f; + this->uvs[0] = 0.0f; + this->uvs[1] = 1.0f; + this->uvs[2] = 1.0f; + this->uvs[3] = 0.0f; }; ~Texture() { Delete(); } PD_SMART_CTOR(Texture) diff --git a/include/pd/UI7.hpp b/include/pd/UI7.hpp index efc4d02..f949aa3 100644 --- a/include/pd/UI7.hpp +++ b/include/pd/UI7.hpp @@ -1,13 +1,14 @@ #pragma once #include -#include -#include +#include +#include +#include #include #define UI7MAKEFLAG(x) (1 << x) -typedef int UI7MenuFlags; +using UI7MenuFlags = unsigned int; enum UI7MenuFlags_ { UI7MenuFlags_None = 0, @@ -16,6 +17,18 @@ enum UI7MenuFlags_ { UI7MenuFlags_Scrolling = MAKEFLAG(2), }; +enum UI7Horizontal { + UI7Horizontal_Left = 0, + UI7Horizontal_Center = 1, + UI7Horizontal_Right = 2, +}; + +enum UI7Vertical { + UI7Vertical_Top = 0, + UI7Vertical_Center = 1, + UI7Vertical_Bot = 2, +}; + class DrawCmd; class UI7DrawList { public: @@ -35,10 +48,16 @@ class UI7DrawList { void Process(bool auto_clear = true); void Clear(); + int Layer() { return layer; } + void Layer(int v) { layer = v; } + int BaseLayer() { return bl; } + void BaseLayer(int v) { bl = v; } PD_SMART_CTOR(UI7DrawList) private: + int layer = 0; + int bl = 0; void AddDebugCall(std::shared_ptr cmd); std::vector> list; }; @@ -77,10 +96,16 @@ void Grid(const std::string &name, const NVec2 &size, const NVec2 &entry_size, void ColorSelector(const std::string &label, unsigned int &color); bool BeginTree(const std::string &text); void EndTree(); +void Prompt(const std::string &label, int &res, + // For Translations + const std::string &lcf = "Confirm", + const std::string &lcc = "Cancel"); +void ClosePromts(); NVec2 GetCursorPos(); void SetCursorPos(NVec2 cp); void RestoreCursor(); void SameLine(); +void Separator(); // Internal API (For Creating Custom Objects) bool InBox(NVec2 inpos, NVec2 boxpos, NVec2 boxsize); void MoveCursor(NVec2 size); diff --git a/include/pd/Allocator.hpp b/include/pd/base/Allocator.hpp similarity index 100% rename from include/pd/Allocator.hpp rename to include/pd/base/Allocator.hpp diff --git a/include/pd/Color.hpp b/include/pd/base/Color.hpp similarity index 96% rename from include/pd/Color.hpp rename to include/pd/base/Color.hpp index e44cb7a..8e2097c 100644 --- a/include/pd/Color.hpp +++ b/include/pd/base/Color.hpp @@ -1,204 +1,204 @@ -#pragma once -#include - -#include -#include -#include -#include -#include - -#define UNPACK_RGBA(col) \ - (unsigned char)(col >> 24), (col >> 16), (col >> 8), (col) -#define UNPACK_BGRA(col) \ - (unsigned char)(col >> 8), (col >> 16), (col >> 24), (col) - -inline unsigned int RGBA8(unsigned char r, unsigned char g, unsigned char b, - unsigned char a = 255) { - return (r | g << 8 | b << 16 | a << 24); -} - -typedef int PDColor; - -// MultiColor (Less FunctionNameLen) - -struct Color2 { - unsigned int color0; - unsigned int color1; -}; - -struct Color3 { - unsigned int color0; - unsigned int color1; - unsigned int color2; -}; - -struct Color4 { - unsigned int color0; - unsigned int color1; - unsigned int color2; - unsigned int color3; -}; - -enum PDColor_ { - PDColor_Text, ///< This Color Should always be used for Light Backgrounds - PDColor_TextDisabled, /// Text Disabled Color - PDColor_Text2, ///< And This want for Texts on Dark Backgrounds - PDColor_Background, ///< Your Bg Color - PDColor_Header, ///< Header Color (if the header is dark text2 is used) - PDColor_Selector, ///< Selector Color - PDColor_SelectorFade, ///< Selector FadingTo Color - PDColor_List0, ///< List Color1 - PDColor_List1, ///< List Color2 - PDColor_MessageBackground, ///< Message Background - PDColor_Button, ///< Button Color - PDColor_ButtonHovered, ///< Button Color if Hovered - PDColor_ButtonDisabled, ///< Button Color if disabled - PDColor_ButtonActive, ///< Button Colkor if Clicked - PDColor_Checkmark, ///< Checkbox Checkmark Color - PDColor_FrameBg, ///< Frame Background Color - PDColor_FrameBgHovered, ///< Frame Background Color if hovered - PDColor_Progressbar, ///< Progressbar Color - /// NON COLOR /// - PDColor_Len, ///< Used to define the lengh of this list -}; - -namespace Palladium { -class Theme { - public: - Theme() = default; - ~Theme() = default; - - void Load(const std::string &path); - void Default(); - void Save(const std::string &path); - - unsigned int Get(PDColor clr); - void Set(PDColor clr, unsigned int v); - void Swap(PDColor a, PDColor b); - bool Undo(); - void UndoAll(); - void TextBy(PDColor bg); - PDColor AutoText(PDColor bg); - void ClearHistory() { changes.clear(); } - - std::vector &GetTableRef() { return clr_tab; } - // For Smart Pointer - PD_SMART_CTOR(Theme); - - // Loader method - void CopyOther(Theme::Ref theme); - - private: - struct change { - change(PDColor a, unsigned int f, unsigned int t) - : clr(a), from(f), to(t) {} - change(PDColor a, PDColor b, unsigned int f, unsigned int t) - : clr(a), clr2(b), from(f), to(t) {} - PDColor clr; - PDColor clr2 = 0; // Used if Swap - unsigned int from; - unsigned int to; - }; - // Use a vector for faster access - std::vector clr_tab; - std::vector changes; -}; - -Theme::Ref ThemeActive(); -/// @brief Change Theme Adress -/// @param theme your adress -void ThemeSet(Theme::Ref theme); -namespace Color { -/// @brief RGBA Class -class RGBA { - public: - /// @brief Construct - /// @param r - /// @param g - /// @param b - /// @param a - RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255) - : m_r(r), m_g(g), m_b(b), m_a(a) {} - /// @brief Construct - /// @param r - /// @param g - /// @param b - /// @param a - RGBA(float r, float g, float b, float a = 1.f) - : m_r(r * 255.f), m_g(g * 255.f), m_b(b * 255.f), m_a(a * 255.f) {} - RGBA(unsigned int in) { -#define ISIMPLEUNPAK(x, y) (((x) >> y) & 0xFF) - m_r = ISIMPLEUNPAK(in, 0); - m_g = ISIMPLEUNPAK(in, 8); - m_b = ISIMPLEUNPAK(in, 16); - m_a = ISIMPLEUNPAK(in, 24); - } - RGBA(PDColor in) { - if (!Palladium::ThemeActive()) return; - unsigned int col = Palladium::ThemeActive()->Get(in); - m_r = ISIMPLEUNPAK(col, 0); - m_g = ISIMPLEUNPAK(col, 8); - m_b = ISIMPLEUNPAK(col, 16); - m_a = ISIMPLEUNPAK(col, 24); - } - RGBA &changeR(unsigned char r) { - m_r = r; - return *this; - } - RGBA &changeG(unsigned char g) { - m_g = g; - return *this; - } - RGBA &changeB(unsigned char b) { - m_b = b; - return *this; - } - RGBA &changeA(unsigned char a) { - m_a = a; - return *this; - } - - RGBA &fade_to(const RGBA &color, float p) { - m_a = - m_a + static_cast((color.m_a - m_a) * ((p + 1.0f) / 2)); - m_b = - m_b + static_cast((color.m_b - m_b) * ((p + 1.0f) / 2)); - m_g = - m_g + static_cast((color.m_g - m_g) * ((p + 1.0f) / 2)); - m_r = - m_r + static_cast((color.m_r - m_r) * ((p + 1.0f) / 2)); - return *this; - } - - /// @brief Get as Uint32 - /// @return color - unsigned int toRGBA() const { return RGBA8(m_r, m_g, m_b, m_a); } - - // Just calculate the "lightness" f.e. to use Text or Text2 - float luminance() const { - // For Reference https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness - return (0.3 * (m_r / 255.f) + 0.59 * (m_g / 255.f) + 0.11 * (m_b / 255.f)); - } - - bool is_light() { - // Gives us the light or dark to not - // always use the below "if" statement - return (luminance() >= 0.5); - } - - unsigned char m_r = 0, m_g = 0, m_b = 0, m_a = 0; -}; -std::string RGBA2Hex(unsigned int c32); -/// @brief Convert RGB to Hex -/// @param r -/// @param g -/// @param b -/// @return Hex-String -std::string RGB2Hex(int r, int g, int b); -/// @brief Hex to U32 -/// @param color -/// @param a -/// @return Color32 -unsigned int Hex(const std::string &color, unsigned char a = 255); -} // namespace Color -} // namespace Palladium +#pragma once +#include + +#include +#include +#include +#include +#include + +#define UNPACK_RGBA(col) \ + (unsigned char)(col >> 24), (col >> 16), (col >> 8), (col) +#define UNPACK_BGRA(col) \ + (unsigned char)(col >> 8), (col >> 16), (col >> 24), (col) + +inline unsigned int RGBA8(unsigned char r, unsigned char g, unsigned char b, + unsigned char a = 255) { + return (r | g << 8 | b << 16 | a << 24); +} + +typedef int PDColor; + +// MultiColor (Less FunctionNameLen) + +struct Color2 { + unsigned int color0; + unsigned int color1; +}; + +struct Color3 { + unsigned int color0; + unsigned int color1; + unsigned int color2; +}; + +struct Color4 { + unsigned int color0; + unsigned int color1; + unsigned int color2; + unsigned int color3; +}; + +enum PDColor_ { + PDColor_Text, ///< This Color Should always be used for Light Backgrounds + PDColor_TextDisabled, /// Text Disabled Color + PDColor_Text2, ///< And This want for Texts on Dark Backgrounds + PDColor_Background, ///< Your Bg Color + PDColor_Header, ///< Header Color (if the header is dark text2 is used) + PDColor_Selector, ///< Selector Color + PDColor_SelectorFade, ///< Selector FadingTo Color + PDColor_List0, ///< List Color1 + PDColor_List1, ///< List Color2 + PDColor_MessageBackground, ///< Message Background + PDColor_Button, ///< Button Color + PDColor_ButtonHovered, ///< Button Color if Hovered + PDColor_ButtonDisabled, ///< Button Color if disabled + PDColor_ButtonActive, ///< Button Colkor if Clicked + PDColor_Checkmark, ///< Checkbox Checkmark Color + PDColor_FrameBg, ///< Frame Background Color + PDColor_FrameBgHovered, ///< Frame Background Color if hovered + PDColor_Progressbar, ///< Progressbar Color + /// NON COLOR /// + PDColor_Len, ///< Used to define the lengh of this list +}; + +namespace Palladium { +class Theme { + public: + Theme() = default; + ~Theme() = default; + + void Load(const std::string &path); + void Default(); + void Save(const std::string &path); + + unsigned int Get(PDColor clr); + void Set(PDColor clr, unsigned int v); + void Swap(PDColor a, PDColor b); + bool Undo(); + void UndoAll(); + void TextBy(PDColor bg); + PDColor AutoText(PDColor bg); + void ClearHistory() { changes.clear(); } + + std::vector &GetTableRef() { return clr_tab; } + // For Smart Pointer + PD_SMART_CTOR(Theme); + + // Loader method + void CopyOther(Theme::Ref theme); + + private: + struct change { + change(PDColor a, unsigned int f, unsigned int t) + : clr(a), from(f), to(t) {} + change(PDColor a, PDColor b, unsigned int f, unsigned int t) + : clr(a), clr2(b), from(f), to(t) {} + PDColor clr; + PDColor clr2 = 0; // Used if Swap + unsigned int from; + unsigned int to; + }; + // Use a vector for faster access + std::vector clr_tab; + std::vector changes; +}; + +Theme::Ref ThemeActive(); +/// @brief Change Theme Adress +/// @param theme your adress +void ThemeSet(Theme::Ref theme); +namespace Color { +/// @brief RGBA Class +class RGBA { + public: + /// @brief Construct + /// @param r + /// @param g + /// @param b + /// @param a + RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255) + : m_r(r), m_g(g), m_b(b), m_a(a) {} + /// @brief Construct + /// @param r + /// @param g + /// @param b + /// @param a + RGBA(float r, float g, float b, float a = 1.f) + : m_r(r * 255.f), m_g(g * 255.f), m_b(b * 255.f), m_a(a * 255.f) {} + RGBA(unsigned int in) { +#define ISIMPLEUNPAK(x, y) (((x) >> y) & 0xFF) + m_r = ISIMPLEUNPAK(in, 0); + m_g = ISIMPLEUNPAK(in, 8); + m_b = ISIMPLEUNPAK(in, 16); + m_a = ISIMPLEUNPAK(in, 24); + } + RGBA(PDColor in) { + if (!Palladium::ThemeActive()) return; + unsigned int col = Palladium::ThemeActive()->Get(in); + m_r = ISIMPLEUNPAK(col, 0); + m_g = ISIMPLEUNPAK(col, 8); + m_b = ISIMPLEUNPAK(col, 16); + m_a = ISIMPLEUNPAK(col, 24); + } + RGBA &changeR(unsigned char r) { + m_r = r; + return *this; + } + RGBA &changeG(unsigned char g) { + m_g = g; + return *this; + } + RGBA &changeB(unsigned char b) { + m_b = b; + return *this; + } + RGBA &changeA(unsigned char a) { + m_a = a; + return *this; + } + + RGBA &fade_to(const RGBA &color, float p) { + m_a = + m_a + static_cast((color.m_a - m_a) * ((p + 1.0f) / 2)); + m_b = + m_b + static_cast((color.m_b - m_b) * ((p + 1.0f) / 2)); + m_g = + m_g + static_cast((color.m_g - m_g) * ((p + 1.0f) / 2)); + m_r = + m_r + static_cast((color.m_r - m_r) * ((p + 1.0f) / 2)); + return *this; + } + + /// @brief Get as Uint32 + /// @return color + unsigned int toRGBA() const { return RGBA8(m_r, m_g, m_b, m_a); } + + // Just calculate the "lightness" f.e. to use Text or Text2 + float luminance() const { + // For Reference https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness + return (0.3 * (m_r / 255.f) + 0.59 * (m_g / 255.f) + 0.11 * (m_b / 255.f)); + } + + bool is_light() { + // Gives us the light or dark to not + // always use the below "if" statement + return (luminance() >= 0.5); + } + + unsigned char m_r = 0, m_g = 0, m_b = 0, m_a = 0; +}; +std::string RGBA2Hex(unsigned int c32); +/// @brief Convert RGB to Hex +/// @param r +/// @param g +/// @param b +/// @return Hex-String +std::string RGB2Hex(int r, int g, int b); +/// @brief Hex to U32 +/// @param color +/// @param a +/// @return Color32 +unsigned int Hex(const std::string &color, unsigned char a = 255); +} // namespace Color +} // namespace Palladium diff --git a/include/pd/FileSystem.hpp b/include/pd/base/FileSystem.hpp similarity index 96% rename from include/pd/FileSystem.hpp rename to include/pd/base/FileSystem.hpp index ba608e1..e4c0ed4 100644 --- a/include/pd/FileSystem.hpp +++ b/include/pd/base/FileSystem.hpp @@ -1,24 +1,24 @@ -#pragma once -#include -#include - -namespace Palladium { -namespace FileSystem { -/// @brief A Directory Entry -struct Entry { - /// @brief Patf of The Entry - std::string path; - /// @brief Name of The Entry - std::string name; - /// @brief Directory or File - bool dir = false; -}; -/// @brief Gets All Entrys of A Directory into a Vector -/// @param path The Path of the Directory -/// @return The Vector of found Entrys -std::vector GetDirContent(std::string path); -std::string GetParentPath(std::string path, std::string mount_point); -std::vector GetDirContentsExt( - std::string &path, const std::vector &extensions); -} // namespace FileSystem +#pragma once +#include +#include + +namespace Palladium { +namespace FileSystem { +/// @brief A Directory Entry +struct Entry { + /// @brief Patf of The Entry + std::string path; + /// @brief Name of The Entry + std::string name; + /// @brief Directory or File + bool dir = false; +}; +/// @brief Gets All Entrys of A Directory into a Vector +/// @param path The Path of the Directory +/// @return The Vector of found Entrys +std::vector GetDirContent(std::string path); +std::string GetParentPath(std::string path, std::string mount_point); +std::vector GetDirContentsExt( + std::string &path, const std::vector &extensions); +} // namespace FileSystem } // namespace Palladium \ No newline at end of file diff --git a/include/pd/FunctionTrace.hpp b/include/pd/base/FunctionTrace.hpp similarity index 58% rename from include/pd/FunctionTrace.hpp rename to include/pd/base/FunctionTrace.hpp index 51c5308..63d6cce 100644 --- a/include/pd/FunctionTrace.hpp +++ b/include/pd/base/FunctionTrace.hpp @@ -1,76 +1,137 @@ -#pragma once -// Base includes -#include -#include -#include - -// 3ds does not support std::chrono -#include <3ds.h> - -/// @brief 3ds System Ticks per milli second -#define TICKS_PER_MSEC 268111.856 - -#define f2s(x_) #x_ -#define scomb(x1, x2) std::string(x1 + x2) - -namespace Palladium { -namespace Ftrace { -/// @brief Result of FTrace -struct FTRes { - std::string group; ///< Group of the Trace - std::string func_name; ///< Function Name - - uint64_t time_start; ///< when started - uint64_t time_end; ///< when stopped - float time_of; ///< stop - start (how long) - float time_ofm; ///< max time off - bool is_ovl; ///< is displayed in overlay? -}; - -/// @brief Map of Traces -extern std::map pd_traces; - -/// @brief Set a Start TracePoint -/// @param group Set a Group Name -/// @param func_name Set a Function Name -inline void Beg(const std::string& group, const std::string& func_name) { - std::string trace_id = scomb(group, func_name); - auto& trace = pd_traces[trace_id]; - trace.group = group; - trace.func_name = func_name; - trace.time_start = svcGetSystemTick(); -} -/// @brief Set an End TracePoint -/// @param group Set a Group Name -/// @param func_name Set a Function Name -inline void End(const std::string& group, const std::string& func_name) { - std::string trace_id = scomb(group, func_name); - auto& trace = pd_traces[trace_id]; - trace.time_end = svcGetSystemTick(); - if (trace.time_of > trace.time_ofm) trace.time_ofm = trace.time_of; - trace.time_of = - static_cast(trace.time_end - trace.time_start) / TICKS_PER_MSEC; -} -/// @brief Trace a function execution -/// @param group Set a Group Name -/// @param name Set a Function Name -inline void Func(const std::string& group, const std::string& name, - std::function fun) { - if (!fun) return; - Beg(group, name); - fun(); - End(group, name); -} - -/// @brief This Starts an Ftrace and -/// end ist when going out of scope -struct ScopedTrace { - ScopedTrace(std::string g, std::string n) : group(g), name(n) { - Ftrace::Beg(g, n); - } - ~ScopedTrace() { Ftrace::End(group, name); } - std::string group; - std::string name; -}; -} // namespace Ftrace -} // namespace Palladium +#pragma once +// Base includes +#include +#include +#include + +// 3ds does not support std::chrono +#include <3ds.h> + +/// @brief 3ds System Ticks per milli second +#define TICKS_PER_MSEC 268111.856 + +#define f2s(x_) #x_ +#define scomb(x1, x2) std::string(x1 + x2) + +namespace Palladium { +namespace Ftrace { +class TimeStats { + public: + TimeStats(int len) : len(len), values(len, 0) {} + + void Add(float v) { + values[idx] = v; + idx = next_index(idx); + num_values = std::min(num_values + 1, len); + } + + float GetAverage() { + float res = 0.f; + if (!num_values) { + return res; + } + for (int i = 0; i < num_values; ++i) { + res += values[index(i)]; + } + return res / num_values; + } + + float GetMax() { + float res = 0.f; + if (!num_values) { + return res; + } + for (int i = 0; i < num_values; i++) { + res = std::max(res, values[index(i)]); + } + return res; + } + + float GetMin() { + float res = 0.f; + if (!num_values) { + return res; + } + res = values[0]; + for (int i = 0; i < num_values; i++) { + res = std::min(res, values[index(i)]); + } + return res; + } + + const std::vector& GetData() { return values; } + const float& operator[](int i) { return values[index(i)]; } + const size_t GetLen() { return len; } + const size_t GetNumValues() { return num_values; } + + private: + // Indexing Functions for better overview + size_t next_index(size_t current) const { return (current + 1) % len; } + size_t index(size_t v) const { return (idx + len - num_values + v) % len; } + + // Data + int len = 0; + std::vector values; + int idx = 0; + int num_values = 0; +}; +/// @brief Result of FTrace +struct FTRes { + FTRes() : time_start(0), time_end(0), time_of(0.f), is_ovl(false), ts(60) {} + std::string group; ///< Group of the Trace + std::string func_name; ///< Function Name + + uint64_t time_start; ///< when started + uint64_t time_end; ///< when stopped + float time_of; ///< stop - start (how long) + bool is_ovl; ///< is displayed in overlay? + TimeStats ts; ///< Time Stats +}; + +/// @brief Map of Traces +extern std::map pd_traces; + +/// @brief Set a Start TracePoint +/// @param group Set a Group Name +/// @param func_name Set a Function Name +inline void Beg(const std::string& group, const std::string& func_name) { + std::string trace_id = scomb(group, func_name); + auto& trace = pd_traces[trace_id]; + trace.group = group; + trace.func_name = func_name; + trace.time_start = svcGetSystemTick(); +} +/// @brief Set an End TracePoint +/// @param group Set a Group Name +/// @param func_name Set a Function Name +inline void End(const std::string& group, const std::string& func_name) { + std::string trace_id = scomb(group, func_name); + auto& trace = pd_traces[trace_id]; + trace.time_end = svcGetSystemTick(); + trace.time_of = + static_cast(trace.time_end - trace.time_start) / TICKS_PER_MSEC; + trace.ts.Add(trace.time_of); +} +/// @brief Trace a function execution +/// @param group Set a Group Name +/// @param name Set a Function Name +inline void Func(const std::string& group, const std::string& name, + std::function fun) { + if (!fun) return; + Beg(group, name); + fun(); + End(group, name); +} + +/// @brief This Starts an Ftrace and +/// end ist when going out of scope +struct ScopedTrace { + ScopedTrace(std::string g, std::string n) : group(g), name(n) { + Ftrace::Beg(g, n); + } + ~ScopedTrace() { Ftrace::End(group, name); } + std::string group; + std::string name; +}; +} // namespace Ftrace +} // namespace Palladium diff --git a/include/pd/lang.hpp b/include/pd/base/Lang.hpp similarity index 96% rename from include/pd/lang.hpp rename to include/pd/base/Lang.hpp index f63b8e1..c78651d 100644 --- a/include/pd/lang.hpp +++ b/include/pd/base/Lang.hpp @@ -1,24 +1,24 @@ -#pragma once -// clang-format off -#include -#include -// clang-format on - -namespace Palladium { -namespace Lang { -/// @brief Get 3ds System lang! [en] by default -/// @return Sytemlang as string -std::string GetSys(); -/// @brief Get The Translation String -/// @param key Key of Translation -/// @return The Translated String -std::string Get(const std::string &key); -/// @brief Load A Language json -/// @param lang The Language Key [en], [de], etc, or getSys() -void Load(const std::string &lang); -// New funcs -std::string GetName(); -std::string GetAuthor(); -std::string GetShortcut(); -} // namespace Lang -} // namespace Palladium +#pragma once +// clang-format off +#include +#include +// clang-format on + +namespace Palladium { +namespace Lang { +/// @brief Get 3ds System lang! [en] by default +/// @return Sytemlang as string +std::string GetSys(); +/// @brief Get The Translation String +/// @param key Key of Translation +/// @return The Translated String +std::string Get(const std::string &key); +/// @brief Load A Language json +/// @param lang The Language Key [en], [de], etc, or getSys() +void Load(const std::string &lang); +// New funcs +std::string GetName(); +std::string GetAuthor(); +std::string GetShortcut(); +} // namespace Lang +} // namespace Palladium diff --git a/include/pd/Memory.hpp b/include/pd/base/Memory.hpp similarity index 96% rename from include/pd/Memory.hpp rename to include/pd/base/Memory.hpp index 70868c1..b2badba 100644 --- a/include/pd/Memory.hpp +++ b/include/pd/base/Memory.hpp @@ -1,26 +1,26 @@ -#pragma once - -#include - -namespace Palladium { -namespace Memory { -/// @brief Metriks struct For the Internal Tracker -struct memory_metrics { - unsigned int t_TotalAllocated = 0; ///< Total Allocated Memory - unsigned int t_TotalFreed = 0; ///< Total Deleted Memory - /// @brief Gets the Currently Allocated Memory - unsigned int t_CurrentlyAllocated() { - return t_TotalAllocated - t_TotalFreed; - } -}; -/// @brief Get Total Allocated Memory -/// @return Total Allocated Memory -size_t GetTotalAllocated(); -/// @brief Get Total Deleted Memory -/// @return Total Deleted Memory -size_t GetTotalFreed(); -/// @brief Get Current Allocated Memory -/// @return Current Allocated Memory -size_t GetCurrent(); -} // namespace Memory -} // namespace Palladium +#pragma once + +#include + +namespace Palladium { +namespace Memory { +/// @brief Metriks struct For the Internal Tracker +struct memory_metrics { + unsigned int t_TotalAllocated = 0; ///< Total Allocated Memory + unsigned int t_TotalFreed = 0; ///< Total Deleted Memory + /// @brief Gets the Currently Allocated Memory + unsigned int t_CurrentlyAllocated() { + return t_TotalAllocated - t_TotalFreed; + } +}; +/// @brief Get Total Allocated Memory +/// @return Total Allocated Memory +size_t GetTotalAllocated(); +/// @brief Get Total Deleted Memory +/// @return Total Deleted Memory +size_t GetTotalFreed(); +/// @brief Get Current Allocated Memory +/// @return Current Allocated Memory +size_t GetCurrent(); +} // namespace Memory +} // namespace Palladium diff --git a/include/pd/stringtool.hpp b/include/pd/base/stringtool.hpp similarity index 77% rename from include/pd/stringtool.hpp rename to include/pd/base/stringtool.hpp index ecb4f9d..3b29e85 100644 --- a/include/pd/stringtool.hpp +++ b/include/pd/base/stringtool.hpp @@ -1,103 +1,98 @@ -#pragma once -#include -#include -#include -#include - -namespace Palladium { -/// @brief Check if A String ends with -/// @param name Input String -/// @param extensions Extensions to Check for -/// @return Ends with or not -inline bool NameIsEndingWith(const std::string &name, - const std::vector &extensions) { - if (name.substr(0, 2) == "._") return false; - - if (name.size() == 0) return false; - - if (extensions.size() == 0) return true; - - for (int i = 0; i < (int)extensions.size(); i++) { - const std::string ext = extensions.at(i); - if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) - return true; - } - - return false; -} -/// @brief Format Milliseconds to clean string (Stolen from one of my Mc -/// Plugins) -/// @param t_time Time in ms -/// @return String -inline std::string MsTimeFmt(float t_time, bool dems = false) { - std::ostringstream oss; - - if (t_time < 0.001f) { - oss << std::fixed << std::setprecision(2) << t_time * 1000.0f << "ns"; - } else if (t_time < 1.0f) { - oss << std::fixed << std::setprecision(2) << t_time << "ms"; - } else if (t_time < 60000.0f) { - int seconds = static_cast(t_time / 1000.0f); - float milliseconds = t_time - (seconds * 1000.0f); - - if (seconds > 0) { - oss << seconds << "s "; - } - if (!dems) - oss << std::fixed << std::setprecision(2) << milliseconds << "ms"; - } else { - int minutes = static_cast(t_time / 60000.0f); - int seconds = static_cast((t_time - (minutes * 60000.0f)) / 1000.0f); - float milliseconds = t_time - (minutes * 60000.0f) - (seconds * 1000.0f); - - oss << minutes << "m "; - if (seconds > 0 || milliseconds > 0.0f) { - oss << seconds << "s "; - } - if (milliseconds > 0.0f && !dems) { - oss << std::fixed << std::setprecision(2) << milliseconds << "ms"; - } - } - - return oss.str(); -} - -inline std::string FormatBytes(int bytes) { - char out[32]; - - if (bytes == 1) - snprintf(out, sizeof(out), "%d Byte", bytes); - - else if (bytes < 1024) - snprintf(out, sizeof(out), "%d Bytes", bytes); - - else if (bytes < 1024 * 1024) - snprintf(out, sizeof(out), "%.1f KB", (float)bytes / 1024); - - else if (bytes < 1024 * 1024 * 1024) - snprintf(out, sizeof(out), "%.1f MB", (float)bytes / 1024 / 1024); - - else - snprintf(out, sizeof(out), "%.1f GB", (float)bytes / 1024 / 1024 / 1024); - - return out; -} -} // namespace Palladium - -template -T GetFileName(T const &path, T const &delims = "/\\") { - return path.substr(path.find_last_of(delims) + 1); -} -template -T remove_ext(T const &filename) { - typename T::size_type const p(filename.find_last_of('.')); - return p > 0 && p != T::npos ? filename.substr(0, p) : filename; -} - -template -std::string Int_To_Hex(T i) { - std::stringstream stream; - stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex - << i; - return stream.str(); +#pragma once +#include +#include +#include +#include +#include + +namespace Palladium { +/// @brief Check if A String ends with +/// @param name Input String +/// @param extensions Extensions to Check for +/// @return Ends with or not +inline bool NameIsEndingWith(const std::string &name, + const std::vector &extensions) { + if (name.substr(0, 2) == "._") return false; + + if (name.size() == 0) return false; + + if (extensions.size() == 0) return true; + + for (int i = 0; i < (int)extensions.size(); i++) { + const std::string ext = extensions.at(i); + if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) + return true; + } + + return false; +} +/// @brief Format Milliseconds to clean string (Stolen from one of my Mc +/// Plugins) +/// @param t_time Time in ms +/// @return String +inline std::string MsTimeFmt(float t_time, bool dems = false) { + std::string res; + + if (t_time < 0.000001f) { + res = std::format("{:.2f}ns", t_time * 1000000.f); + } else if (t_time < 0.001f) { + res = std::format("{:.2f}µs", t_time * 1000.f); + } else if (t_time < 1.0f) { + res = std::format("{:.2f}ms", t_time); + } else if (t_time < 60000.0f) { + int seconds = static_cast(t_time / 1000.0f); + float milliseconds = t_time - (seconds * 1000.0f); + if (seconds) { + res = std::format("{}s {:.2f}ms", seconds, milliseconds); + } + res = std::format("{:.2f}ms", milliseconds); + } else { + int minutes = static_cast(t_time / 60000.0f); + int seconds = static_cast((t_time - (minutes * 60000.0f)) / 1000.0f); + float milliseconds = t_time - (minutes * 60000.0f) - (seconds * 1000.0f); + + res = std::format("{}m {}s {:.2f}ms", minutes, seconds, milliseconds); + } + + return res; +} + +inline std::string FormatBytes(int bytes) { + char out[32]; + + if (bytes == 1) + snprintf(out, sizeof(out), "%d Byte", bytes); + + else if (bytes < 1024) + snprintf(out, sizeof(out), "%d Bytes", bytes); + + else if (bytes < 1024 * 1024) + snprintf(out, sizeof(out), "%.1f KB", (float)bytes / 1024); + + else if (bytes < 1024 * 1024 * 1024) + snprintf(out, sizeof(out), "%.1f MB", (float)bytes / 1024 / 1024); + + else + snprintf(out, sizeof(out), "%.1f GB", (float)bytes / 1024 / 1024 / 1024); + + return out; +} +} // namespace Palladium + +template +T GetFileName(T const &path, T const &delims = "/\\") { + return path.substr(path.find_last_of(delims) + 1); +} +template +T remove_ext(T const &filename) { + typename T::size_type const p(filename.find_last_of('.')); + return p > 0 && p != T::npos ? filename.substr(0, p) : filename; +} + +template +std::string Int_To_Hex(T i) { + std::stringstream stream; + stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex + << i; + return stream.str(); } \ No newline at end of file diff --git a/include/pd/global_db.hpp b/include/pd/global_db.hpp index 1a2ba0b..ea4cc8f 100644 --- a/include/pd/global_db.hpp +++ b/include/pd/global_db.hpp @@ -11,7 +11,7 @@ void Restart(); } // namespace IDB } // namespace Palladium -using PDFlags = int; +using PDFlags = unsigned int; enum PDFlags_ { PDFlags_None = 0, PDFlags_MemTrack = 1 << 0, @@ -19,6 +19,47 @@ enum PDFlags_ { PDFlags_Default = PDFlags_SceneSystem, }; +using PDMetrikOverlayFlags = unsigned int; +enum PDMetrikOverlayFlags_ { + PDMetrikOverlayFlags_None = 0, // Displays Nothing + PDMetrikOverlayFlags_FPS = 1 << 0, // Display FPS + PDMetrikOverlayFlags_CPU = 1 << 1, // Display CPU Usage + PDMetrikOverlayFlags_GPU = 1 << 2, // Display GPU Usage + PDMetrikOverlayFlags_CMD = 1 << 3, // Display GPU CMD Usage + PDMetrikOverlayFlags_LMM = 1 << 4, // Display Linear Space Free + PDMetrikOverlayFlags_LVT = 1 << 5, // Display Lithium Vertex Usage + PDMetrikOverlayFlags_LID = 1 << 6, // Display Lithium Indices Usage + PDMetrikOverlayFlags_LDM = 1 << 7, // Display Lithium Draw Command Num + PDMetrikOverlayFlags_LDC = 1 << 8, // Display Lithium Drawcalls Count + PDMetrikOverlayFlags_PDO = 1 << 9, // Display Overlay Info String + PDMetrikOverlayFlags_MTD = 1 << 10, // Display Memory Usage (if enabled) + PDMetrikOverlayFlags_CGR = 1 << 11, // Display CPU Graph + PDMetrikOverlayFlags_GGR = 1 << 12, // Display GPU Graph + PDMetrikOverlayFlags_Default = + PDMetrikOverlayFlags_FPS | PDMetrikOverlayFlags_CPU | + PDMetrikOverlayFlags_GPU | PDMetrikOverlayFlags_CMD | + PDMetrikOverlayFlags_LMM | PDMetrikOverlayFlags_LVT | + PDMetrikOverlayFlags_LID | PDMetrikOverlayFlags_LDM | + PDMetrikOverlayFlags_LDC | PDMetrikOverlayFlags_PDO | + PDMetrikOverlayFlags_MTD, // Enable All of Them exept Graphs +}; + +using PDFTraceOverlayFlags = unsigned int; +enum PDFTraceOverlayFlags_ { + PDFTraceOverlayFlags_None = 0, // Displays Nothing + PDFTraceOverlayFlags_DisplayName = 1 << 0, // Display Tracename + PDFTraceOverlayFlags_DisplayAverage = 1 << 1, // Display Average Time + PDFTraceOverlayFlags_DisplayMin = 1 << 2, // Display Minimum Time + PDFTraceOverlayFlags_DisplayMax = 1 << 3, // Display Maximum Time + PDFTraceOverlayFlags_FillBg = 1 << 4, // Make Background Darker + PDFTraceOverlayFlags_DisplayHelp = 1 << 5, // Display Info for values + PDFTraceOverlayFlags_Default = + PDFTraceOverlayFlags_DisplayName | PDFTraceOverlayFlags_DisplayAverage | + PDFTraceOverlayFlags_DisplayMin | PDFTraceOverlayFlags_DisplayMax | + PDFTraceOverlayFlags_FillBg | + PDFTraceOverlayFlags_DisplayHelp, // Enable All of Them +}; + // Outdated HidApi (HidV2Patched) extern u32 d7_hDown; extern u32 d7_hHeld; @@ -27,11 +68,11 @@ extern u32 d7_hRepeat; // Inofficial lol extern touchPosition d7_touch; // Modern Global Api -extern int pd_max_objects; extern C3D_RenderTarget *pd_top; extern C3D_RenderTarget *pd_top_right; extern C3D_RenderTarget *pd_bottom; extern PDFlags pd_flags; - +extern PDMetrikOverlayFlags pd_ovl_flags; +extern PDFTraceOverlayFlags pd_ftrace_ovl_flags; // Draw2 extern float pd_draw2_tsm; \ No newline at end of file diff --git a/include/pd/internal_db.hpp b/include/pd/internal_db.hpp index e929955..aaeee35 100644 --- a/include/pd/internal_db.hpp +++ b/include/pd/internal_db.hpp @@ -4,7 +4,7 @@ #include #include -#define CFGVER "1" +#define CFGVER "2" #define THEMEVER "0" #ifndef V_PDBTIME @@ -26,9 +26,6 @@ extern u8 pdi_system_region; extern bool pdi_is_citra; extern bool pdi_settings; extern NVec2 pdi_hid_touch_pos; -extern C2D_TextBuf pdi_text_buffer; -extern C2D_TextBuf pdi_d2_dimbuf; -extern C2D_Font pdi_base_font; extern bool pdi_is_ndsp; extern bool pdi_running; extern std::unique_ptr pdi_fade_scene; @@ -36,8 +33,8 @@ extern std::vector> pdi_overlays; extern unsigned int pdi_frames; extern u64 pdi_last_time; extern float pdi_framerate; -extern u32 pdi_mt_color; -extern u32 pdi_mt_txtcolor; +extern unsigned int pdi_mt_color; +extern unsigned int pdi_mt_txtcolor; extern bool pdi_mt_screen; extern float pdi_mt_txtSize; extern bool pdi_metrikd; @@ -63,7 +60,5 @@ extern bool pdi_is_am_init; extern Palladium::Theme::Ref pdi_active_theme; extern bool pdi_lggrf; -// Use function for protection -Palladium::LoggerBase::Ref _pdi_logger(); Palladium::Net::Error pdi_soc_init(); void pdi_soc_deinit(); \ No newline at end of file diff --git a/include/pd/maths/NMat.hpp b/include/pd/maths/NMat.hpp new file mode 100644 index 0000000..d24053c --- /dev/null +++ b/include/pd/maths/NMat.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include + +class NMat4 { + public: + NMat4() { Zeros(); } + ~NMat4() {} + + void Zeros() { memset(this, 0, sizeof(*this)); } + void Identity() { Diagonal(NVec4(1.f, 1.f, 1.f, 1.f)); } + void Diagonal(NVec4 xyzw) { + Zeros(); + r[0][0] = xyzw[0]; + r[1][1] = xyzw[1]; + r[2][2] = xyzw[2]; + r[3][3] = xyzw[3]; + } + NMat4& Get() { return *this; } + void Add(const NMat4& in) { + for (int i = 0; i < 0x10; i++) { + m[i] += in[i]; + } + } + void Sub(const NMat4& in) { + for (int i = 0; i < 0x10; i++) { + m[i] -= in[i]; + } + } + void Mul(const NMat4& in) { + + } + + void Transpose(); + float Inverse(); + + // Operators + float operator[](int i) const { return m[i]; } + float& operator[](int i) { return m[i]; } + + union { + NVec4 r[4]; + float m[0x10]; + }; +}; \ No newline at end of file diff --git a/include/pd/maths/NVec.hpp b/include/pd/maths/NVec.hpp new file mode 100644 index 0000000..dd82fc1 --- /dev/null +++ b/include/pd/maths/NVec.hpp @@ -0,0 +1,366 @@ +#pragma once + +#include + +struct NVec2 { + // Init Funcs + NVec2() { + v[0] = 0; + v[1] = 0; + } + NVec2(float x, float y) { + v[0] = x; + v[1] = y; + } + NVec2(const NVec2 &i) { + v[0] = i[0]; + v[1] = i[1]; + } + NVec2(float i) { + v[0] = i; + v[1] = i; + } + + // Operations + // Add + NVec2 &operator+=(const NVec2 &i) { + v[0] += i[0]; + v[1] += i[1]; + return *this; + } + + NVec2 &operator+=(const float &i) { + v[0] += i; + v[1] += i; + return *this; + } + + NVec2 operator+(const NVec2 &i) const { + return NVec2(v[0] + i[0], v[1] + i[1]); + } + NVec2 operator+(const float &i) const { return NVec2(v[0] + i, v[1] + i); } + + // Sub + NVec2 &operator-=(const NVec2 &i) { + v[0] -= i[0]; + v[1] -= i[1]; + return *this; + } + + NVec2 &operator-=(const float &i) { + v[0] -= i; + v[1] -= i; + return *this; + } + + NVec2 operator-(const NVec2 &i) const { + return NVec2(v[0] - i[0], v[1] - i[1]); + } + NVec2 operator-(const float &i) const { return NVec2(v[0] - i, v[1] - i); } + + // Mul + NVec2 &operator*=(const NVec2 &i) { + v[0] *= i[0]; + v[1] *= i[1]; + return *this; + } + + NVec2 &operator*=(const float &i) { + v[0] *= i; + v[1] *= i; + return *this; + } + + NVec2 operator*(const NVec2 &i) const { + return NVec2(v[0] * i[0], v[1] * i[1]); + } + NVec2 operator*(const float &i) const { return NVec2(v[0] * i, v[1] * i); } + + // Div + NVec2 &operator/=(const NVec2 &i) { + v[0] /= i[0]; + v[1] /= i[1]; + return *this; + } + + NVec2 &operator/=(const float &i) { + v[0] /= i; + v[1] /= i; + return *this; + } + + NVec2 operator/(const NVec2 &i) const { + return NVec2(v[0] / i[0], v[1] / i[1]); + } + NVec2 operator/(const float &i) const { return NVec2(v[0] / i, v[1] / i); } + + // Compare + bool operator==(const NVec2 &in) const { + return v[0] == in[0] && v[1] == in[1]; + } + + bool operator!=(const NVec2 &in) const { + // use the first comparefuncs result + // and swap it lol + return !(*this == in); + } + + NVec2 operator-() const { return NVec2(-v[0], -v[1]); } + float operator[](int i) const { return v[i]; } + float &operator[](int i) { return v[i]; } + + float len() const { return sqrt(sqlen()); } + float sqlen() const { return v[0] * v[0] + v[1] * v[1]; } + + float x() const { return v[0]; } + float &x() { return v[0]; } + float y() const { return v[1]; } + float &y() { return v[1]; } + // Internal Values + float v[2]; +}; + +struct NVec3 { + // Init Funcs + NVec3() { + v[0] = 0.f; + v[1] = 0.f; + v[2] = 0.f; + } + NVec3(float x, float y, float z) { + v[0] = x; + v[1] = y; + v[2] = z; + } + NVec3(const NVec3 &i) { + v[0] = i[0]; + v[1] = i[1]; + v[2] = i[2]; + } + NVec3(float i) { + v[0] = i; + v[1] = i; + v[2] = i; + } + + // Operations + // Add + NVec3 &operator+=(const NVec3 &i) { + v[0] += i[0]; + v[1] += i[1]; + v[2] += i[2]; + return *this; + } + + NVec3 &operator+=(const float &i) { + v[0] += i; + v[1] += i; + v[2] += i; + return *this; + } + + NVec3 operator+(const NVec3 &i) const { + return NVec3(v[0] + i[0], v[1] + i[1], v[2] + i[2]); + } + NVec3 operator+(const float &i) const { + return NVec3(v[0] + i, v[1] + i, v[2] + i); + } + + // Sub + NVec3 &operator-=(const NVec3 &i) { + v[0] -= i[0]; + v[1] -= i[1]; + v[2] -= i[2]; + return *this; + } + + NVec3 &operator-=(const float &i) { + v[0] -= i; + v[1] -= i; + v[2] -= i; + return *this; + } + + NVec3 operator-(const NVec3 &i) const { + return NVec3(v[0] - i[0], v[1] - i[1], v[2] - i[2]); + } + NVec3 operator-(const float &i) const { + return NVec3(v[0] - i, v[1] - i, v[2] - i); + } + + // Mul + NVec3 &operator*=(const NVec3 &i) { + v[0] *= i[0]; + v[1] *= i[1]; + v[2] *= i[2]; + return *this; + } + + NVec3 &operator*=(const float &i) { + v[0] *= i; + v[1] *= i; + v[2] *= i; + return *this; + } + + NVec3 operator*(const NVec3 &i) const { + return NVec3(v[0] * i[0], v[1] * i[1], v[2] * i[2]); + } + NVec3 operator*(const float &i) const { + return NVec3(v[0] * i, v[1] * i, v[2] * i); + } + + // Div + NVec3 &operator/=(const NVec3 &i) { + v[0] /= i[0]; + v[1] /= i[1]; + v[2] /= i[2]; + return *this; + } + + NVec3 &operator/=(const float &i) { + v[0] /= i; + v[1] /= i; + v[2] /= i; + return *this; + } + + NVec3 operator/(const NVec3 &i) const { + return NVec3(v[0] / i[0], v[1] / i[1], v[2] / i[2]); + } + NVec3 operator/(const float &i) const { + return NVec3(v[0] / i, v[1] / i, v[2] / i); + } + + // Compare + bool operator==(const NVec3 &in) const { + return v[0] == in[0] && v[1] == in[1] && v[2] == v[2]; + } + + bool operator!=(const NVec3 &in) const { + // use the first comparefuncs result + // and swap it lol + return !(*this == in); + } + + // Base + NVec3 operator-() const { return NVec3(-v[0], -v[1], -v[2]); } + float operator[](int i) const { return v[i]; } + float &operator[](int i) { return v[i]; } + + float len() const { return sqrt(sqlen()); } + float sqlen() const { return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; } + + float x() const { return v[0]; } + float &x() { return v[0]; } + float y() const { return v[1]; } + float &y() { return v[1]; } + float z() const { return v[2]; } + float &z() { return v[2]; } + + float v[3]; +}; + +struct NVec4 { + // Init Funcs + NVec4() { + v[0] = 0.f; + v[1] = 0.f; + v[2] = 0.f; + v[3] = 0.f; + } + NVec4(float x, float y, float z, float w) { + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = w; + } + NVec4(const NVec4 &i) { + v[0] = i[0]; + v[1] = i[1]; + v[2] = i[2]; + v[3] = i[3]; + } + + NVec4(const NVec2 &i0, const NVec2 &i1) { + v[0] = i0[0]; + v[1] = i0[1]; + v[2] = i1[0]; + v[3] = i1[1]; + } + NVec4(float i) { + v[0] = i; + v[1] = i; + v[2] = i; + v[3] = i; + } + + // Operators + // Add + NVec4 &operator+=(const NVec4 &i) { + v[0] += i[0]; + v[1] += i[1]; + v[2] += i[2]; + v[3] += i[3]; + return *this; + } + + NVec4 operator+(const NVec4 &i) const { + return NVec4(v[0] + i[0], v[1] + i[1], v[2] + i[2], v[3] + i[3]); + } + + // Sub + NVec4 &operator-=(const NVec4 &i) { + v[0] -= i[0]; + v[1] -= i[1]; + v[2] -= i[2]; + v[3] -= i[3]; + return *this; + } + + NVec4 operator-(const NVec4 &i) const { + return NVec4(v[0] - i[0], v[1] - i[1], v[2] - i[2], v[3] - i[3]); + } + + // Compare + bool operator==(const NVec4 &in) const { + return v[0] == in[0] && v[1] == in[1] && v[2] == in[2] && v[3] == in[3]; + } + + bool operator!=(const NVec4 &in) const { + // use the first comparefuncs result + // and swap it lol + return !(*this == in); + } + + // Base + NVec3 operator-() const { return NVec3(-v[0], -v[1], -v[2]); } + float operator[](int i) const { return v[i]; } + float &operator[](int i) { return v[i]; } + + float len() const { return sqrt(sqlen()); } + float sqlen() const { + return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]; + } + + // Vec Acess + float x() const { return v[0]; } + float &x() { return v[0]; } + float y() const { return v[1]; } + float &y() { return v[1]; } + float z() const { return v[2]; } + float &z() { return v[2]; } + float w() const { return v[3]; } + float &w() { return v[3]; } + // Quaternion Acess + float r() const { return v[0]; } + float &r() { return v[0]; } + float k() const { return v[1]; } + float &k() { return v[1]; } + float j() const { return v[2]; } + float &j() { return v[2]; } + float i() const { return v[3]; } + float &i() { return v[3]; } + // Internal Values + float v[4]; +}; \ No newline at end of file diff --git a/include/pd/palladium.hpp b/include/pd/palladium.hpp index 54ae5e5..6578520 100644 --- a/include/pd/palladium.hpp +++ b/include/pd/palladium.hpp @@ -13,26 +13,21 @@ #include /// 3ds Includes #include <3ds.h> -#include #include /// Palladium Includes -#include -#include +#include +#include #include -#include -#include +#include #include #include -#include #include -#include #include -#include #include #include -#include +#include #include -#include +#include #include #define PDVSTRING "1.0.0" @@ -43,8 +38,6 @@ extern int pd_max_objects; namespace Palladium { -// Reference to Global Logger -LoggerBase::Ref Logger(); /// @brief Get Deltatime /// @return Deltatime float GetDeltaTime(); diff --git a/source/Error.cpp b/source/Error.cpp index 36af39c..d1bc231 100644 --- a/source/Error.cpp +++ b/source/Error.cpp @@ -4,6 +4,7 @@ #include #include #include +#include void pdi_save_report(const std::string& msg) { auto ts = Palladium::GetTimeStr(); @@ -27,17 +28,16 @@ void Error(const std::string& msg) { C3D_RenderTargetClear(pd_top, C3D_CLEAR_ALL, 0x00000000, 0); C3D_RenderTargetClear(pd_top_right, C3D_CLEAR_ALL, 0x00000000, 0); C3D_RenderTargetClear(pd_bottom, C3D_CLEAR_ALL, 0x00000000, 0); - Palladium::R2::OnScreen(R2Screen_Top); + Palladium::LI::OnScreen(false); if (UI7::BeginMenu("Palladium - Error Manager", NVec2(), UI7MenuFlags_TitleMid)) { UI7::Label(msg); UI7::Label("Press Start to Exit!"); UI7::EndMenu(); } - Palladium::R2::OnScreen(R2Screen_Bottom); + Palladium::LI::OnScreen(true); UI7::Update(); - Palladium::R2::Process(); - Palladium::LI7::Render(pd_top, pd_bottom); + Palladium::LI::Render(pd_top, pd_bottom); C3D_FrameEnd(0); } exit(0); diff --git a/source/Image.cpp b/source/Image.cpp index 941418e..2eb8bb5 100644 --- a/source/Image.cpp +++ b/source/Image.cpp @@ -22,14 +22,14 @@ void Image::From_NIMG(const nimg &image) { Texture::Ref Image::Get() { if (!Loadet()) { - _pdi_logger()->Write("Image not Loadet!"); + return nullptr; } return img; } void Image::Set(Texture::Ref i, NVec4 uvs) { Delete(); - if(uvs.x != -1) custom_uvs = uvs; + if(uvs.x() != -1) custom_uvs = uvs; img = i; } diff --git a/source/LI7.cpp b/source/LI7.cpp deleted file mode 100644 index fdf1f1b..0000000 --- a/source/LI7.cpp +++ /dev/null @@ -1,489 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif - -namespace Palladium { -const float LI7::m_dffs = 24.f; -const float LI7::m_dts = 0.7f; -float LI7::m_txt_scale = 0.7f; -int LI7::m_uLoc_proj; -float LI7::m_scale = 1.0f; -int LI7::m_width, LI7::m_height; -int LI7::m_d_vertices = 0; -int LI7::m_d_drawcalls = 0; -int LI7::m_d_commands = 0; -const int LI7::m_char_height = 8; // Constant -// UI Stuff -std::vector LI7::m_top_draw_cmds; -std::vector LI7::m_bot_draw_cmds; -Texture::Ref LI7::m_current_texture; -Texture::Ref LI7::m_white; -std::vector> LI7::m_vtx_list[2]; -// LI7::Font *LI7::m_font; -LIFont::Ref LI7::m_font; -std::vector LI7::m_text_buffer; -// Ctx Stuff -bool LI7::m_bottom_active = false; -// Shader -DVLB_s* LI7::li7_dvlb; -shaderProgram_s LI7::li7_prog; -C3D_AttrInfo LI7::li7_attr; - -void LIFont::LoadTFF(const std::string path, int px_size) { - Palladium::Ftrace::ScopedTrace st( - "LIFont", std::filesystem::path(path).filename().string()); - this->pixel_height = px_size; - if (!Palladium::FS::FileExist(path)) return; - int type = px_size * 16; - // Load TTF - stbtt_fontinfo inf; - std::ifstream loader(path, std::ios::binary); - if (!loader.is_open()) return; - loader.seekg(0, std::ios::end); - size_t len = loader.tellg(); - loader.seekg(0, std::ios::beg); - unsigned char* buffer = new unsigned char[len]; - loader.read(reinterpret_cast(buffer), len); - loader.close(); - stbtt_InitFont(&inf, buffer, 0); - std::vector fmap(type * type * 4); - float scale = stbtt_ScaleForPixelHeight(&inf, pixel_height); - - int ascent, descent, lineGap; - stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap); - int baseline = static_cast(ascent * scale); - - name = path; - auto ftex = Texture::New(); - NVec2 offset; - for (int c = 0; c < 255; c++) { - CPI codepoint; - if (stbtt_IsGlyphEmpty(&inf, c)) { - codepoint.codepoint = c; - codepoint.tex = ftex; - cpmap.push_back(codepoint); - continue; - } - - int width, height, xOffset, yOffset; - unsigned char* bitmap = stbtt_GetCodepointBitmap( - &inf, scale, scale, c, &width, &height, &xOffset, &yOffset); - int x0, y0, x1, y1; - stbtt_GetCodepointBitmapBox(&inf, c, scale, scale, &x0, &y0, &x1, &y1); - - if (offset.x + width > type) { - offset.y += pixel_height; - offset.x = 0; - } - - codepoint.uv.x = static_cast((float)offset.x / (float)type); - codepoint.uv.y = 1.0f - static_cast((float)offset.y / (float)type); - codepoint.uv.z = - static_cast(float(offset.x + width) / (float)type); - codepoint.uv.w = - 1.0f - static_cast(float(offset.y + height) / (float)type); - - codepoint.tex = ftex; - codepoint.szs.x = width; - codepoint.szs.y = height; - codepoint.off = baseline + yOffset; - - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - int map_pos = ((offset.y + y) * type + (offset.x + x)) * 4; - - fmap[map_pos + 0] = 255; - fmap[map_pos + 1] = 255; - fmap[map_pos + 2] = 255; - fmap[map_pos + 3] = bitmap[x + y * width]; - } - } - offset.x += width; - if (offset.x + width > type) { - offset.y += pixel_height; - offset.x = 0; - } - free(bitmap); - cpmap.push_back(codepoint); - } - ftex->LoadPixels(fmap, type, type); - this->tex.push_back(ftex); -} - -void LIFont::LoadBitmapFont(const std::string& path) {} - -void LIFont::LoadSystemFont() { - name = "System Font"; - float text_scale = 0.f; - // Code to Load the System Font - const auto fnt = fontGetSystemFont(); - const auto fnt_info = fontGetInfo(fnt); - const auto glyph_info = fontGetGlyphInfo(fnt); - this->tex.resize(glyph_info->nSheets + 1); - text_scale = 30.f / glyph_info->cellHeight; - for (size_t i = 0; i < glyph_info->nSheets; i++) { - auto tex = this->tex[i]; - tex = Texture::New(); - auto tx = new C3D_Tex; - tx->data = fontGetGlyphSheetTex(fnt, i); - tx->fmt = (GPU_TEXCOLOR)glyph_info->sheetFmt; - tx->size = glyph_info->sheetSize; - tx->width = glyph_info->sheetWidth; - tx->height = glyph_info->sheetHeight; - tx->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | - GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) | - GPU_TEXTURE_WRAP_S(GPU_REPEAT) | GPU_TEXTURE_WRAP_T(GPU_REPEAT); - tx->border = 0xffffffff; - tx->lodParam = 0; - tex->ExternalLoad(tx, NVec2(tx->width, tx->height), NVec4(0, 1, 1, 0)); - } -} - -int LIFont::GetPixelHeight() { return this->pixel_height; } - -LIFont::CPI LIFont::GetCodepoint(char c) { return cpmap[c]; } - -void LIFont::Dump() { - std::ofstream ofs("sdmc:/font.txt", std::ios::out); - ofs << "LI7 Font Dump" << std::endl; - ofs << "Pixel Height: " << (int)pixel_height << std::endl; - for (auto& it : this->cpmap) { - ofs << " Codepoint: " << (int)it.codepoint << std::endl; - ofs << " Width: " << (int)it.szs.x << std::endl; - ofs << " UV: (" << (float)it.uv.x << ", " << (float)it.uv.y << ", " - << (float)it.uv.z << ", " << (float)it.uv.w << ")" << std::endl; - } - ofs.close(); -} - -void LI7::Init() { - m_text_buffer.resize(1024); - m_vtx_list[0].reserve(2 * 4096); - m_vtx_list[1].reserve(2 * 4096); - - li7_dvlb = DVLB_ParseFile((u32*)li7_shader, li7_shader_size); - shaderProgramInit(&li7_prog); - shaderProgramSetVsh(&li7_prog, &li7_dvlb->DVLE[0]); - m_uLoc_proj = - shaderInstanceGetUniformLocation(li7_prog.vertexShader, "projection"); - - AttrInfo_Init(&li7_attr); - AttrInfo_AddLoader(&li7_attr, 0, GPU_FLOAT, 3); - AttrInfo_AddLoader(&li7_attr, 1, GPU_FLOAT, 2); - AttrInfo_AddLoader(&li7_attr, 2, GPU_UNSIGNED_BYTE, 4); - - m_white = Texture::New(); - std::vector pixels(16 * 16 * 4, 255); - m_white->LoadPixels(pixels, 16, 16); - // C3D_Tex* w = new C3D_Tex; - // C3D_TexInit(w, 16, 16, GPU_L8); - // C3D_TexLoadImage(w, pixels.data(), GPU_TEXFACE_2D, 0); - // m_white->ExternalLoad(w, NVec2(16, 16), NVec4(0, 1, 1, 0)); - - m_font = LIFont::New(); - // m_font->LoadSystemFont(); - m_font->LoadTFF("romfs:/fonts/ComicNeue.ttf", 32); -} - -void LI7::Exit() { - shaderProgramFree(&li7_prog); - DVLB_Free(li7_dvlb); -} - -void LI7::OnScreen(bool bottom) { - m_width = bottom ? 320 : 400; - m_height = 240; - m_bottom_active = bottom; -} - -bool LI7::CompareCommands(const LI7::Cmd& a, const LI7::Cmd& b) { - if (a.layer == b.layer) return a.tex < b.tex; - return b.layer < a.layer; -} - -void LI7::RenderFrame(bool bottom) { - C3D_Mtx proj; - Mtx_OrthoTilt(&proj, 0.f, (bottom ? 320 : 400), m_height, 0.f, 1.f, -1.f, - false); - C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, m_uLoc_proj, &proj); - - C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); - - C3D_TexEnv* env = C3D_GetTexEnv(0); - C3D_TexEnvInit(env); - C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, (GPU_TEVSRC)0); - C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); - - auto& active_list = m_vtx_list[bottom]; - - int total_vertices = 0; - m_d_drawcalls = 0; - auto& draw_cmds = bottom ? m_bot_draw_cmds : m_top_draw_cmds; - std::reverse(draw_cmds.begin(), draw_cmds.end()); - // std::sort(draw_cmds.begin(), draw_cmds.end(), CompareCommands); - m_d_commands = draw_cmds.size(); - size_t vtx = 0; - while (draw_cmds.size() > 0) { - C3D_Tex* texture = draw_cmds[draw_cmds.size() - 1].tex->Get(); - size_t start_vtx = vtx; - - while (draw_cmds.size() > 0 && - draw_cmds[draw_cmds.size() - 1].tex->Get() == texture) { - auto c = draw_cmds[draw_cmds.size() - 1]; - if (c.cmd_type == 1) { - active_list[vtx++] = - Vtx(NVec2(c.bot.z, c.bot.w), c.uv.z, c.uv.w, c.clr); - active_list[vtx++] = - Vtx(NVec2(c.top.z, c.top.w), c.uv.z, c.uv.y, c.clr); - active_list[vtx++] = - Vtx(NVec2(c.top.x, c.top.y), c.uv.x, c.uv.y, c.clr); - /// - active_list[vtx++] = - Vtx(NVec2(c.top.x, c.top.y), c.uv.x, c.uv.y, c.clr); - active_list[vtx++] = - Vtx(NVec2(c.bot.x, c.bot.y), c.uv.x, c.uv.w, c.clr); - active_list[vtx++] = - Vtx(NVec2(c.bot.z, c.bot.w), c.uv.z, c.uv.w, c.clr); - } else if (c.cmd_type == 2) { - active_list[vtx++] = - Vtx(NVec2(c.top.x, c.top.y), c.uv.x, c.uv.y, c.clr); - active_list[vtx++] = - Vtx(NVec2(c.top.z, c.top.w), c.uv.z, c.uv.w, c.clr); - active_list[vtx++] = - Vtx(NVec2(c.bot.x, c.bot.y), c.uv.x, c.uv.w, c.clr); - } - draw_cmds.pop_back(); - } - - C3D_TexBind(0, texture); - - C3D_BufInfo* bufinfo = C3D_GetBufInfo(); - BufInfo_Init(bufinfo); - BufInfo_Add(bufinfo, active_list.data() + start_vtx, sizeof(Vtx), 3, 0x210); - - C3D_DrawArrays(GPU_TRIANGLES, 0, vtx - start_vtx); - m_d_drawcalls++; - total_vertices += vtx - start_vtx; - } - C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); - - m_d_vertices = total_vertices; - m_current_texture = nullptr; - m_scale = 1.f; -} - -void LI7::Render(C3D_RenderTarget* top, C3D_RenderTarget* bot) { - Palladium::Ftrace::ScopedTrace st("Li7", "Render"); - C3D_BindProgram(&li7_prog); - C3D_SetAttrInfo(&li7_attr); - C3D_FrameDrawOn(top); - RenderFrame(false); - int d_tmp_cmds1 = m_d_commands; - int d_tmp_dcls1 = m_d_drawcalls; - int d_tmp_vtxs1 = m_d_vertices; - C3D_FrameDrawOn(bot); - RenderFrame(true); - m_d_commands += d_tmp_cmds1; - m_d_drawcalls += d_tmp_dcls1; - m_d_vertices += d_tmp_vtxs1; -} - -void LI7::ColorRect(NVec2 pos, NVec2 szs, NVec4 uvs, unsigned int clr) { - Cmd c; - if (pos.x > m_width || pos.x + szs.x < 0 || pos.y > m_height || - pos.y + szs.y < 0) - return; - c.top = NVec4(pos, NVec2(pos.x + szs.x, pos.y)); - c.bot = NVec4(NVec2(pos.x, pos.y + szs.y), pos + szs); - c.uv = uvs; - c.clr = clr; - c.tex = m_current_texture; - c.cmd_type = 1; - if (m_bottom_active) - m_bot_draw_cmds.push_back(c); - else - m_top_draw_cmds.push_back(c); -} - -void LI7::ColorRect(NVec2 pos, NVec2 szs, unsigned int clr) { - ColorRect(pos, szs, NVec4(0, 0, 1, 1), clr); -} - -void LI7::Rect(NVec2 pos, NVec2 szs, NVec4 uvs) { - ColorRect(pos, szs, uvs, 0xffffffff); -} - -void LI7::Rect(NVec2 pos, NVec2 szs) { - ColorRect(pos, szs, NVec4(0, 0, 1, 1), 0xffffffff); -} - -void LI7::Triangle(NVec2 a, NVec2 b, NVec2 c, unsigned int clr) { - Cmd cmd; - if ((a.x > m_width && b.x > m_width && c.x > m_width) || - (a.y > m_height && b.y > m_height && c.y > m_height) || - (a.x < 0 && b.x < 0 && c.x < 0) || (a.y < 0 && b.y < 0 && c.y < 0)) - return; - cmd.ppos = a; - cmd.pszs = b; - cmd.apos = c; - cmd.top = NVec4(a, b); - cmd.bot = NVec4(c, NVec2()); - cmd.uv = NVec4(0, 1, 1, 0); - cmd.clr = clr; - cmd.tex = m_current_texture; - cmd.cmd_type = 1; - if (m_bottom_active) - m_bot_draw_cmds.push_back(cmd); - else - m_top_draw_cmds.push_back(cmd); -} - -void LI7::Line(NVec2 a, NVec2 b, unsigned int clr, int t) { - // Calculate direction vector - NVec2 direction = {b.x - a.x, b.y - a.y}; - float length = - std::sqrt(direction.x * direction.x + direction.y * direction.y); - - // Normalize direction vector - NVec2 unit_direction = {direction.x / length, direction.y / length}; - - // Calculate perpendicular vector - NVec2 perpendicular = {-unit_direction.y, unit_direction.x}; - - // Scale perpendicular vector by half the thickness - float half_t = t / 2.0f; - NVec2 offset = {perpendicular.x * half_t, perpendicular.y * half_t}; - - // Calculate corner positions - float px0 = a.x + offset.x; - float py0 = a.y + offset.y; - float px1 = b.x + offset.x; - float py1 = b.y + offset.y; - float px2 = a.x - offset.x; - float py2 = a.y - offset.y; - float px3 = b.x - offset.x; - float py3 = b.y - offset.y; - - Cmd c; - c.top = NVec4(px0, py0, px1, py1); - c.bot = NVec4(px2, py2, px3, py3); - c.uv = NVec4(0, 1, 1, 0); - c.clr = clr; - c.tex = m_current_texture; - c.cmd_type = 1; - if (m_bottom_active) - m_bot_draw_cmds.push_back(c); - else - m_top_draw_cmds.push_back(c); -} - -void LI7::TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce) { - float u0 = (float)(cb.x / (float)m_current_texture->Get()->width); - float v1 = (float)(((float)m_current_texture->Get()->height - cb.y) / - (float)m_current_texture->Get()->height); - float u1 = (float)(ce.x / (float)m_current_texture->Get()->width); - float v0 = (float)(((float)m_current_texture->Get()->height - ce.y) / - (float)m_current_texture->Get()->height); - Rect(pos, szs, NVec4(u0, v0, u1, v1)); -} - -NVec2 LI7::GetTextDimensions(const std::string& text) { - // FONT - std::string txt = text + "\0"; - NVec2 pos(0, 0); // Temp Pos - NVec2 offset; - float maxWidth = 0.f; - float ntxtszs = m_dffs * m_txt_scale; - float cpm = ntxtszs / m_font->GetPixelHeight(); - float line_height = m_font->GetPixelHeight() * cpm * m_scale; - - for (size_t i = 0; i < txt.length(); i++) { - if (txt[i] == '\0') break; - auto cp = m_font->GetCodepoint(txt[i]); - bool implicitBreak = false; - if (txt[i] == '\n' || implicitBreak) { - offset.y += line_height; - maxWidth = std::max(maxWidth, offset.x); - offset.x = 0; - if (implicitBreak) continue; - } else if (txt[i] == '\t') { - offset.x = ((offset.x / ntxtszs) / 4 + 1) * 4 * ntxtszs; - } else { - if (txt[i] == ' ') { - // this will make the space twice - offset.x += 2 * m_txt_scale; - } - if (i == txt.length() - 1) - offset.x += cp.szs.x * cpm + m_txt_scale; - else - offset.x += cp.szs.x * cpm + (2 * m_txt_scale); - } - } - maxWidth = std::max(maxWidth, offset.x); - return NVec2(maxWidth, offset.y + (m_dffs * m_txt_scale)); -} - -void LI7::DrawText(NVec2 pos, unsigned int color, const std::string& text, - PDTextFlags flags, NVec2 ap) { - std::string txt = text; - NVec2 offset; - float ntxtszs = m_dffs * m_txt_scale; - float cpm = ntxtszs / m_font->GetPixelHeight(); - float line_height = m_font->GetPixelHeight() * cpm * m_scale; - NVec2 td = GetTextDimensions(text); - if (flags & PDTextFlags_AlignRight) pos.x -= td.x; - if (flags & PDTextFlags_AlignMid) { - pos.x = (ap.x * 0.5) - (td.x * 0.5) + pos.x; - } - std::vector lines; - std::istringstream iss(txt); - std::string temp; - while (std::getline(iss, temp)) { - lines.push_back(temp); - } - - for (auto& it : lines) { - if (pos.y + offset.y + line_height < 0) { - offset.y += line_height; - continue; - } else if (pos.y + offset.y > m_height) { - // Break func as we dont want loop over lines that get skipped too - break; - } - // Loop over line - for (auto& jt : it) { - auto cp = m_font->GetCodepoint(jt); - m_current_texture = cp.tex; - if (jt == '\t') { - offset.x = ((offset.x / ntxtszs) / 4 + 1) * 4 * ntxtszs; - } else { - if (jt != ' ') { - if (flags & PDTextFlags_Shaddow) { - ColorRect(pos + NVec2(offset.x + 1, (offset.y+(cp.off*cpm)) + 1), - NVec2(cp.szs.x*cpm, cp.szs.y*cpm), cp.uv, - Palladium::Color::RGBA(color).is_light() ? 0xff111111 - : 0xffeeeeee); - } - ColorRect(pos + offset + NVec2(0, (cp.off*cpm)), NVec2(cp.szs.x*cpm, cp.szs.y*cpm), cp.uv, color); - - } else { - // this will make the space twice - offset.x += 2 * m_txt_scale; - } - offset.x += cp.szs.x * cpm + (2 * m_txt_scale); - } - } - offset.y += line_height; - offset.x = 0; - } -} -} // namespace Palladium \ No newline at end of file diff --git a/source/Lithium.cpp b/source/Lithium.cpp new file mode 100644 index 0000000..c6e3bd5 --- /dev/null +++ b/source/Lithium.cpp @@ -0,0 +1,767 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +std::wstring make_wstring(const std::string& str) { + std::wstring_convert, wchar_t> converter; + return converter.from_bytes(str); +} + +namespace Palladium { +PDLithiumFlags LI::flags = PDLithiumFlags_Default; +const float LI::default_font_size = 24.f; +const float LI::default_text_size = 0.7f; +float LI::text_scale = 0.7f; +// Renderer Stuff +bool LI::bottom_screen = false; +NVec2 LI::screen_size; +int LI::layer = 0; +std::vector LI::draw_lists[2]; +Texture::Ref LI::active_texture; +Texture::Ref LI::single_color; +std::vector> LI::vertex_buffer; +std::vector> LI::idx_buffer; +size_t LI::vertex_index = 0; +size_t LI::idx_index = 0; +bool LI::font_update = false; +LIFont::Ref LI::font; +bool LI::sysfont_render = false; +std::map LI::text_sizes; +int LI::cmd_index = 0; +// Debug +int LI::num_vertices = 0; +int LI::num_drawcalls = 0; +int LI::num_commands = 0; +int LI::num_indices = 0; +// Shader +DVLB_s* LI::li7_dvlb; +shaderProgram_s LI::li7_prog; +C3D_AttrInfo LI::li7_attr; +int LI::uLoc_proj; + +void LIFont::LoadTFF(const std::string path, int px_size) { + sysfnt = false; + Palladium::Ftrace::ScopedTrace st( + "LIFont", std::filesystem::path(path).filename().string()); + this->pixel_height = px_size; + if (!Palladium::FS::FileExist(path)) return; + int type = px_size * 16; + // Load TTF + stbtt_fontinfo inf; + std::ifstream loader(path, std::ios::binary); + if (!loader.is_open()) return; + loader.seekg(0, std::ios::end); + size_t len = loader.tellg(); + loader.seekg(0, std::ios::beg); + unsigned char* buffer = new unsigned char[len]; + loader.read(reinterpret_cast(buffer), len); + loader.close(); + stbtt_InitFont(&inf, buffer, 0); + std::vector fmap(type * type * 4); + float scale = stbtt_ScaleForPixelHeight(&inf, pixel_height); + + int ascent, descent, lineGap; + stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap); + int baseline = static_cast(ascent * scale); + + name = path; + auto ftex = Texture::New(); + NVec2 offset; + for (int c = 0; c < 255; c++) { + CPI codepoint; + if (stbtt_IsGlyphEmpty(&inf, c)) { + codepoint.codepoint = c; + codepoint.tex = ftex; + codepoint.invalid = true; + cpmap[c] = codepoint; + continue; + } + + int width, height, xOffset, yOffset; + unsigned char* bitmap = stbtt_GetCodepointBitmap( + &inf, scale, scale, c, &width, &height, &xOffset, &yOffset); + int x0, y0, x1, y1; + stbtt_GetCodepointBitmapBox(&inf, c, scale, scale, &x0, &y0, &x1, &y1); + + if (offset[0] + width > type) { + offset[1] += pixel_height; + offset[0] = 0; + } + + codepoint.uv[0] = static_cast((float)offset[0] / (float)type); + codepoint.uv[1] = 1.0f - static_cast((float)offset[1] / (float)type); + codepoint.uv[2] = + static_cast(float(offset[0] + width) / (float)type); + codepoint.uv[3] = + 1.0f - static_cast(float(offset[1] + height) / (float)type); + + codepoint.tex = ftex; + codepoint.szs[0] = width; + codepoint.szs[1] = height; + codepoint.off = baseline + yOffset; + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + int map_pos = ((offset[1] + y) * type + (offset[0] + x)) * 4; + + fmap[map_pos + 0] = 255; + fmap[map_pos + 1] = 255; + fmap[map_pos + 2] = 255; + fmap[map_pos + 3] = bitmap[x + y * width]; + } + } + offset[0] += width; + if (offset[0] + width > type) { + offset[1] += pixel_height; + offset[0] = 0; + } + free(bitmap); + cpmap[c] = codepoint; + } + ftex->LoadPixels(fmap, type, type); + this->tex.push_back(ftex); +} + +void LIFont::LoadBitmapFont(const std::string& path) {} + +void LIFont::LoadSystemFont() { + Palladium::Ftrace::ScopedTrace st("li", "sysfnt"); + sysfnt = true; + name = "System Font"; + // Code to Load the System Font + const auto fnt = fontGetSystemFont(); + const auto fnt_info = fontGetInfo(fnt); + const auto glyph_info = fontGetGlyphInfo(fnt); + this->tex.resize(glyph_info->nSheets + 1); + pixel_height = glyph_info->cellHeight; + for (size_t i = 0; i < glyph_info->nSheets; i++) { + auto stex = Texture::New(); + auto tx = new C3D_Tex; + tx->data = fontGetGlyphSheetTex(fnt, i); + tx->fmt = (GPU_TEXCOLOR)glyph_info->sheetFmt; + tx->size = glyph_info->sheetSize; + tx->width = glyph_info->sheetWidth; + tx->height = glyph_info->sheetHeight; + tx->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | + GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) | + GPU_TEXTURE_WRAP_S(GPU_REPEAT) | GPU_TEXTURE_WRAP_T(GPU_REPEAT); + tx->border = 0xffffffff; + tx->lodParam = 0; + stex->ExternalLoad(tx, NVec2(tx->width, tx->height), NVec4(0, 1, 1, 0)); + tex[i] = stex; + } + std::vector charSet; + for (auto cmap = fnt_info->cmap; cmap; cmap = cmap->next) { + if (cmap->mappingMethod == CMAP_TYPE_DIRECT) { + if (cmap->codeEnd >= cmap->codeBegin) { + charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1); + for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) { + if (cmap->indexOffset + (i - cmap->codeBegin) == 0xFFFF) break; + charSet.emplace_back(i); + } + } + } else if (cmap->mappingMethod == CMAP_TYPE_TABLE) { + if (cmap->codeEnd >= cmap->codeBegin) { + charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1); + for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) { + if (cmap->indexTable[i - cmap->codeBegin] == 0xFFFF) continue; + charSet.emplace_back(i); + } + } + } else if (cmap->mappingMethod == CMAP_TYPE_SCAN) { + charSet.reserve(charSet.size() + cmap->nScanEntries); + for (unsigned i = 0; i < cmap->nScanEntries; ++i) { + if (cmap->scanEntries[i].code >= cmap->codeBegin && + cmap->scanEntries[i].code <= cmap->codeEnd) { + if (cmap->scanEntries[i].glyphIndex != 0xFFFF) { + charSet.emplace_back(cmap->scanEntries[i].code); + } + } + } + } else { + continue; + } + } + + std::sort(charSet.begin(), charSet.end()); + charSet.erase(std::unique(charSet.begin(), charSet.end())); + + for (auto cp : charSet) { + int gidx = fontGlyphIndexFromCodePoint(fnt, cp); + if (gidx >= 0xFFFF) continue; + CPI codepoint; + fontGlyphPos_s dat; + fontCalcGlyphPos(&dat, fnt, gidx, GLYPH_POS_CALC_VTXCOORD, 1.f, 1.f); + + codepoint.codepoint = cp; + codepoint.uv[0] = dat.texcoord.left; + codepoint.uv[1] = dat.texcoord.top; + codepoint.uv[2] = dat.texcoord.right; + codepoint.uv[3] = dat.texcoord.bottom; + if (tex.at(dat.sheetIndex) != nullptr) codepoint.tex = tex[dat.sheetIndex]; + codepoint.szs[0] = dat.vtxcoord.right; + codepoint.szs[1] = dat.vtxcoord.bottom; + codepoint.off = 0; + cpmap[cp] = codepoint; + } +} + +int LIFont::GetPixelHeight() { return this->pixel_height; } + +LIFont::CPI LIFont::GetCodepoint(unsigned int c) { + auto res = cpmap.find(c); + if (res == cpmap.end()) return CPI(true); + return res->second; +} + +void LIFont::Dump() { + // std::ofstream ofs("sdmc:/font.txt", std::ios::out); + // ofs << "LI7 Font Dump" << std::endl; + // ofs << "Pixel Height: " << (int)pixel_height << std::endl; + // for (auto& it : this->cpmap) { + // ofs << " Codepoint: " << (int)it.codepoint << std::endl; + // ofs << " Tex: " << (unsigned int)it.tex->Get() << std::endl; + // ofs << " Szs: (" << (int)it.szs[0] << ", " << (int)it.szs[1] << ")" + // << std::endl; + // ofs << " UV: (" << (float)it.uv[0] << ", " << (float)it.uv[1] << ", " + // << (float)it.uv[2] << ", " << (float)it.uv[3] << ")" << std::endl; + // } + // ofs.close(); +} + +void LI::Init() { + vertex_buffer.resize(4 * 4096); + idx_buffer.resize(6 * 4096); + + li7_dvlb = DVLB_ParseFile((u32*)li7_shader, li7_shader_size); + shaderProgramInit(&li7_prog); + shaderProgramSetVsh(&li7_prog, &li7_dvlb->DVLE[0]); + uLoc_proj = + shaderInstanceGetUniformLocation(li7_prog.vertexShader, "projection"); + + AttrInfo_Init(&li7_attr); + AttrInfo_AddLoader(&li7_attr, 0, GPU_FLOAT, 3); + AttrInfo_AddLoader(&li7_attr, 1, GPU_FLOAT, 2); + AttrInfo_AddLoader(&li7_attr, 2, GPU_UNSIGNED_BYTE, 4); + + single_color = Texture::New(); + std::vector pixels(16 * 16 * 4, 255); + single_color->LoadPixels(pixels, 16, 16); + // C3D_Tex* w = new C3D_Tex; + // C3D_TexInit(w, 16, 16, GPU_L8); + // C3D_TexLoadImage(w, pixels.data(), GPU_TEXFACE_2D, 0); + // single_color->ExternalLoad(w, NVec2(16, 16), NVec4(0, 1, 1, 0)); + + font = LIFont::New(); + font->LoadSystemFont(); +} + +void LI::Exit() { + shaderProgramFree(&li7_prog); + DVLB_Free(li7_dvlb); +} + +void LI::OnScreen(bool bottom) { + screen_size[0] = bottom ? 320 : 400; + screen_size[1] = 240; + bottom_screen = bottom; +} + +bool LI::CompareCommands(const LI::Cmd& a, const LI::Cmd& b) { + if (a.layer == b.layer) { + if (a.tex == b.tex) return a.index < b.index; + return a.tex > b.tex; + } + return a.layer < b.layer; +} + +void LI::RotateCorner(NVec2& v, float s, float c) { + float x = v[0] * c - v[1] * s; + float y = v[1] * c + v[0] * s; + v = NVec2(x, y); +} + +void LI::MakeRect(NVec4& top, NVec4& bot, NVec2 pos, NVec2 szs, float angle) { + NVec2 c; // Center + NVec2 tl(-c[0], -c[1]); // Top Left Corner + NVec2 tr(-c[0] + szs[0], -c[1]); // Top Right Corner + NVec2 bl(-c[0], -c[1] + szs[1]); // Bottom Left Corner + NVec2 br(-c[0] + szs[0], -c[1] + szs[1]); // Bottom Right Corner + + // Calculate Rotation if required + if (angle != 0.f) { + float s = std::sin(angle); + float c = std::cos(angle); + RotateCorner(tl, s, c); + RotateCorner(tr, s, c); + RotateCorner(bl, s, c); + RotateCorner(br, s, c); + } + + // Generate top and bottom positions + top = NVec4(tl + pos + c, tr + pos + c); + bot = NVec4(bl + pos + c, br + pos + c); +} + +void LI::RenderFrame(bool bottom) { + Palladium::Ftrace::ScopedTrace st( + "LI", "Render" + std::string(bottom ? "Bot" : "Top")); + // Create and Setup Projection Matrix + C3D_Mtx proj; + Mtx_OrthoTilt(&proj, 0.f, (bottom ? 320 : 400), screen_size[1], 0.f, 1.f, + -1.f, false); + C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_proj, &proj); + + // Disable Depth Test + C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); + + bool sfr = false; + + // Set Tex Env to use Texture 0 + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvInit(env); + C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, (GPU_TEVSRC)0); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + + // Setup vars for performance data + int total_vertices = 0; + int total_indices = 0; + num_drawcalls = 0; + + // Get DrawCmd List and reverse it + auto& draw_cmds = draw_lists[bottom]; + if (flags & PDLithiumFlags_LRS) { + std::sort(draw_cmds.begin(), draw_cmds.end(), CompareCommands); + } + num_commands = draw_cmds.size(); + size_t index = 0; + // Process Command List + while (index < draw_cmds.size()) { + // Get Active Texture and Setup Vertex List for every command with same tex + C3D_Tex* texture = draw_cmds[index].tex->Get(); + size_t start_vtx = vertex_index; + size_t start_idx = idx_index; + + while (index < draw_cmds.size() && draw_cmds[index].tex->Get() == texture) { + auto c = draw_cmds[index]; + if (c.sfr != sfr) { + if (c.sfr == 0) { + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvInit(env); + C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, + (GPU_TEVSRC)0); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + } else if (c.sfr == 1) { + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvInit(env); + C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR, (GPU_TEVSRC)0, + (GPU_TEVSRC)0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); + C3D_TexEnvSrc(env, C3D_Alpha, GPU_PRIMARY_COLOR, GPU_TEXTURE0, + (GPU_TEVSRC)0); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); + } + sfr = c.sfr; + } + if (c.cmd_type == 1) { + // Tiangle 1 + idx_buffer[idx_index++] = vertex_index + 0; + idx_buffer[idx_index++] = vertex_index + 1; + idx_buffer[idx_index++] = vertex_index + 2; + // Tirangle 2 + idx_buffer[idx_index++] = vertex_index + 0; + idx_buffer[idx_index++] = vertex_index + 2; + idx_buffer[idx_index++] = vertex_index + 3; + + // Vertices + vertex_buffer[vertex_index++] = + Vtx(NVec2(c.bot[2], c.bot[3]), c.uv[2], c.uv[3], c.clr); + vertex_buffer[vertex_index++] = + Vtx(NVec2(c.top[2], c.top[3]), c.uv[2], c.uv[1], c.clr); + vertex_buffer[vertex_index++] = + Vtx(NVec2(c.top[0], c.top[1]), c.uv[0], c.uv[1], c.clr); + vertex_buffer[vertex_index++] = + Vtx(NVec2(c.bot[0], c.bot[1]), c.uv[0], c.uv[3], c.clr); + } else if (c.cmd_type == 2) { + // Triangle + idx_buffer[idx_index++] = vertex_index + 0; + idx_buffer[idx_index++] = vertex_index + 1; + idx_buffer[idx_index++] = vertex_index + 2; + // Vertices + vertex_buffer[vertex_index++] = + Vtx(NVec2(c.bot[0], c.bot[1]), c.uv[0], c.uv[3], c.clr); + vertex_buffer[vertex_index++] = + Vtx(NVec2(c.top[2], c.top[3]), c.uv[2], c.uv[3], c.clr); + vertex_buffer[vertex_index++] = + Vtx(NVec2(c.top[0], c.top[1]), c.uv[0], c.uv[1], c.clr); + } else if (c.cmd_type == 3) { + for (size_t i = 1; i < (size_t)c.top[3] - 1; i++) { + idx_buffer[idx_index++] = vertex_index; + idx_buffer[idx_index++] = vertex_index + i + 1; + idx_buffer[idx_index++] = vertex_index + i; + } + float as = 2.0f * M_PI / c.top[3]; + for (int i = 0; i < (int)c.top[3]; i++) { + float a = i * as; + float x = c.top[0] + c.top[2] * cos(a); + float y = c.top[1] + c.top[2] * sin(a); + vertex_buffer[vertex_index++] = + Vtx(NVec2(x, y), (cos(a) + 1) / 2, (sin(a) + 1) / 2, c.clr); + } + } + index++; + } + + // Bind Texture + C3D_TexBind(0, texture); + + // Setup Buffer + C3D_BufInfo* bufinfo = C3D_GetBufInfo(); + BufInfo_Init(bufinfo); + BufInfo_Add(bufinfo, vertex_buffer.data(), sizeof(Vtx), 3, 0x210); + + // Draw + C3D_DrawElements(GPU_TRIANGLES, idx_index - start_idx, C3D_UNSIGNED_SHORT, + idx_buffer.data() + start_idx); + + num_drawcalls++; + total_vertices += vertex_index - start_vtx; + total_indices += idx_index - start_idx; + } + draw_cmds.clear(); + // Enable DepthTest + C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); + num_vertices = total_vertices; + num_indices = total_indices; + active_texture = nullptr; +} + +void LI::Render(C3D_RenderTarget* top, C3D_RenderTarget* bot) { + Palladium::Ftrace::ScopedTrace st("Li7", "Render"); + if (font_update) { + text_sizes.clear(); + font_update = false; + } + vertex_index = 0; + idx_index = 0; + C3D_BindProgram(&li7_prog); + C3D_SetAttrInfo(&li7_attr); + C3D_FrameDrawOn(top); + RenderFrame(false); + int d_tmp_cmds1 = num_commands; + int d_tmp_dcls1 = num_drawcalls; + int d_tmp_vtxs1 = num_vertices; + int d_tmp_idx1 = num_indices; + C3D_FrameDrawOn(bot); + RenderFrame(true); + num_commands += d_tmp_cmds1; + num_drawcalls += d_tmp_dcls1; + num_vertices += d_tmp_vtxs1; + num_indices += d_tmp_idx1; + layer = 0; + cmd_index = 0; + if (flags & PDLithiumFlags_TMS) { + std::vector rem; + for (auto& it : text_sizes) { + if (Palladium::GetTime() - it.second.time_created > 5) + rem.push_back(it.first); + } + for (auto it : rem) text_sizes.erase(it); + } else { + if (text_sizes.size()) text_sizes.clear(); + } +} + +void LI::DrawRect(NVec2 pos, NVec2 size, unsigned int clr, NVec4 uvs) { + Cmd c; + if (pos[0] > screen_size[0] || pos[0] + size[0] < 0 || + pos[1] > screen_size[1] || pos[1] + size[1] < 0) + return; + + MakeRect(c.top, c.bot, pos, size); + c.uv = uvs; + c.clr = clr; + c.tex = active_texture; + c.cmd_type = 1; + c.layer = layer; + c.sfr = sysfont_render; + c.index = cmd_index++; + sysfont_render = false; + draw_lists[bottom_screen].push_back(c); +} + +void LI::DrawTriangle(NVec2 a, NVec2 b, NVec2 c, unsigned int clr) { + UseTexture(); + Cmd cmd; + if ((a[0] > screen_size[0] && b[0] > screen_size[0] && + c[0] > screen_size[0]) || + (a[1] > screen_size[1] && b[1] > screen_size[1] && + c[1] > screen_size[1]) || + (a[0] < 0 && b[0] < 0 && c[0] < 0) || (a[1] < 0 && b[1] < 0 && c[1] < 0)) + return; + cmd.top = NVec4(a, b); + cmd.bot = NVec4(c, NVec2()); + cmd.uv = NVec4(0, 1, 1, 0); + cmd.layer = layer; + cmd.clr = clr; + cmd.tex = active_texture; + cmd.cmd_type = 2; + cmd.index = cmd_index++; + draw_lists[bottom_screen].push_back(cmd); +} + +void LI::DrawCircle(NVec2 pos, float r, unsigned int color, int segments) { + if (segments < 3) return; + Cmd c; + c.top = NVec4(pos, NVec2(r, segments)); + c.bot = NVec4(); + c.uv = NVec4(0, 1, 1, 0); + c.clr = color; + c.tex = active_texture; + c.layer = layer; + c.cmd_type = 3; + c.index = cmd_index++; + draw_lists[bottom_screen].push_back(c); +} + +void LI::DrawLine(NVec2 a, NVec2 b, unsigned int clr, int t) { + UseTexture(); + NVec2 direction = {b[0] - a[0], b[1] - a[1]}; + float length = + std::sqrt(direction[0] * direction[0] + direction[1] * direction[1]); + NVec2 unit_direction = {direction[0] / length, direction[1] / length}; + NVec2 perpendicular = {-unit_direction[1], unit_direction[0]}; + float half_t = t / 2.0f; + NVec2 offset = {perpendicular[0] * half_t, perpendicular[1] * half_t}; + + // Calculate corner positions + float px0 = a[0] + offset[0]; + float py0 = a[1] + offset[1]; + float px1 = b[0] + offset[0]; + float py1 = b[1] + offset[1]; + float px2 = a[0] - offset[0]; + float py2 = a[1] - offset[1]; + float px3 = b[0] - offset[0]; + float py3 = b[1] - offset[1]; + + Cmd c; + c.top = NVec4(px2, py2, px3, py3); + c.bot = NVec4(px0, py0, px1, py1); + c.uv = NVec4(0, 1, 1, 0); + c.clr = clr; + c.tex = active_texture; + c.layer = layer; + c.cmd_type = 1; + c.index = cmd_index++; + draw_lists[bottom_screen].push_back(c); +} + +std::string LI::WrapText(const std::string& in, int maxlen, NVec2& dim) { + if (flags & PDLithiumFlags_TMS) { + if (text_sizes.find(in) != text_sizes.end()) { + text_sizes[in].time_created = Palladium::GetTime(); + dim = text_sizes[in].size; + if (text_sizes[in].optinal) return text_sizes[in].text; + } + } + std::string out; + std::string line; + int line_x = 0; + std::istringstream istream(in); + std::string temp; + + while (istream >> temp) { + NVec2 dim = GetTextDimensions(line + temp); + if (line_x + dim[0] <= maxlen) { + line += temp + ' '; + line_x += dim[0]; + } else { + out += line + '\n'; + line = temp + ' '; + line_x = GetTextDimensions(line)[0]; + } + } + out += line; + dim = GetTextDimensions(out); + if (flags & PDLithiumFlags_TMS) { + text_sizes[in] = TextBox{dim, Palladium::GetTime(), true, out}; + } + return out; +} + +std::string LI::ShortText(const std::string& in, int maxlen, NVec2& dim) { + auto textdim = GetTextDimensions(in); + if (textdim[0] < (float)maxlen) return in; + if (flags & PDLithiumFlags_TMS) { + if (text_sizes.find(in) != text_sizes.end()) { + text_sizes[in].time_created = Palladium::GetTime(); + dim = text_sizes[in].size; + if (text_sizes[in].optinal) return text_sizes[in].text; + } + } + std::string ext = ""; + std::string ph = "(...)"; // placeholder + std::string worker = in; + std::string out; + size_t ext_pos = in.find_last_of('.'); + if (ext_pos != in.npos) { + ext = in.substr(ext_pos); + worker = in.substr(0, ext_pos); + } + + maxlen -= GetTextDimensions(ext)[0]; + maxlen -= GetTextDimensions(ph)[0]; + + for (auto& it : worker) { + if (GetTextDimensions(out)[0] > (float)maxlen) { + out += ph; + out += ext; + dim = GetTextDimensions(out); + if (flags & PDLithiumFlags_TMS) { + text_sizes[in] = TextBox{dim, Palladium::GetTime(), true, out}; + } + return out; + } + out += it; + } + return out; // Impossible to reach +} + +NVec2 LI::GetTextDimensions(const std::string& text) { + if (!font) return NVec2(); + if (flags & PDLithiumFlags_TMS) { + if (text_sizes.find(text) != text_sizes.end()) { + text_sizes[text].time_created = Palladium::GetTime(); + return text_sizes[text].size; + } + } + // FONT + auto txt = make_wstring(text + "\0"); + NVec2 pos(0, 0); // Temp Pos + NVec2 offset; + float txt_scale = text_scale; + if (font->IsSystemFont()) txt_scale *= 0.9; + float gapm = 1; + float maxWidth = 0.f; + float ntxtszs = default_font_size * txt_scale; + float cpm = ntxtszs / font->GetPixelHeight(); + float line_height = font->GetPixelHeight() * cpm; + + for (size_t i = 0; i < txt.length(); i++) { + if (txt[i] == '\0') break; + auto cp = font->GetCodepoint(txt[i]); + if (cp.invalid && txt[i] != '\n' && txt[i] != ' ' && txt[i] != '\t') + continue; + bool implicitBreak = false; + if (txt[i] == '\n' || implicitBreak) { + offset[1] += line_height; + maxWidth = std::max(maxWidth, offset[0]); + offset[0] = 0; + if (implicitBreak) continue; + } else if (txt[i] == '\t') { + offset[0] = ((offset[0] / ntxtszs) / 4 + 1) * 4 * ntxtszs; + } else { + if (txt[i] == ' ') { + // this will make the space twice + if (!font->IsSystemFont()) offset[0] += 4 * gapm * txt_scale; + } + if (i == txt.length() - 1) + offset[0] += cp.szs[0] * cpm + txt_scale; + else + offset[0] += cp.szs[0] * cpm + (gapm * txt_scale); + } + } + maxWidth = std::max(maxWidth, offset[0]); + NVec2 res = NVec2(maxWidth, offset[1] + (default_font_size * txt_scale)); + if (flags & PDLithiumFlags_TMS) + text_sizes[text] = TextBox{res, Palladium::GetTime(), false, ""}; + return res; +} + +void LI::DrawText(NVec2 pos, unsigned int color, const std::string& text, + PDTextFlags flags, NVec2 ap) { + if (!font) return; + std::string txt = text; + NVec2 offset; + float txt_scale = text_scale; + if (font->IsSystemFont()) txt_scale *= 0.9; + float gapm = 1; + float ntxtszs = default_font_size * txt_scale; + float cpm = ntxtszs / font->GetPixelHeight(); + float line_height = font->GetPixelHeight() * cpm; + NVec2 td; + if (flags & PDTextFlags_Wrap) + txt = WrapText(text, ap[0] - pos[0], td); + else if (flags & PDTextFlags_Short) + txt = ShortText(text, ap[0] - pos[0], td); + if (td[0] == 0 && td[1] == 0) td = GetTextDimensions(text); + if (flags & PDTextFlags_AlignRight) + pos[0] -= td[0]; + else if (flags & PDTextFlags_AlignMid) { + pos[0] = (ap[0] * 0.5) - (td[0] * 0.5) + pos[0]; + } + std::vector lines; + std::istringstream iss(txt); + std::string temp; + while (std::getline(iss, temp)) { + lines.push_back(temp); + } + + for (auto& it : lines) { + if (pos[1] + offset[1] + line_height < 0) { + offset[1] += line_height; + continue; + } else if (pos[1] + offset[1] > screen_size[1]) { + // Break func as we dont want loop over lines that get skipped too + break; + } + auto wstr = make_wstring(it); + // Loop over line + for (auto& jt : wstr) { + auto cp = font->GetCodepoint(jt); + if (cp.invalid && jt != '\n' && jt != ' ' && jt != '\t') continue; + active_texture = cp.tex; + if (jt == '\t') { + offset[0] = ((offset[0] / ntxtszs) / 4 + 1) * 4 * ntxtszs; + } else { + if (jt != ' ') { + int lr = layer; + if (flags & PDTextFlags_Shaddow) { + sysfont_render = true; + DrawRect( + pos + NVec2(offset[0] + 1, (offset[1] + (cp.off * cpm)) + 1), + NVec2(cp.szs[0] * cpm, cp.szs[1] * cpm), + Palladium::Color::RGBA(color).is_light() ? 0xff111111 + : 0xffeeeeee, + cp.uv); + layer++; + } + sysfont_render = true; + DrawRect(pos + offset + NVec2(0, (cp.off * cpm)), + NVec2(cp.szs[0] * cpm, cp.szs[1] * cpm), color, cp.uv); + layer = lr; + + } else { + // this will make the space twice + if (!font->IsSystemFont()) offset[0] += 4 * gapm * txt_scale; + } + offset[0] += cp.szs[0] * cpm + (gapm * txt_scale); + } + } + offset[1] += line_height; + offset[0] = 0; + } +} +} // namespace Palladium \ No newline at end of file diff --git a/source/Logger.cpp b/source/Logger.cpp deleted file mode 100644 index d119621..0000000 --- a/source/Logger.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include -#include - -namespace Palladium { -LoggerBase::~LoggerBase() { - if (_log.is_open()) _log.close(); -} -void LoggerBase::Init(const std::string& name, bool fileless) { - if (!fileless) { - std::string path_base = Palladium::GetAppDirectory() + "/logs/"; - if (!std::filesystem::is_directory(path_base)) { - std::filesystem::create_directories(path_base); - } - auto ts = Palladium::GetTimeStr(); - std::string fn = name + ts + ".txt"; - this->filename = name; - this->log_path = path_base + name; - if (std::filesystem::exists(this->log_path)) { - // Do nothing - } else { - _log.open(this->log_path, std::ios::out); - } - } - this->Write("Palladium Log\n\n"); -} - -void LoggerBase::Write(const std::string& debug_text, int lvl) { - std::string msg = "[" + Palladium::GetTimeStr() + "]: " + debug_text; - if (this->_log.is_open() && lvl <= writelvl) { - this->_log << msg << std::endl; - } - /*while (msg.find_first_of('\n') != 0) { - lines.push_back(msg.substr(0, msg.find_first_of('\n'))); - msg = msg.substr(msg.find_first_of('\n')); - }*/ - lines.push_back(msg); -} - -const std::vector& LoggerBase::Lines() { return this->lines; } -} // namespace Palladium \ No newline at end of file diff --git a/source/Message.cpp b/source/Message.cpp index 95af704..37ea66d 100644 --- a/source/Message.cpp +++ b/source/Message.cpp @@ -1,8 +1,9 @@ #include #include -#include +#include #include #include +#include #include extern bool pdi_debugging; @@ -13,38 +14,40 @@ static int idles = 60; // start of Idle static int anim_len = 300; // Full Length of Animation static NVec2 msg_box = NVec2(170, 50); // Message Box Size -NVec2 MakePos(int frame, int entry) { +NVec2 MakePos(float anim_time, int entry) { float fol = anim_len - fade_outs; - if (frame > fade_outs) - return NVec2(5, 240 - ((entry + 1) * 55) - 5 + - (float)((frame - fade_outs) / fol) * -20); - if (frame > idles) return NVec2(5, 240 - ((entry + 1) * 55) - 5); - return NVec2(-150 + ((float)(frame / (float)idles) * 155), - 240 - ((entry + 1) * 55) - 5); + if (anim_time > fade_outs) + return NVec2( + 5, static_cast(240 - ((entry + 1) * 55) - 5 + + (float)((anim_time - fade_outs) / fol) * -20)); + if (anim_time > idles) return NVec2(5, 240 - ((entry + 1) * 55) - 5); + return NVec2( + static_cast(-150 + ((float)(anim_time / (float)idles) * 155)), + 240 - ((entry + 1) * 55) - 5); } namespace Palladium { float GetDeltaTime(); // Extern from Palladium.cpp void ProcessMessages() { - float tmp_txt = R2::GetTextSize(); - R2::DefaultTextSize(); + float tmp_txt = LI::GetTextScale(); + LI::DefaultTextScale(); // Draw in ovl mode - R2::OnScreen(R2Screen_Top); + LI::OnScreen(false); + LI::NewLayer(); float fol = anim_len - fade_outs; std::reverse(msg_lst.begin(), msg_lst.end()); for (size_t i = 0; i < msg_lst.size(); i++) { - NVec2 pos = MakePos(msg_lst[i]->animationframe, i); - if ((pos.y + 150) < 0) { + NVec2 pos = MakePos(msg_lst[i]->animtime, i); + if ((pos.y() + 150) < 0) { // Dont Render Out of Screen // And as thay aren't relevant anymore // Thay get deleted! msg_lst.erase(msg_lst.begin() + i); } else { int new_alpha = 200; - if (msg_lst[i]->animationframe > fade_outs) { - new_alpha = - 200 - (float(msg_lst[i]->animationframe - fade_outs) / fol) * 200; + if (msg_lst[i]->animtime > fade_outs) { + new_alpha = 200 - (float(msg_lst[i]->animtime - fade_outs) / fol) * 200; } // Wtf is this function lol auto bgc = Palladium::Color::RGBA(PDColor_MessageBackground) @@ -52,26 +55,21 @@ void ProcessMessages() { .toRGBA(); auto tc = Palladium::Color::RGBA(PDColor_Text2).changeA(new_alpha).toRGBA(); - R2::AddRect(pos, msg_box, bgc); - R2::AddText(pos + NVec2(5, 1), msg_lst[i]->title, tc); - R2::AddText(pos + NVec2(5, 17), msg_lst[i]->message, tc); + LI::DrawRect(pos, msg_box, bgc); + LI::NewLayer(); + LI::DrawText(pos + NVec2(5, 1), tc, msg_lst[i]->title); + LI::DrawText(pos + NVec2(5, 17), tc, msg_lst[i]->message); if (pdi_debugging) - R2::AddText(pos + NVec2(msg_box.x+5, 1), - std::to_string(msg_lst[i]->animationframe), tc); - // Why Frameadd? because Message uses int as frame and - // It seems that lower 0.5 will be rounded to 0 - // Why not replace int with float ? - // cause of buggy positions (seen in Flappy Bird 3ds for example) - float frameadd = 60.f * Palladium::GetDeltaTime(); - // 60fps animation * delta to not slowdown - // Oh and fix for Startup lol + LI::DrawText(pos + NVec2(msg_box.x() + 5, 1), tc, + std::to_string((int)msg_lst[i]->animtime)); + // fix for Startup lol // Todo: Only do this on AppStart - if (msg_lst[i]->animationframe == 0) { - msg_lst[i]->animationframe += 1; + if (msg_lst[i]->animtime == 0) { + msg_lst[i]->animtime += 1; } else { - msg_lst[i]->animationframe += (frameadd < 1.f ? 1.f : frameadd); + msg_lst[i]->animtime += Palladium::GetDeltaTime()*0.1f; } - if (msg_lst[i]->animationframe > anim_len) { + if (msg_lst[i]->animtime > anim_len) { msg_lst.erase(msg_lst.begin() + i); } } @@ -79,7 +77,7 @@ void ProcessMessages() { // ReReverse ?? lol // Cause otherwise the Toasts will swap std::reverse(msg_lst.begin(), msg_lst.end()); - R2::SetTextSize(tmp_txt); + LI::SetTextScale(tmp_txt); } void PushMessage(const Message &msg) { diff --git a/source/Overlays.cpp b/source/Overlays.cpp index 45e1458..a9641ec 100644 --- a/source/Overlays.cpp +++ b/source/Overlays.cpp @@ -1,6 +1,8 @@ -#include +#include #include +#include #include +#include #include #include @@ -257,8 +259,9 @@ std::vector keyboard_layout_shift = { // From UI7 bool UI7_InBox(NVec2 inpos, NVec2 boxpos, NVec2 boxsize) { - if ((inpos.x > boxpos.x) && (inpos.y > boxpos.y) && - (inpos.x < boxpos.x + boxsize.x) && (inpos.y < boxpos.y + boxsize.y)) + if ((inpos.x() > boxpos.x()) && (inpos.y() > boxpos.y()) && + (inpos.x() < boxpos.x() + boxsize.x()) && + (inpos.y() < boxpos.y() + boxsize.y())) return true; return false; } @@ -267,111 +270,204 @@ namespace Palladium { Ovl_Ftrace::Ovl_Ftrace(bool* is_enabled) { i_is_enabled = is_enabled; } void Ovl_Ftrace::Draw(void) const { - float tmp_txt = R2::GetTextSize(); - R2::DefaultTextSize(); - R2::OnScreen(R2Screen_Top); - Palladium::Color::RGBA bg(PDColor_Background); - bg.changeA(150); - R2::AddRect(NVec2(0, 0), NVec2(400, 20), bg.toRGBA()); + float tmp_txt = LI::GetTextScale(); + LI::DefaultTextScale(); + LI::OnScreen(false); + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_FillBg) { + LI::NewLayer(); + Palladium::Color::RGBA bg(PDColor_Background); + bg.changeA(150); + LI::DrawRect(NVec2(0, 0), NVec2(400, 20), bg.toRGBA()); + } + LI::NewLayer(); + int lrb = LI::Layer(); + std::string label = "FTrace Overlay"; + auto lbdim = LI::GetTextDimensions(label); + LI::DrawRect(NVec2(), lbdim, + Palladium::ThemeActive()->Get(PDColor_TextDisabled)); + LI::Layer(lrb + 1); + LI::DrawText(NVec2(0, 0), Palladium::ThemeActive()->Get(PDColor_Text2), + label); + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayHelp) { + std::string hlp = + (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayName ? "Name" : "#"); + hlp += ": Current"; + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayAverage || + pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMin || + pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMax) { + hlp += " |"; + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayAverage) + hlp += " Avg"; + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMin) hlp += " Min"; + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMax) hlp += " Max"; + } + auto hlpdim = LI::GetTextDimensions(hlp); + LI::Layer(lrb); + LI::DrawRect(NVec2(0, 20), hlpdim, + Palladium::ThemeActive()->Get(PDColor_TextDisabled)); + LI::Layer(lrb + 1); + LI::DrawText(NVec2(0, 20), Palladium::ThemeActive()->Get(PDColor_Text2), + hlp); + } std::vector dt; for (auto const& it : Palladium::Ftrace::pd_traces) if (it.second.is_ovl && dt.size() < 10) dt.push_back(it.second); for (size_t i = 0; i < (dt.size() < 10 ? dt.size() : 10); i++) { - std::string text = dt[i].func_name + ": " + Palladium::MsTimeFmt(dt[i].time_of); - auto dim = R2::GetTextDimensions(text); - R2::AddRect(NVec2(5, 30+i*dim.y), dim, PDColor_TextDisabled); - R2::AddText(NVec2(5, 30 + i * dim.y), text, PDColor_Text2); + std::string slot = (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayName + ? dt[i].func_name + : std::to_string(i)); + slot += ": " + MsTimeFmt(dt[i].time_of); + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayAverage || + pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMin || + pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMax) { + slot += " |"; + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayAverage) + slot += " " + MsTimeFmt(dt[i].ts.GetAverage()); + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMin) + slot += " " + MsTimeFmt(dt[i].ts.GetMin()); + if (pd_ftrace_ovl_flags & PDFTraceOverlayFlags_DisplayMax) + slot += " " + MsTimeFmt(dt[i].ts.GetMax()); + } + auto dim = LI::GetTextDimensions(slot); + LI::Layer(lrb); + LI::DrawRect(NVec2(0, 37 + i * dim.y()), dim, + Palladium::ThemeActive()->Get(PDColor_TextDisabled)); + LI::Layer(lrb + 1); + LI::DrawText(NVec2(0, 37 + i * dim.y()), + Palladium::ThemeActive()->Get(PDColor_Text2), slot); } - R2::SetTextSize(tmp_txt); + LI::SetTextScale(tmp_txt); } void Ovl_Ftrace::Logic() { if (!i_is_enabled[0]) this->Kill(); } -Ovl_Metrik::Ovl_Metrik(bool* is_enabled, bool* screen, uint32_t* mt_color, - uint32_t* txt_color, float* txt_size) { +Ovl_Metrik::Ovl_Metrik(bool* is_enabled, bool* screen, unsigned int* mt_color, + unsigned int* txt_color, float* txt_size) + : cpu_stats(300), gpu_stats(300) { i_is_enabled = is_enabled; i_screen = screen; i_mt_color = mt_color; i_txt_color = txt_color; i_txt_size = txt_size; + v_update.Reset(); +} + +int MetrikEntry(const std::string& text, NVec2 pos, unsigned int clr1, + unsigned int clr2) { + int dim_y = LI::GetTextDimensions(text).y(); + int lr = LI::Layer(); + LI::DrawRect(pos, LI::GetTextDimensions(text), clr1); + LI::Layer(lr + 1); + LI::DrawText(pos, clr2, text); + LI::Layer(lr); + return dim_y + !LI::GetFont()->IsSystemFont(); +} + +void Graph(Palladium::Ftrace::TimeStats& s, NVec2 pos, NVec2 size, NVec2 range, + unsigned int clr, int lod = 1) { + float xs = static_cast(size.x() / s.GetLen()); + float ys = static_cast(size.y() / (range.y() - range.x())); + + std::vector nodes; + for (size_t i = 0; i < s.GetNumValues(); i += lod) { + nodes.push_back( + NVec2(pos.x() + i * xs, pos.y() + size.y() - (s[i] - range.x()) * ys)); + } + for (size_t i = 1; i < nodes.size(); i++) + LI::DrawLine(nodes[i - 1], nodes[i], clr); } void Ovl_Metrik::Draw(void) const { - float tmp_txt = R2::GetTextSize(); - R2::DefaultTextSize(); - R2::OnScreen(i_screen[0] ? R2Screen_Bottom : R2Screen_Top); + float tmp_txt = LI::GetTextScale(); + LI::SetTextScale(*i_txt_size); + LI::OnScreen(i_screen[0]); + LI::NewLayer(); std::string info = "Palladium " + std::string(PDVSTRING) + " Debug Overlay"; - float dim_y = R2::GetTextDimensions(info).y; - float infoy = 240 - dim_y; - mt_fps = "FPS: " + Palladium::GetFramerate(); + float dim_y = LI::GetTextDimensions(info).y(); + mt_fps = std::format("{:.2f}ms/f -> {:.1f} FPS", Palladium::GetDeltaTime(), + 1000.f / Palladium::GetDeltaTime()); if (pdi_idb_running) mt_fps += " IDB -> ON"; - mt_cpu = "CPU: " + - std::to_string(C3D_GetProcessingTime() * (Palladium::GetFps() / 10)) - .substr(0, 4) + - "%/" + std::to_string(C3D_GetProcessingTime()).substr(0, 4) + "ms"; - mt_gpu = "GPU: " + - std::to_string(C3D_GetDrawingTime() * (Palladium::GetFps() / 10)) - .substr(0, 4) + - "%/" + std::to_string(C3D_GetDrawingTime()).substr(0, 4) + "ms"; - mt_cmd = - "CMD: " + std::to_string(C3D_GetCmdBufUsage() * 100.0f).substr(0, 4) + - "%"; + float cpu_time = C3D_GetProcessingTime(); + cpu_stats.Add(cpu_time); + float gpu_time = C3D_GetDrawingTime(); + gpu_stats.Add(gpu_time); + v_update.Tick(); + if (v_update.Get() > 500.f) { + float fps_lim = C3D_FrameRate(0.f) / 10.f; + mt_cpu = std::format("CPU: {:.1f}% | {:.2f}ms | {:.2f}ms", + cpu_time * fps_lim, cpu_time, cpu_stats.GetAverage()); + mt_gpu = std::format("GPU: {:.1f}% | {:.2f}ms | {:.2f}ms", + gpu_time * fps_lim, gpu_time, gpu_stats.GetAverage()); + v_update.Reset(); + } + mt_cmd = std::format("CMD: {:.2f}%", C3D_GetCmdBufUsage() * 100.f); mt_lfr = "Linear: " + Palladium::FormatBytes(linearSpaceFree()); - if (pdi_enable_memtrack) + if (pd_flags & PDFlags_MemTrack) mt_mem = "Mem: " + Palladium::FormatBytes(Palladium::Memory::GetCurrent()) + " | " + Palladium::FormatBytes(Palladium::Memory::GetTotalAllocated()) + " | " + Palladium::FormatBytes(Palladium::Memory::GetTotalFreed()); - mt_vtx = "Vertices: " + std::to_string(LI7::Vertices()); - mt_dmc = "DrawCmds: " + std::to_string(LI7::DarwCommands()); - mt_drc = "DrawCalls: " + std::to_string(LI7::Drawcalls()); - R2::AddRect(NVec2(0, 0), R2::GetTextDimensions(mt_fps), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, 50), R2::GetTextDimensions(mt_cpu), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, 50 + dim_y * 1), R2::GetTextDimensions(mt_gpu), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, 50 + dim_y * 2), R2::GetTextDimensions(mt_cmd), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, 50 + dim_y * 3), R2::GetTextDimensions(mt_lfr), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, 50 + dim_y * 4), R2::GetTextDimensions(mt_vtx), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, 50 + dim_y * 5), R2::GetTextDimensions(mt_dmc), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, 50 + dim_y * 6), R2::GetTextDimensions(mt_drc), - (unsigned int)i_mt_color[0]); - if (pdi_enable_memtrack) - R2::AddRect(NVec2(0, 50 + dim_y * 7), R2::GetTextDimensions(mt_mem), - (unsigned int)i_mt_color[0]); - R2::AddRect(NVec2(0, infoy), R2::GetTextDimensions(info), - (unsigned int)i_mt_color[0]); - R2::AddText(NVec2(0, 0), mt_fps, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, 50), mt_cpu, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, 50 + dim_y * 1), mt_gpu, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, 50 + dim_y * 2), mt_cmd, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, 50 + dim_y * 3), mt_lfr, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, 50 + dim_y * 4), mt_vtx, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, 50 + dim_y * 5), mt_dmc, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, 50 + dim_y * 6), mt_drc, (unsigned int)i_txt_color[0]); - if (pdi_enable_memtrack) - R2::AddText(NVec2(0, 50 + dim_y * 7), mt_mem, (unsigned int)i_txt_color[0]); - R2::AddText(NVec2(0, infoy), info, (unsigned int)i_txt_color[0]); - - // Force Bottom (Debug Touchpos) - R2::OnScreen(R2Screen_Bottom); - if (Hid::IsEvent("touch", Hid::Held)) { - R2::AddLine(NVec2(Hid::GetTouchPosition().x, 0), - NVec2(Hid::GetTouchPosition().x, 240), - Palladium::Color::Hex("#ff0000")); - R2::AddLine(NVec2(0, Hid::GetTouchPosition().y), - NVec2(320, Hid::GetTouchPosition().y), - Palladium::Color::Hex("#ff0000")); + mt_vtx = "Vertices: " + std::to_string(LI::Vertices()); + mt_idx = "Indices: " + std::to_string(LI::Indices()); + mt_dmc = "DrawCmds: " + std::to_string(LI::DarwCommands()); + mt_drc = "DrawCalls: " + std::to_string(LI::Drawcalls()); + // Rendering + int posy = 0; + if (pd_ovl_flags & PDMetrikOverlayFlags_FPS) + posy += MetrikEntry(mt_fps, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + // Mod PosY to 50 + posy = 50; + if (pd_ovl_flags & PDMetrikOverlayFlags_CPU) + posy += MetrikEntry(mt_cpu, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_GPU) + posy += MetrikEntry(mt_gpu, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_CMD) + posy += MetrikEntry(mt_cmd, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_LMM) + posy += MetrikEntry(mt_lfr, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_LVT) + posy += MetrikEntry(mt_vtx, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_LID) + posy += MetrikEntry(mt_idx, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_LDM) + posy += MetrikEntry(mt_dmc, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_LDC) + posy += MetrikEntry(mt_drc, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_flags & PDFlags_MemTrack && pd_ovl_flags & PDMetrikOverlayFlags_MTD) + posy += MetrikEntry(mt_mem, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + posy = 240 - dim_y; + if (pd_ovl_flags & PDMetrikOverlayFlags_PDO) + posy += MetrikEntry(info, NVec2(0, posy), i_mt_color[0], i_txt_color[0]); + if (pd_ovl_flags & PDMetrikOverlayFlags_CGR || + pd_ovl_flags & PDMetrikOverlayFlags_GGR) { + LI::NewLayer(); + float tl = 1000.f / GetFps(); + std::string tlt = std::format("{:.2f}ms", tl); + auto tldim = LI::GetTextDimensions(tlt); + LI::DrawRect(NVec2(0, 17), NVec2(150 + tldim.x(), 33), i_mt_color[0]); + LI::NewLayer(); + LI::DrawText(NVec2(150, 17), i_txt_color[0], tlt); + if (pd_ovl_flags & PDMetrikOverlayFlags_CGR) + Graph(cpu_stats, NVec2(0, 17), NVec2(150, 33), NVec2(0, tl), 0xff0000ff, + 2); + if (pd_ovl_flags & PDMetrikOverlayFlags_GGR) + Graph(gpu_stats, NVec2(0, 17), NVec2(150, 33), NVec2(0, tl), 0xffff0000, + 2); } - R2::SetTextSize(tmp_txt); + // Force Bottom (Debug Touchpos) + LI::OnScreen(true); + if (Hid::IsEvent("touch", Hid::Held)) { + LI::DrawLine(NVec2((int)Hid::GetTouchPosition().x(), 0), + NVec2((int)Hid::GetTouchPosition().x(), 240), + Palladium::Color::Hex("#ff0000")); + LI::DrawLine(NVec2(0, (int)Hid::GetTouchPosition().y()), + NVec2(320, (int)Hid::GetTouchPosition().y()), + Palladium::Color::Hex("#ff0000")); + } + LI::SetTextScale(tmp_txt); } void Ovl_Metrik::Logic() { @@ -379,13 +475,15 @@ void Ovl_Metrik::Logic() { } Ovl_Keyboard::Ovl_Keyboard(std::string& ref, PDKeyboardState& state, - const std::string& hint, PDKeyboard type) { + const std::string& hint, PDKeyboard type, + PDKeyboardFlags flags) { // Blocks All Input outside of Keyboard // Doesnt work for Hidkeys down etc - Palladium::Hid::Lock(); + if (flags & PDKeyboardFlags_LockControls) Palladium::Hid::Lock(); typed_text = &ref; this->state = &state; this->type = type; + this->flags = flags; *this->state = PDKeyboardState_None; str_bak = ref; ft3 = 0; @@ -393,33 +491,47 @@ Ovl_Keyboard::Ovl_Keyboard(std::string& ref, PDKeyboardState& state, Ovl_Keyboard::~Ovl_Keyboard() { // And Unlock when closing Keyboard lol - Palladium::Hid::Unlock(); + if (flags & PDKeyboardFlags_LockControls) Palladium::Hid::Unlock(); } void Ovl_Keyboard::Draw(void) const { - float tmp_txt = R2::GetTextSize(); - R2::DefaultTextSize(); - if (ft3 > 5) Palladium::Hid::Unlock(); + float tmp_txt = LI::GetTextScale(); + LI::DefaultTextScale(); + if (ft3 > 5) { + if (flags & PDKeyboardFlags_LockControls) Palladium::Hid::Unlock(); + } auto key_table = (type == PDKeyboard_Numpad) ? keyboard_layout_num : keyboard_layout; if (mode == 1) key_table = keyboard_layout_caps; else if (mode == 2) key_table = keyboard_layout_shift; - R2::OnScreen(R2Screen_Top); - R2::AddRect(NVec2(0, 0), NVec2(400, 240), - Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA()); - R2::OnScreen(R2Screen_Bottom); - R2::AddRect(NVec2(0, 0), NVec2(320, 112), - Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA()); - R2::AddRect(NVec2(0, 112), NVec2(320, 128), PDColor_FrameBg); - R2::AddRect(NVec2(0, 112), NVec2(320, 20), PDColor_Header); - R2::AddText(NVec2(5, 114), "> " + *typed_text, - Palladium::ThemeActive()->AutoText(PDColor_Header)); + if (flags & PDKeyboardFlags_BlendTop) { + LI::OnScreen(false); + LI::NewLayer(); + LI::DrawRect(NVec2(0, 0), NVec2(400, 240), + Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA()); + } + LI::OnScreen(true); + LI::NewLayer(); + if (flags & PDKeyboardFlags_BlendBottom) { + LI::DrawRect(NVec2(0, 0), NVec2(320, 112), + Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA()); + } + LI::DrawRect(NVec2(0, 112), NVec2(320, 128), + ThemeActive()->Get(PDColor_FrameBg)); + LI::DrawRect(NVec2(0, 112), NVec2(320, 20), + ThemeActive()->Get(PDColor_Header)); + LI::NewLayer(); + LI::DrawText( + NVec2(5, 114), + ThemeActive()->Get(Palladium::ThemeActive()->AutoText(PDColor_Header)), + "> " + *typed_text); + int lr = LI::Layer(); for (auto const& it : key_table) { NVec2 szs = it.size; NVec2 pos = it.pos; - NVec2 txtdim = R2::GetTextDimensions(it.disp); + NVec2 txtdim = LI::GetTextDimensions(it.disp); PDColor btn = PDColor_Button; if (Palladium::Hid::IsEvent("cancel", Palladium::Hid::Up)) { Palladium::Hid::Clear(); @@ -454,13 +566,19 @@ void Ovl_Keyboard::Draw(void) const { pos -= NVec2(1, 1); szs += NVec2(2, 2); } - NVec2 txtpos = NVec2(pos.x + szs.x * 0.5 - txtdim.x * 0.5, - pos.y + szs.y * 0.5 - txtdim.y * 0.5); - R2::AddRect(pos, szs, btn); - R2::AddText(txtpos, it.disp, Palladium::ThemeActive()->AutoText(btn)); + NVec2 txtpos = NVec2(pos.x() + szs.x() * 0.5 - txtdim.x() * 0.5, + pos.y() + szs.y() * 0.5 - txtdim.y() * 0.5); + LI::Layer(lr); + LI::DrawRect(pos, szs, ThemeActive()->Get(btn)); + LI::Layer(lr + 1); + LI::DrawText(txtpos, + ThemeActive()->Get(Palladium::ThemeActive()->AutoText(btn)), + it.disp); } - if (ft3 > 5) Palladium::Hid::Lock(); - R2::SetTextSize(tmp_txt); + if (ft3 > 5) { + if (flags & PDKeyboardFlags_LockControls) Palladium::Hid::Lock(); + } + LI::SetTextScale(tmp_txt); } void Ovl_Keyboard::Logic() { diff --git a/source/Render2.cpp b/source/Render2.cpp deleted file mode 100644 index 63a6f9d..0000000 --- a/source/Render2.cpp +++ /dev/null @@ -1,325 +0,0 @@ -#include -#include -#include - -namespace Palladium { -const float R2::default_text_size = 0.5f; -float R2::text_size = 0.5; -Font::Ref R2::font; -std::map R2::ts; -std::map R2::mln; -bool R2::next_lined = false; -std::vector R2::commands; -R2Screen R2::current_screen = R2Screen_Bottom; - -void R2::Init() { R2::font = Font::New(); } - -void R2::SetFont(Font::Ref fnt) { - if (!fnt) return; - R2::font = fnt; -} - -Font::Ref R2::GetFont() { return R2::font; } - -void R2::DefaultFont() { R2::font->Unload(); } - -void R2::DrawNextLined() { R2::next_lined = true; } - -void R2::OnScreen(R2Screen screen) { - if (screen < 0 || screen > R2Screen_Top) return; - R2::current_screen = screen; -} - -void R2::SetTextSize(float szs) { text_size = szs; } - -void R2::DefaultTextSize() { text_size = R2::default_text_size; } - -float R2::GetTextSize() { return text_size; } - -R2Screen R2::GetCurrentScreen() { return current_screen; } - -NVec2 R2::GetTextDimensions(const std::string& text) { - return LI7::GetTextDimensions(text); -} - -std::string R2::WrapText(const std::string& in, int maxlen) { - std::string out; - std::string line; - int line_x = 0; - std::istringstream istream(in); - std::string temp; - - while (istream >> temp) { - NVec2 dim = R2::GetTextDimensions(line + temp); - if (line_x + dim.x <= maxlen) { - line += temp + ' '; - line_x += dim.x; - } else { - out += line + '\n'; - line = temp + ' '; - line_x = R2::GetTextDimensions(line).x; - } - } - out += line; - return out; -} - -std::string R2::ShortText(const std::string& in, int maxlen) { - auto textdim = R2::GetTextDimensions(in); - if (textdim.x < (float)maxlen) return in; - std::string ext = ""; - std::string ph = "(...)"; // placeholder - std::string worker = in; - std::string out; - size_t ext_pos = in.find_last_of('.'); - if (ext_pos != in.npos) { - ext = in.substr(ext_pos); - worker = in.substr(0, ext_pos); - } - - maxlen -= R2::GetTextDimensions(ext).x; - maxlen -= R2::GetTextDimensions(ph).x; - - for (auto& it : worker) { - if (R2::GetTextDimensions(out).x > (float)maxlen) { - out += ph; - out += ext; - return out; - } - out += it; - } - return out; // Impossible to reach -} - -NVec2 R2::GetCurrentScreenSize() { - return NVec2(R2::current_screen == R2Screen_Bottom ? 320 : 400, 240); -} - -// Main Processing of Draw Calls -void R2::Process() { - Palladium::Ftrace::ScopedTrace st("Render2", "ProcessList"); - for (auto& it : R2::commands) { - if (it->type <= 0 || it->type > 6) { - // Skip - continue; - } - LI7::OnScreen(!it->Screen); - if (it->type == 1) { - LI7::UseTexture(); - // Rect - if (it->lined) { - LI7::Line(it->pos, NVec2(it->pos.x + it->pszs.x, it->pos.y), it->clr, - 1.f); - LI7::Line(it->pos, NVec2(it->pos.x, it->pos.y + it->pszs.y), it->clr, - 1.f); - LI7::Line(NVec2(it->pos.x + it->pszs.x, it->pos.y), - NVec2(it->pos.x + it->pszs.x, it->pos.y + it->pszs.y), - it->clr, 1.f); - LI7::Line(NVec2(it->pos.x, it->pos.y + it->pszs.y), - NVec2(it->pos.x + it->pszs.x, it->pos.y + it->pszs.y), - it->clr, 1.f); - } else { - LI7::ColorRect(it->pos, it->pszs, it->clr); - } - } else if (it->type == 2) { - LI7::UseTexture(); - // Triangle - if (it->lined) { - LI7::Line(it->pos, it->pszs, it->clr, 1); - LI7::Line(it->pos, it->ap, it->clr, 1); - LI7::Line(it->pszs, it->ap, it->clr, 1); - } else { - LI7::Triangle(it->pos, it->pszs, it->ap, it->clr); - } - } else if (it->type == 3) { - std::string txt = it->text; - if (it->flags & PDTextFlags_Short) { - txt = ShortText(txt, it->pszs.x - it->pos.x); - } else if(it->flags & PDTextFlags_Wrap) { - txt = WrapText(it->text, it->pszs.x-it->pos.x); - } - LI7::DrawText(it->pos, it->clr, txt, it->flags, it->pszs); - } else if (it->type == 4) { - if (it->img->Loadet()) { - LI7::UseTexture(it->img->Get()); - LI7::Rect(it->pos, it->img->Get()->GetSize(), it->img->GetUV()); - } - } else if (it->type == 5) { - // TODO: Move the Draw Func into this API - // it->spr->Draw(); - } else if (it->type == 6) { - LI7::UseTexture(); - LI7::Line(it->pos, it->pszs, it->clr, it->ap.x); - } - } - R2::commands.clear(); -} - -void R2::AddRect(NVec2 pos, NVec2 size, PDColor clr) { - auto cmd = R2Cmd::New(); - cmd->pos = pos; - cmd->pszs = size; - cmd->clr = Palladium::ThemeActive()->Get(clr); - cmd->type = 1; // Rect - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddRect(NVec2 pos, NVec2 size, unsigned int clr) { - auto cmd = R2Cmd::New(); - cmd->pos = pos; - cmd->pszs = size; - cmd->clr = clr; - cmd->type = 1; // Rect - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddLine(NVec2 pos_a, NVec2 pos_b, PDColor clr, int t) { - auto cmd = R2Cmd::New(); - cmd->pos = pos_a; - cmd->pszs = pos_b; - cmd->ap.x = t; - cmd->clr = Palladium::ThemeActive()->Get(clr); - cmd->type = 6; // Line - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddLine(NVec2 pos_a, NVec2 pos_b, unsigned int clr, int t) { - auto cmd = R2Cmd::New(); - cmd->pos = pos_a; - cmd->pszs = pos_b; - cmd->ap.x = t; - cmd->clr = clr; - cmd->type = 6; // Line - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr) { - auto cmd = R2Cmd::New(); - cmd->pos = pos0; - cmd->pszs = pos1; - cmd->ap = pos2; - cmd->clr = Palladium::ThemeActive()->Get(clr); - cmd->type = 2; // Triangle - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, unsigned int clr) { - auto cmd = R2Cmd::New(); - cmd->pos = pos0; - cmd->pszs = pos1; - cmd->ap = pos2; - cmd->clr = clr; - cmd->type = 2; // Triangle - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddText(NVec2 pos, const std::string& text, PDColor clr, - PDTextFlags flags, NVec2 tmb) { - auto cmd = R2Cmd::New(); - cmd->pos = pos; - cmd->pszs = tmb; - cmd->clr = Palladium::ThemeActive()->Get(clr); - cmd->flags = flags; - cmd->text = text; - cmd->type = 3; // Text - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddText(NVec2 pos, const std::string& text, unsigned int clr, - PDTextFlags flags, NVec2 tmb) { - auto cmd = R2Cmd::New(); - cmd->pos = pos; - cmd->pszs = tmb; - cmd->clr = clr; - cmd->flags = flags; - cmd->text = text; - cmd->type = 3; // Text - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddImage(NVec2 pos, Image::Ref img) { - auto cmd = R2Cmd::New(); - cmd->pos = pos; - cmd->img = img; - cmd->type = 4; // Image - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -void R2::AddSprite(Sprite::Ref spr) { - auto cmd = R2Cmd::New(); - cmd->spr = spr; - cmd->type = 5; // Sprite - // Just assign current screen as bottom is 0 (false) - // and Top and TopRight are !0 (true) - cmd->Screen = current_screen; - if (R2::next_lined) { - cmd->lined = true; - R2::next_lined = false; - } - R2::commands.push_back(cmd); -} - -} // namespace Palladium \ No newline at end of file diff --git a/source/Rubidium.cpp b/source/Rubidium.cpp index 73c80e9..d924928 100644 --- a/source/Rubidium.cpp +++ b/source/Rubidium.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include void d7_pixel_blend(Palladium::Rubidium* rb, int x, int y, unsigned int clr, diff --git a/source/Sheet.cpp b/source/Sheet.cpp index 8f1d3e9..bf33e6a 100644 --- a/source/Sheet.cpp +++ b/source/Sheet.cpp @@ -1,22 +1,51 @@ +#include <3ds.h> + +#include #include -#include -Result Palladium::Sheet::Load(const std::string& path) { - if (this->spritesheet) Free(); - this->spritesheet = C2D_SpriteSheetLoad(path.c_str()); - if (!this->spritesheet) { - _pdi_logger()->Write("Failed to Load Spritesheet from: " + path, 0); +namespace Palladium { +void Sheet::LoadT3X(const std::string& path) { + if (sheet_tex) { + C3D_TexDelete(sheet_tex); + delete sheet_tex; + sheet_tex = nullptr; + } + sheet_tex = new C3D_Tex; + std::fstream f(path, std::ios::in | std::ios::binary); + if (!f) { + delete sheet_tex; + sheet_tex = nullptr; + return; + } + f.seekg(0, std::ios::end); + std::vector dat(f.tellg()); + f.seekg(0, std::ios::beg); + f.read(reinterpret_cast(dat.data()), dat.size()); + sheet = + Tex3DS_TextureImport(dat.data(), dat.size(), sheet_tex, nullptr, true); + C3D_TexSetFilter(sheet_tex, GPU_LINEAR, GPU_LINEAR); + f.close(); + int st = Tex3DS_GetNumSubTextures(sheet); + sprites.resize(st); + for (int i = 0; i < st; i++) { + sprites[i] = Texture::New(); + auto stex = Tex3DS_GetSubTexture(sheet, i); + sprites[i]->ExternalLoad( + sheet_tex, NVec2(stex->width, stex->height), + NVec4(stex->left, stex->top, stex->right, stex->bottom)); + sprites[i]->AutoDelete(false); } - return 0; } -void Palladium::Sheet::Free() { - if (!this->spritesheet) return; - C2D_SpriteSheetFree(this->spritesheet); - this->spritesheet = nullptr; +Texture::Ref Sheet::Get(int idx) { + if (idx < 0 || idx >= (int)sprites.size()) return nullptr; + return sprites[idx]; } -C2D_Image Palladium::Sheet::GetImage(int idx) { - if (!this->spritesheet) return {nullptr, nullptr}; - return C2D_SpriteSheetGetImage(this->spritesheet, idx); -} \ No newline at end of file +Image::Ref Sheet::GetImage(int idx) { + if (idx < 0 || idx >= (int)sprites.size()) return nullptr; + Image::Ref img = Image::New(); + img->Set(sprites[idx], sprites[idx]->GetUV()); + return img; +} +} // namespace Palladium \ No newline at end of file diff --git a/source/Sound.cpp b/source/Sound.cpp index 6354379..ea44f04 100644 --- a/source/Sound.cpp +++ b/source/Sound.cpp @@ -33,7 +33,6 @@ Sound::Sound(const string &path, int channel, bool toloop) { std::fstream fp(path, std::ios::in | std::ios::binary); if (!fp.is_open()) { - _pdi_logger()->Write("Could not open WAV: " + path, 0); return; } @@ -42,7 +41,6 @@ Sound::Sound(const string &path, int channel, bool toloop) { size_t read = fp.tellg(); if (read != sizeof(wavHeader)) { // Short read. - _pdi_logger()->Write("WAV Header is too short", 0); fp.close(); return; } @@ -51,7 +49,6 @@ Sound::Sound(const string &path, int channel, bool toloop) { static const char RIFF_magic[4] = {'R', 'I', 'F', 'F'}; if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) { // Incorrect magic number. - _pdi_logger()->Write("Wrong Fileformat", 0); fp.close(); return; } @@ -60,7 +57,6 @@ Sound::Sound(const string &path, int channel, bool toloop) { (wavHeader.channels != 1 && wavHeader.channels != 2) || (wavHeader.bits_per_sample != 8 && wavHeader.bits_per_sample != 16)) { // Unsupported WAV file. - _pdi_logger()->Write("File is invalid", 0); fp.close(); return; } diff --git a/source/Sprite.cpp b/source/Sprite.cpp index e789a66..45398d4 100644 --- a/source/Sprite.cpp +++ b/source/Sprite.cpp @@ -1,5 +1,5 @@ #include - +/* void Palladium::Sprite::FromSheet(Palladium::Sheet::Ref sheet, size_t index) { C2D_SpriteFromSheet(&this->sprite, sheet->Get(), index); } @@ -50,4 +50,4 @@ void Palladium::Sprite::FromImage(Palladium::Image::Ref img) { void Palladium::Sprite::SetScale(float x, float y) { C2D_SpriteScale(&this->sprite, x, y); -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/source/SpriteSheetAnimation.cpp b/source/SpriteSheetAnimation.cpp deleted file mode 100644 index 55736ba..0000000 --- a/source/SpriteSheetAnimation.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include - -void Palladium::SpriteSheetAnimation::Setup(Palladium::Sheet::Ref sheet, - size_t imagecount, - size_t startimage, - float frame_begin, - float frame_finish) { - D_totaltime = frame_begin; - - this->images = imagecount; - - this->sheet = sheet; - - this->time = frame_finish; - - Palladium::SpriteSheetAnimation::FromSheet(this->sheet, startimage); -} -void Palladium::SpriteSheetAnimation::Play(float timespeed) { - D_totaltime += timespeed; - if (D_totaltime >= time) { - D_totaltime -= time; - imgs++; - if (imgs == images) { - imgs = 0; - } - } - Palladium::SpriteSheetAnimation::FromSheet(sheet, imgs); - // Palladium::SpriteSheetAnimation::Draw(); -} \ No newline at end of file diff --git a/source/Texture.cpp b/source/Texture.cpp index 9ddd640..6bde309 100644 --- a/source/Texture.cpp +++ b/source/Texture.cpp @@ -3,6 +3,7 @@ #include #include +#include namespace pdi { static bool single_bit(unsigned int v) { return v && !(v & (v - 1)); } @@ -56,13 +57,12 @@ int GetBPP(Texture::Type type) { void Texture::MakeTex(std::vector &buf, int w, int h, Type type) { if (!tex) { - _pdi_logger()->Write("Invalid Input (object has no adress!)"); return; } // Don't check here as check done before int bpp = GetBPP(type); if (bpp == 4) { - // RGBA -> Abgr + //// RGBA -> Abgr for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int pos = (x + y * w) * bpp; @@ -93,19 +93,19 @@ void Texture::MakeTex(std::vector &buf, int w, int h, NVec2 tex_size(w, h); // Pow2 - if (!pdi::single_bit(w)) tex_size.x = pdi::get_pow2((unsigned int)w); - if (!pdi::single_bit(h)) tex_size.y = pdi::get_pow2((unsigned int)h); + if (!pdi::single_bit(w)) tex_size.x() = pdi::get_pow2((unsigned int)w); + if (!pdi::single_bit(h)) tex_size.y() = pdi::get_pow2((unsigned int)h); - this->img_size.x = (u16)w; - this->img_size.y = (u16)h; - this->uvs.x = 0.0f; - this->uvs.y = 1.0f; - this->uvs.z = ((float)w / (float)tex_size.x); - this->uvs.w = 1.0 - ((float)h / (float)tex_size.y); + this->img_size.x() = (u16)w; + this->img_size.y() = (u16)h; + this->uvs.x() = 0.0f; + this->uvs.y() = 1.0f; + this->uvs.z() = ((float)w / (float)tex_size.x()); + this->uvs.w() = 1.0 - ((float)h / (float)tex_size.y()); // Texture Setup auto tex_fmt = GetTexFmt(type); - C3D_TexInit(tex, (u16)tex_size.x, (u16)tex_size.y, tex_fmt); + C3D_TexInit(tex, (u16)tex_size.x(), (u16)tex_size.y(), tex_fmt); C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST); memset(tex->data, 0, tex->size); @@ -113,7 +113,7 @@ void Texture::MakeTex(std::vector &buf, int w, int h, if (bpp == 3 || bpp == 4) { for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { - int dst_pos = ((((y >> 3) * ((int)tex_size.x >> 3) + (x >> 3)) << 6) + + int dst_pos = ((((y >> 3) * ((int)tex_size.x() >> 3) + (x >> 3)) << 6) + ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) * bpp; @@ -131,6 +131,7 @@ void Texture::MakeTex(std::vector &buf, int w, int h, C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); } void Texture::LoadFile(const std::string &path) { + Palladium::Ftrace::ScopedTrace st("texldr", path); int w, h, c = 0; unsigned char *image = stbi_load(path.c_str(), &w, &h, &c, 4); if (image == nullptr) { @@ -232,10 +233,10 @@ void Texture::Delete() { delete tex; tex = nullptr; img_size = NVec2(); - this->uvs.x = 0.0f; - this->uvs.y = 1.0f; - this->uvs.z = 1.0f; - this->uvs.w = 0.0f; + this->uvs.x() = 0.0f; + this->uvs.y() = 1.0f; + this->uvs.z() = 1.0f; + this->uvs.w() = 0.0f; } } } // namespace Palladium \ No newline at end of file diff --git a/source/ThemeEditor.cpp b/source/ThemeEditor.cpp index 5151ef5..c876153 100644 --- a/source/ThemeEditor.cpp +++ b/source/ThemeEditor.cpp @@ -39,7 +39,7 @@ Palladium::ThemeEditor::~ThemeEditor() { } void Palladium::ThemeEditor::Draw() const { - Palladium::R2::OnScreen(R2Screen_Top); + Palladium::LI::OnScreen(false); if (UI7::BeginMenu("Palladium -> Theme Editor")) { UI7::Label("Sample Text"); UI7::Checkbox("Checkbox", cm); @@ -50,7 +50,7 @@ void Palladium::ThemeEditor::Draw() const { edit_theme->GetTableRef()[PDColor_Progressbar]); UI7::EndMenu(); } - Palladium::R2::OnScreen(R2Screen_Bottom); + Palladium::LI::OnScreen(true); if (UI7::BeginMenu("Theme", NVec2(), UI7MenuFlags_Scrolling)) { if (menu == 0) { if (UI7::Button("Create New")) { diff --git a/source/UI7.cpp b/source/UI7.cpp index 7aa4a42..bbc4d10 100644 --- a/source/UI7.cpp +++ b/source/UI7.cpp @@ -1,23 +1,13 @@ #include -#include #include #include #include #include +#include #include #include #include -template -inline T d7max(T a, T b) { - return a > b ? a : b; -} - -template -inline T d7min(T a, T b) { - return a < b ? a : b; -} - // As the 3ds doesn't support std::chrono #ifdef __3DS__ /// @brief 3ds System Ticks per milli second @@ -33,6 +23,20 @@ inline T d7min(T a, T b) { .count() #endif +struct UI7ObjID { + UI7ObjID() : id(0) {} + int id; + UI7ObjID *operator+=(int i) { + id += i; + return this; + } + UI7ObjID *operator++() { + id++; + return this; + } + std::string str() { return std::to_string(id); } +}; + // Basement structs enums etc struct UI7ID { UI7ID(const std::string &id) { @@ -114,62 +118,62 @@ class DrawCmd { if (type == DrawCmdType_Skip) { return; } - Palladium::R2::OnScreen(screen ? R2Screen_Top : R2Screen_Bottom); + Palladium::LI::OnScreen(screen); + Palladium::LI::Layer(layer); if (type == DrawCmdType_Rect) { - Palladium::R2::AddRect(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w), clr); + Palladium::LI::DrawRect(NVec2(rect[0], rect[1]), NVec2(rect[2], rect[3]), + clr); } else if (type == DrawCmdType_Triangle) { - Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w), - add_coords, clr); + Palladium::LI::DrawTriangle(NVec2(rect[0], rect[1]), + NVec2(rect[2], rect[3]), add_coords, clr); } else if (type == DrawCmdType_Text) { - Palladium::R2::AddText(NVec2(rect.x, rect.y), text, clr, text_flags, - text_box); + Palladium::LI::DrawText(NVec2(rect[0], rect[1]), clr, text, text_flags, + text_box); } else if (type == DrawCmdType_Image) { - Palladium::R2::AddImage(NVec2(rect.x, rect.y), img); + Palladium::LI::DrawImage(NVec2(rect[0], rect[1]), img->Get(), + img->GetSize(), img->GetUV()); } else if (type == DrawCmdType_Debug) { Debug(); } } void Debug() { - Palladium::R2::OnScreen(screen ? R2Screen_Top : R2Screen_Bottom); + return; + Palladium::LI::OnScreen(screen); if (stype == DrawCmdType_Skip && type != DrawCmdType_Debug) return; if (stype == DrawCmdType_Rect) { - Palladium::R2::DrawNextLined(); - Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), - NVec2(rect.x + rect.z, rect.y), - NVec2(rect.x, rect.y + rect.w), 0xff0000ff); - Palladium::R2::DrawNextLined(); - Palladium::R2::AddTriangle(NVec2(rect.x + rect.z, rect.y + rect.w), - NVec2(rect.x + rect.z, rect.y), - NVec2(rect.x, rect.y + rect.w), 0xff0000ff); + Palladium::LI::DrawTriangle( + NVec2(rect[0], rect[1]), NVec2(rect[0] + rect[2], rect[1]), + NVec2(rect[0], rect[1] + rect[3]), 0xff0000ff); + Palladium::LI::DrawTriangle(NVec2(rect[0] + rect[2], rect[1] + rect[3]), + NVec2(rect[0] + rect[2], rect[1]), + NVec2(rect[0], rect[1] + rect[3]), + 0xff0000ff); } else if (stype == DrawCmdType_Triangle) { - Palladium::R2::DrawNextLined(); - Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w), - add_coords, 0xff00ff00); + Palladium::LI::DrawTriangle(NVec2(rect[0], rect[1]), + NVec2(rect[2], rect[3]), add_coords, + 0xff00ff00); } else if (stype == DrawCmdType_Text) { - auto szs = Palladium::R2::GetTextDimensions(text); + auto szs = Palladium::LI::GetTextDimensions(text); if (text_flags & PDTextFlags_AlignRight) { - rect.x -= szs.x; + rect[0] -= szs[0]; } - Palladium::R2::DrawNextLined(); - Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), - NVec2(rect.x + szs.x, rect.y), - NVec2(rect.x, rect.y + szs.y), 0xff00ffff); - Palladium::R2::DrawNextLined(); - Palladium::R2::AddTriangle(NVec2(rect.x + szs.x, rect.y + szs.y), - NVec2(rect.x + szs.x, rect.y), - NVec2(rect.x, rect.y + szs.y), 0xff00ffff); + Palladium::LI::DrawTriangle(NVec2(rect[0], rect[1]), + NVec2(rect[0] + szs[0], rect[1]), + NVec2(rect[0], rect[1] + szs[1]), 0xff00ffff); + Palladium::LI::DrawTriangle(NVec2(rect[0] + szs[0], rect[1] + szs[1]), + NVec2(rect[0] + szs[0], rect[1]), + NVec2(rect[0], rect[1] + szs[1]), 0xff00ffff); } else if (stype == DrawCmdType_Image) { if (!img) return; - rect.z = img->GetSize().x; - rect.w = img->GetSize().y; - Palladium::R2::DrawNextLined(); - Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), - NVec2(rect.x + rect.z, rect.y), - NVec2(rect.x, rect.y + rect.w), 0xff0000ff); - Palladium::R2::DrawNextLined(); - Palladium::R2::AddTriangle(NVec2(rect.x + rect.z, rect.y + rect.w), - NVec2(rect.x + rect.z, rect.y), - NVec2(rect.x, rect.y + rect.w), 0xff0000ff); + rect[2] = img->GetSize().x(); + rect[3] = img->GetSize().y(); + Palladium::LI::DrawTriangle( + NVec2(rect[0], rect[1]), NVec2(rect[0] + rect[2], rect[1]), + NVec2(rect[0], rect[1] + rect[3]), 0xff0000ff); + Palladium::LI::DrawTriangle(NVec2(rect[0] + rect[2], rect[1] + rect[3]), + NVec2(rect[0] + rect[2], rect[1]), + NVec2(rect[0], rect[1] + rect[3]), + 0xff0000ff); } } PD_SMART_CTOR(DrawCmd) @@ -184,44 +188,48 @@ class DrawCmd { PDTextFlags text_flags = 0; // Flags for Text Rendering NVec2 text_box = NVec2(); // Maximum text Box bool screen = false; // Defines Top or Bottom + int layer = 0; // Defines the Rendering Layer }; void UI7DrawList::AddRectangle(NVec2 pos, NVec2 szs, PDColor clr) { auto cmd = DrawCmd::New(); - cmd->screen = Palladium::R2::GetCurrentScreen(); - cmd->rect.x = pos.x; - cmd->rect.y = pos.y; - cmd->rect.z = szs.x; - cmd->rect.w = szs.y; + cmd->screen = Palladium::LI::IsBottomScreen(); + cmd->rect[0] = pos[0]; + cmd->rect[1] = pos[1]; + cmd->rect[2] = szs[0]; + cmd->rect[3] = szs[1]; cmd->clr = Palladium::ThemeActive()->Get(clr); cmd->type = DrawCmdType_Rect; + cmd->layer = bl + layer; AddDebugCall(cmd); AddCall(cmd); } void UI7DrawList::AddRectangle(NVec2 pos, NVec2 szs, unsigned int clr) { auto cmd = DrawCmd::New(); - cmd->screen = Palladium::R2::GetCurrentScreen(); - cmd->rect.x = pos.x; - cmd->rect.y = pos.y; - cmd->rect.z = szs.x; - cmd->rect.w = szs.y; + cmd->screen = Palladium::LI::IsBottomScreen(); + cmd->rect[0] = pos[0]; + cmd->rect[1] = pos[1]; + cmd->rect[2] = szs[0]; + cmd->rect[3] = szs[1]; cmd->clr = clr; cmd->type = DrawCmdType_Rect; + cmd->layer = bl + layer; AddDebugCall(cmd); AddCall(cmd); } void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr) { auto cmd = DrawCmd::New(); - cmd->screen = Palladium::R2::GetCurrentScreen(); - cmd->rect.x = pos0.x; - cmd->rect.y = pos0.y; - cmd->rect.z = pos1.x; - cmd->rect.w = pos1.y; + cmd->screen = Palladium::LI::IsBottomScreen(); + cmd->rect[0] = pos0[0]; + cmd->rect[1] = pos0[1]; + cmd->rect[2] = pos1[0]; + cmd->rect[3] = pos1[1]; cmd->add_coords = pos2; cmd->clr = Palladium::ThemeActive()->Get(clr); cmd->type = DrawCmdType_Triangle; + cmd->layer = bl + layer; AddDebugCall(cmd); AddCall(cmd); } @@ -229,14 +237,15 @@ void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr) { void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, unsigned int clr) { auto cmd = DrawCmd::New(); - cmd->screen = Palladium::R2::GetCurrentScreen(); - cmd->rect.x = pos0.x; - cmd->rect.y = pos0.y; - cmd->rect.z = pos1.x; - cmd->rect.w = pos1.y; + cmd->screen = Palladium::LI::IsBottomScreen(); + cmd->rect[0] = pos0[0]; + cmd->rect[1] = pos0[1]; + cmd->rect[2] = pos1[0]; + cmd->rect[3] = pos1[1]; cmd->add_coords = pos2; cmd->clr = clr; cmd->type = DrawCmdType_Triangle; + cmd->layer = bl + layer; AddDebugCall(cmd); AddCall(cmd); } @@ -244,14 +253,15 @@ void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, void UI7DrawList::AddText(NVec2 pos, const std::string &text, PDColor clr, PDTextFlags flags, NVec2 box) { auto cmd = DrawCmd::New(); - cmd->screen = Palladium::R2::GetCurrentScreen(); - cmd->rect.x = pos.x; - cmd->rect.y = pos.y; + cmd->screen = Palladium::LI::IsBottomScreen(); + cmd->rect[0] = pos[0]; + cmd->rect[1] = pos[1]; cmd->text = text; cmd->clr = Palladium::ThemeActive()->Get(clr); cmd->text_flags = flags; cmd->text_box = box; cmd->type = DrawCmdType_Text; + cmd->layer = bl + layer + 1; AddDebugCall(cmd); AddCall(cmd); } @@ -259,25 +269,27 @@ void UI7DrawList::AddText(NVec2 pos, const std::string &text, PDColor clr, void UI7DrawList::AddText(NVec2 pos, const std::string &text, unsigned int clr, PDTextFlags flags, NVec2 box) { auto cmd = DrawCmd::New(); - cmd->screen = Palladium::R2::GetCurrentScreen(); - cmd->rect.x = pos.x; - cmd->rect.y = pos.y; + cmd->screen = Palladium::LI::IsBottomScreen(); + cmd->rect[0] = pos[0]; + cmd->rect[1] = pos[1]; cmd->text = text; cmd->text_flags = flags; cmd->text_box = box; cmd->clr = clr; cmd->type = DrawCmdType_Text; + cmd->layer = bl + layer + 1; AddDebugCall(cmd); AddCall(cmd); } void UI7DrawList::AddImage(NVec2 pos, Palladium::Image::Ref img) { auto cmd = DrawCmd::New(); - cmd->screen = Palladium::R2::GetCurrentScreen(); - cmd->rect.x = pos.x; - cmd->rect.y = pos.y; + cmd->screen = Palladium::LI::IsBottomScreen(); + cmd->rect[0] = pos[0]; + cmd->rect[1] = pos[1]; cmd->img = img; cmd->type = DrawCmdType_Image; + cmd->layer = bl + layer + 1; // USe Text Layer as well AddDebugCall(cmd); AddCall(cmd); } @@ -306,16 +318,27 @@ void UI7DrawList::AddDebugCall(std::shared_ptr cmd) { dcmd->text_flags = cmd->text_flags; dcmd->img = cmd->img; dcmd->type = DrawCmdType_Debug; - dcmd->screen = Palladium::R2::GetCurrentScreen(); + dcmd->screen = Palladium::LI::IsBottomScreen(); + dcmd->layer = cmd->layer; UI7CtxPushDebugCmd(dcmd); } +struct UI7Promt { + UI7Promt() {} + std::string text; + std::string confirm; + std::string cancel; + int *res_ptr = nullptr; + PD_SMART_CTOR(UI7Promt) +}; + struct UI7Menu { UI7Menu() {} UI7ID menuid; // menu ID NVec2 cursor; // cursor NVec2 cb; // backup cursor NVec2 slc; // sameline cursor + NVec2 screen_size; // MenuScreenSize float scrolling_offset = 0.f; // MenuScrolling Pos bool enable_scrolling = false; // Menu Scrolling float scrolling_mod = 0.f; // For Menu Scrolling effect @@ -341,42 +364,76 @@ struct UI7Menu { PD_SMART_CTOR(UI7Menu) }; +struct UI7_Object { + UI7_Object() : id(""), is_dragged(false) {} + std::string id; + bool is_dragged; + PD_SMART_CTOR(UI7_Object) +}; + struct UI7_Ctx { UI7_Ctx() { delta = 0.0f; time = 0.0f; - is_activated = false; _last = 0; in_menu = false; debugging = false; debug_menu = false; } + // Timings float delta; float time; - bool is_activated; float _last; + // IsInMenu bool in_menu; + // Debug bool debugging; + // TODO: remove as not using anymore bool debug_menu; + // Menu Handlers std::map menus; std::vector active_menus; + // DrawLists UI7DrawList::Ref debug_calls; UI7DrawList::Ref bdl; UI7DrawList::Ref fdl; + // Current Menu UI7Menu::Ref cm; + // Object Handler + std::vector objs; + UI7ObjID *obj_id; + + // Promt Handler + UI7Promt::Ref promt; PD_SMART_CTOR(UI7_Ctx) }; UI7_Ctx::Ref ui7_ctx; +UI7_Object::Ref UI7CtxGetObject(std::string id) { + for (auto &it : ui7_ctx->objs) + if (it->id == id) return it; + auto obj = UI7_Object::New(); + obj->id = id; + ui7_ctx->objs.push_back(obj); + return obj; +} + +bool UI7CtxIsOtherObjDragged(std::string id) { + for (auto &it : ui7_ctx->objs) { + if (it->id == id) continue; + if (it->is_dragged) return true; + } + return false; +} + void UI7CtxPushDebugCmd(DrawCmd::Ref ref) { if (ui7_ctx->debugging) ui7_ctx->debug_calls->AddCall(ref); } bool UI7CtxValidate() { if (ui7_ctx == nullptr) return false; - if (!ui7_ctx->is_activated) return false; return true; } @@ -394,10 +451,20 @@ bool UI7CtxBeginMenu(const std::string &lb) { if (!ui7_ctx->cm->ctrl) ui7_ctx->cm->ctrl = NTCtrl::New(); ui7_ctx->cm->menuid = id; ui7_ctx->cm->cursor = NVec2(0, 0); - ui7_ctx->cm->has_touch = !Palladium::R2::GetCurrentScreen(); - if (!ui7_ctx->cm->background) ui7_ctx->cm->background = UI7DrawList::New(); - if (!ui7_ctx->cm->main) ui7_ctx->cm->main = UI7DrawList::New(); - if (!ui7_ctx->cm->front) ui7_ctx->cm->front = UI7DrawList::New(); + ui7_ctx->cm->has_touch = Palladium::LI::IsBottomScreen(); + ui7_ctx->cm->screen_size = Palladium::LI::GetScreenSize(); + if (!ui7_ctx->cm->background) { + ui7_ctx->cm->background = UI7DrawList::New(); + ui7_ctx->cm->background->BaseLayer(20); + } + if (!ui7_ctx->cm->main) { + ui7_ctx->cm->main = UI7DrawList::New(); + } + ui7_ctx->cm->main->BaseLayer(30); + if (!ui7_ctx->cm->front) { + ui7_ctx->cm->front = UI7DrawList::New(); + ui7_ctx->cm->front->BaseLayer(40); + } ui7_ctx->in_menu = true; return true; } @@ -405,15 +472,14 @@ bool UI7CtxBeginMenu(const std::string &lb) { void UI7CtxEndMenu() { if (!UI7CtxValidate()) return; if (!UI7CtxInMenu()) return; - Palladium::Ftrace::ScopedTrace tr("ui7", "EndMenu"); // Draw Scrollbar if (ui7_ctx->cm->enable_scrolling) { - ui7_ctx->cm->scrolling_possible = (ui7_ctx->cm->ms.y < 235 ? false : true); + ui7_ctx->cm->scrolling_possible = (ui7_ctx->cm->ms[1] < 235 ? false : true); ui7_ctx->cm->show_scroolbar = ui7_ctx->cm->scrolling_possible; if (ui7_ctx->cm->show_scroolbar) { // Screen Width - int sw = Palladium::R2::GetCurrentScreenSize().x; + int sw = Palladium::LI::GetScreenSize().x(); // Top Start Pos int tsp = 5 + ui7_ctx->cm->tbh; // Slider Width @@ -424,82 +490,216 @@ void UI7CtxEndMenu() { int lszs = 20; // Lowest Slider size // Calculate Slider Height float slider_h = (szs - 4) * (static_cast(szs - 4) / - static_cast(ui7_ctx->cm->ms.y)); + static_cast(ui7_ctx->cm->ms[1])); // Create Real Slider Height - int slider_rh = d7min(d7max(slider_h, (float)lszs), (float)(szs - 4)); + int slider_rh = std::clamp(slider_h, static_cast(lszs), + static_cast(szs - 4)); auto slider_clr = PDColor_Button; - // Process Slider Dragging - /// TODO: Optimize - if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Held)) { - auto tp = Palladium::Hid::GetTouchPosition(); - if (UI7::InBox(tp, NVec2(sw - 10, tsp), NVec2(8, szs))) { - slider_clr = PDColor_ButtonHovered; - ui7_ctx->cm->scrolling_offset = d7max( - 0.f, d7min(ui7_ctx->cm->ms.y - 240, - ((tp.y - tsp) / szs) * (ui7_ctx->cm->ms.y - 240))); + + // Process MenuDragging + auto objmbg = UI7CtxGetObject("menu_bg" + ui7_ctx->cm->menuid.real_id); + // Patch that sets scrolling to 0 if max pos is not out of screen + if (ui7_ctx->cm->scrolling_offset != 0.f && ui7_ctx->cm->ms[1] < 235) { + ui7_ctx->cm->scrolling_offset = 0.f; + } + // Auto scroll back if last object is on screen + if (ui7_ctx->cm->scrolling_offset > ui7_ctx->cm->ms[1] - 240 && + ui7_ctx->cm->ms[1] != 0 && ui7_ctx->cm->ms[1] >= 235) { + ui7_ctx->cm->scrolling_offset -= 0.3 * ui7_ctx->delta; + // Patch to Scroll to perfect pos + if (ui7_ctx->cm->scrolling_offset < ui7_ctx->cm->ms[1] - 240) { + ui7_ctx->cm->scrolling_offset = ui7_ctx->cm->ms[1] - 240; } } + // Auto Scroll back if offset gets below 0 + if (ui7_ctx->cm->scrolling_offset < 0) { + ui7_ctx->cm->scrolling_offset += 0.3 * ui7_ctx->delta; + if (ui7_ctx->cm->scrolling_offset > 0) + ui7_ctx->cm->scrolling_offset = 0; + } + + // Zero out scrolling_mod if it goeas < -40 + // or > 40 over the max size + if (ui7_ctx->cm->scrolling_offset < -40 || + ui7_ctx->cm->scrolling_offset > ui7_ctx->cm->ms[1] - 200) { + ui7_ctx->cm->scrolling_mod = 0.f; + } + if (ui7_ctx->cm->has_touch) { + auto np = Palladium::Hid::GetTouchPosition(); + if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Down) && + !UI7CtxIsOtherObjDragged(objmbg->id)) { + // Set the mdp Value as Start Pos + ui7_ctx->cm->mdp = np; + } else if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up) && + !UI7CtxIsOtherObjDragged(objmbg->id)) { + // 0 out the start pos + ui7_ctx->cm->mdp = NVec2(); + objmbg->is_dragged = false; + } + if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Held) && + !UI7CtxIsOtherObjDragged(objmbg->id)) { + // Set modifier + if (!UI7::InBox(np, + NVec2(Palladium::LI::GetScreenSize().x() - 8 - 5, + 5 + ui7_ctx->cm->tbh), + NVec2(8, 240 - ui7_ctx->cm->tbh - 10))) { + objmbg->is_dragged = true; + // Check if and do nothing if the scrolling ofset goes out of screen + if (ui7_ctx->cm->scrolling_offset < ui7_ctx->cm->ms[1] - 200 && + ui7_ctx->cm->scrolling_offset > -40) { + float cursor_mod = (ui7_ctx->cm->mdp[1] - np[1]); + if (ui7_ctx->cm->scrolling_mod <= 4.f && + ui7_ctx->cm->scrolling_mod >= -4 && cursor_mod != 0.0f) { + if (cursor_mod > 2) { + ui7_ctx->cm->scrolling_mod = cursor_mod; + } else if (cursor_mod < -2) { + ui7_ctx->cm->scrolling_mod = cursor_mod; + } + } + } + } + // Update Start pos + ui7_ctx->cm->mdp = np; + } + } + // New Scrolling efect + if (ui7_ctx->cm->scrolling_mod != 0) + ui7_ctx->cm->scrolling_offset += ui7_ctx->cm->scrolling_mod; + // Slow out the effect + if (ui7_ctx->cm->scrolling_mod < 0.f) { + ui7_ctx->cm->scrolling_mod += 0.4f; + if (ui7_ctx->cm->scrolling_mod > 0.f) { + ui7_ctx->cm->scrolling_mod = 0.f; + } + } else if (ui7_ctx->cm->scrolling_mod > 0.f) { + ui7_ctx->cm->scrolling_mod -= 0.4f; + if (ui7_ctx->cm->scrolling_mod < 0.f) { + ui7_ctx->cm->scrolling_mod = 0.f; + } + } + // Process Slider Dragging + /// TODO: Optimize + auto obj = + UI7CtxGetObject("ui7_menu_slider" + ui7_ctx->cm->menuid.real_id); + if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Held) && + !UI7CtxIsOtherObjDragged(obj->id)) { + auto tp = Palladium::Hid::GetTouchPosition(); + if (UI7::InBox(tp, NVec2(sw - 10, tsp), NVec2(8, szs))) { + obj->is_dragged = true; + } + if (obj->is_dragged) { + slider_clr = PDColor_ButtonHovered; + float drag_center = slider_rh / 2.0f; + float drag_pos = + std::clamp(static_cast((tp[1] - tsp - drag_center) / + (szs - slider_rh - 4)), + 0.0f, 1.0f); + + ui7_ctx->cm->scrolling_offset = + drag_pos * (ui7_ctx->cm->ms[1] - 240.0f); + } + } else if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up) && + obj->is_dragged) { + obj->is_dragged = false; + } + // Calculate Slider Position int slider_pos = tsp + - d7min(static_cast(szs - slider_rh - 4), - d7max(0.f, - static_cast( - (szs - slider_rh) * - (static_cast(ui7_ctx->cm->scrolling_offset) / - static_cast(ui7_ctx->cm->ms.y - 240.f))))); + std::clamp(static_cast( + (szs - slider_rh - 4) * + (static_cast(ui7_ctx->cm->scrolling_offset) / + static_cast(ui7_ctx->cm->ms[1] - 240.f))), + 0.f, static_cast(szs - slider_rh - 4)); + // Render Slider ui7_ctx->cm->front->AddRectangle(NVec2(sw - 12, tsp), NVec2(slider_w * 2, szs), PDColor_List0); ui7_ctx->cm->front->AddRectangle(NVec2(sw - 10, slider_pos + 2), NVec2(slider_w, slider_rh), slider_clr); + } else { + // Set scrollingoffset and mod to 0 if not scrolling enabled + ui7_ctx->cm->scrolling_offset = 0.f; + ui7_ctx->cm->scrolling_mod = 0.f; } } - // Debug Print Menu Values - if (ui7_ctx->debug_menu) { - std::stringstream str; - str << "Menu: " << ui7_ctx->cm->menuid.ID() << std::endl; - str << "ui7_ctx->cm->cursor: (" << ui7_ctx->cm->cursor.x << ", " - << ui7_ctx->cm->cursor.y << ")" << std::endl; - str << "ui7_ctx->cm->cb: (" << ui7_ctx->cm->cb.x << ", " - << ui7_ctx->cm->cb.y << ")" << std::endl; - str << "ui7_ctx->cm->slc: (" << ui7_ctx->cm->slc.x << ", " - << ui7_ctx->cm->slc.y << ")" << std::endl; - str << "ui7_ctx->cm->scrolling_offset: " << ui7_ctx->cm->scrolling_offset - << std::endl; - str << "ui7_ctx->cm->enable_scrolling: " << ui7_ctx->cm->enable_scrolling - << std::endl; - str << "ui7_ctx->cm->scrolling_mod: " << ui7_ctx->cm->scrolling_mod - << std::endl; - str << "ui7_ctx->cm->tbh: " << ui7_ctx->cm->tbh << std::endl; - str << "ui7_ctx->cm->show_scroolbar: " << ui7_ctx->cm->show_scroolbar - << std::endl; - str << "ui7_ctx->cm->has_touch: " << ui7_ctx->cm->has_touch << std::endl; - std::string submenu; - - str << "ui7_ctx->cm->ms: (" << ui7_ctx->cm->ms.x << ", " - << ui7_ctx->cm->ms.y << ")" << std::endl; - str << "ui7_ctx->cm->mdp: (" << ui7_ctx->cm->mdp.x << ", " - << ui7_ctx->cm->mdp.y << ")" << std::endl; - str << "ui7_ctx->cm->bslp: (" << ui7_ctx->cm->bslp.x << ", " - << ui7_ctx->cm->bslp.y << ")" << std::endl; - str << "ui7_ctx->cm->lszs: (" << ui7_ctx->cm->lszs.x << ", " - << ui7_ctx->cm->lszs.y << ")" << std::endl; - UI7::GetForegroundList()->AddRectangle( - NVec2(), Palladium::R2::GetTextDimensions(str.str()), - (unsigned int)RGBA8(0, 0, 0, 110)); - UI7::GetForegroundList()->AddText(NVec2(), str.str(), - (unsigned int)RGBA8(255, 255, 255, 110)); - } ui7_ctx->active_menus.push_back(ui7_ctx->cm); ui7_ctx->cm = nullptr; ui7_ctx->in_menu = false; } +void UI7CtxPromtHandle() { + if (!ui7_ctx->promt) return; + Palladium::Hid::Unlock(); + Palladium::LI::OnScreen(true); + auto sd = Palladium::LI::GetScreenSize(); + auto tdim = Palladium::LI::GetTextDimensions(ui7_ctx->promt->text); + // Dim Screen + ui7_ctx->fdl->AddRectangle(NVec2(), sd, 0xaa000000); + NVec2 size(215, tdim[1] + 32); + NVec2 spos((sd[0] * 0.5 - size[0] * 0.5), (sd[1] * 0.5 - size[1] * 0.5)); + // Round POositions to fix graphical glitch + spos[0] = (int)spos[0]; + spos[1] = (int)spos[1]; + auto btn_a = PDColor_Button; + auto btn_b = PDColor_Button; + auto tp = Palladium::Hid::GetLastTouchPosition(); + auto th = Palladium::Hid::IsEvent("touch", Palladium::Hid::Held); + auto tu = Palladium::Hid::IsEvent("touch", Palladium::Hid::Held); + // Cancel + if (UI7::InBox(tp, spos + NVec2(5, 10 + tdim[1]), NVec2(100, 18)) && th) { + btn_a = PDColor_ButtonHovered; + } + // Confirm + if (UI7::InBox(tp, spos + NVec2(110, 10 + tdim[1]), NVec2(100, 18)) && th) { + btn_b = PDColor_ButtonHovered; + } + ui7_ctx->fdl->AddRectangle(spos, size, PDColor_FrameBg); + ui7_ctx->fdl->AddText(spos + NVec2(5), ui7_ctx->promt->text, + Palladium::ThemeActive()->AutoText(PDColor_FrameBg)); + ui7_ctx->fdl->AddRectangle(spos + NVec2(5, 10 + tdim[1]), NVec2(100, 18), + btn_a); + ui7_ctx->fdl->AddRectangle(spos + NVec2(110, 10 + tdim[1]), NVec2(100, 18), + btn_b); + ui7_ctx->fdl->AddText(spos + NVec2(5, 10 + tdim[1]), ui7_ctx->promt->cancel, + Palladium::ThemeActive()->AutoText(btn_a), + PDTextFlags_AlignMid, NVec2(100, 18)); + ui7_ctx->fdl->AddText(spos + NVec2(110, 10 + tdim[1]), + ui7_ctx->promt->confirm, + Palladium::ThemeActive()->AutoText(btn_b), + PDTextFlags_AlignMid, NVec2(100, 18)); + // Cancel + if (UI7::InBox(tp, spos + NVec2(5, 10 + tdim[1]), NVec2(100, 18)) && tu) { + ui7_ctx->promt->res_ptr[0] = 0; + ui7_ctx->promt = nullptr; + return; + } + // Confirm + if (UI7::InBox(tp, spos + NVec2(110, 10 + tdim[1]), NVec2(100, 18)) && tu) { + ui7_ctx->promt->res_ptr[0] = 1; + ui7_ctx->promt = nullptr; + return; + } + // Cancel + if (Palladium::Hid::IsEvent("cancel", Palladium::Hid::Up)) { + ui7_ctx->promt->res_ptr[0] = 0; + ui7_ctx->promt = nullptr; + return; + } + // Confirm + if (Palladium::Hid::IsEvent("confirm", Palladium::Hid::Up)) { + ui7_ctx->promt->res_ptr[0] = 1; + ui7_ctx->promt = nullptr; + return; + } + Palladium::Hid::Lock(); +} + namespace UI7 { bool InBox(NVec2 inpos, NVec2 boxpos, NVec2 boxsize) { - if ((inpos.x > boxpos.x) && (inpos.y > boxpos.y) && - (inpos.x < boxpos.x + boxsize.x) && (inpos.y < boxpos.y + boxsize.y)) + if ((inpos[0] > boxpos[0]) && (inpos[1] > boxpos[1]) && + (inpos[0] < boxpos[0] + boxsize[0]) && + (inpos[1] < boxpos[1] + boxsize[1])) return true; return false; } @@ -508,26 +708,31 @@ void Init() { // If Context is valid it makes no sense to reinit lol if (UI7CtxValidate()) return; ui7_ctx = UI7_Ctx::New(); + ui7_ctx->obj_id = new UI7ObjID; ui7_ctx->delta = 0.0f; ui7_ctx->time = 0.0f; ui7_ctx->_last = __get_time(); ui7_ctx->bdl = UI7DrawList::New(); + ui7_ctx->bdl->BaseLayer(10); ui7_ctx->fdl = UI7DrawList::New(); + ui7_ctx->fdl->BaseLayer(50); ui7_ctx->debug_calls = UI7DrawList::New(); - ui7_ctx->is_activated = true; + ui7_ctx->debug_calls->BaseLayer(100); } void Deinit() { if (!UI7CtxValidate()) return; - ui7_ctx->is_activated = false; ui7_ctx->menus.clear(); ui7_ctx->debug_calls->Clear(); ui7_ctx->active_menus.clear(); + delete ui7_ctx->obj_id; } void Update() { + Palladium::Ftrace::ScopedTrace st("UI7", "Update"); // Dont do anithing without ctx; if (!UI7CtxValidate()) return; + UI7CtxPromtHandle(); ui7_ctx->bdl->Process(); for (auto &it : ui7_ctx->active_menus) { it->background->Process(); @@ -538,9 +743,10 @@ void Update() { ui7_ctx->fdl->Process(); ui7_ctx->active_menus.clear(); float current = __get_time(); - ui7_ctx->delta = (current - ui7_ctx->_last) / 1000.f; + ui7_ctx->delta = (current - ui7_ctx->_last); ui7_ctx->_last = current; - ui7_ctx->time += ui7_ctx->delta; + ui7_ctx->time += ui7_ctx->delta * 0.001f; + ui7_ctx->obj_id->id = 0; } float GetTime() { @@ -556,34 +762,42 @@ float GetDeltaTime() { bool Button(const std::string &label, NVec2 size) { bool ret = false; if (!UI7CtxValidate()) return ret; - NVec2 textdim = Palladium::R2::GetTextDimensions(label); - if (size.x == 0) { - size.x = textdim.x + 8; + NVec2 textdim = Palladium::LI::GetTextDimensions(label); + if (size[0] == 0) { + size[0] = textdim[0] + 8; } - if (size.y == 0) { - size.y = textdim.y + 4; + if (size[1] == 0) { + size[1] = textdim[1] + 4; } PDColor btn = PDColor_Button; NVec2 pos = GetCursorPos(); MoveCursor(size); ui7_ctx->cm->ctrl->AddObj(); + ui7_ctx->obj_id->id++; if (HandleScrolling(pos, size)) return false; - + auto obj = UI7CtxGetObject("button" + ui7_ctx->obj_id->str()); if (ui7_ctx->cm->has_touch) { - if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up) && - InBox(Palladium::Hid::GetLastTouchPosition(), pos, size)) { - btn = PDColor_ButtonActive; - ret = true; + auto tp = Palladium::Hid::GetLastTouchPosition(); + if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up)) { + obj->is_dragged = false; + if (InBox(tp, pos, size)) { + btn = PDColor_ButtonActive; + ret = true; + } } else if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Held) && - InBox(Palladium::Hid::GetTouchPosition(), pos, size)) { + InBox(Palladium::Hid::GetTouchPosition(), pos, size) && + !UI7CtxIsOtherObjDragged(obj->id)) { + obj->is_dragged = true; + } + if (obj->is_dragged) { btn = PDColor_ButtonHovered; } } ui7_ctx->cm->main->AddRectangle(pos, size, btn); - pos = NVec2(pos.x + size.x * 0.5f - textdim.x * 0.5, - pos.y + size.y * 0.5f - textdim.y * 0.5); + pos = NVec2(pos[0] + size[0] * 0.5f - textdim[0] * 0.5, + pos[1] + size[1] * 0.5f - textdim[1] * 0.5); ui7_ctx->cm->main->AddText(pos, label, Palladium::ThemeActive()->AutoText(btn)); return ret; @@ -591,28 +805,33 @@ bool Button(const std::string &label, NVec2 size) { void Checkbox(const std::string &label, bool &c) { if (!UI7CtxValidate()) return; - float sv = (Palladium::R2::GetTextSize() * 40) * 0.9; + float sv = (Palladium::LI::GetTextScale() * 30) * 0.9; NVec2 cbs = NVec2(sv, sv); - NVec2 txtdim = Palladium::R2::GetTextDimensions(label); - NVec2 inp = cbs + NVec2(txtdim.x + 5, 0); + NVec2 txtdim = Palladium::LI::GetTextDimensions(label); + NVec2 inp = cbs + NVec2(txtdim[0] + 5, 0); PDColor bg = PDColor_FrameBg; NVec2 pos = GetCursorPos(); MoveCursor(inp); ui7_ctx->cm->ctrl->AddObj(); + ui7_ctx->obj_id->id++; if (HandleScrolling(pos, inp)) return; - + auto obj = UI7CtxGetObject("cb" + ui7_ctx->obj_id->str()); if (ui7_ctx->cm->has_touch) { - if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up) && - InBox(Palladium::Hid::GetLastTouchPosition(), pos, inp)) { - bg = PDColor_FrameBgHovered; - c = !c; + if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up)) { + obj->is_dragged = false; + if (InBox(Palladium::Hid::GetLastTouchPosition(), pos, inp)) { + bg = PDColor_FrameBgHovered; + c = !c; + } } else if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Held) && - InBox(Palladium::Hid::GetTouchPosition(), pos, inp)) { - bg = PDColor_FrameBgHovered; + InBox(Palladium::Hid::GetTouchPosition(), pos, inp) && + !UI7CtxIsOtherObjDragged(obj->id)) { + obj->is_dragged = true; } + if (obj->is_dragged) bg = PDColor_FrameBgHovered; } ui7_ctx->cm->main->AddRectangle(pos, cbs, bg); @@ -621,13 +840,13 @@ void Checkbox(const std::string &label, bool &c) { PDColor_Checkmark); } ui7_ctx->cm->main->AddText( - pos + NVec2(cbs.x + 5, 1), label, + pos + NVec2(cbs[0] + 5, 1), label, Palladium::ThemeActive()->AutoText(PDColor_Background)); } void Label(const std::string &label, PDTextFlags flags) { if (!UI7CtxValidate()) return; - NVec2 textdim = Palladium::R2::GetTextDimensions(label); + NVec2 textdim = Palladium::LI::GetTextDimensions(label); NVec2 pos = GetCursorPos(); auto upos = pos; // Remove some y offset cause texts have some offset @@ -636,23 +855,23 @@ void Label(const std::string &label, PDTextFlags flags) { if (HandleScrolling(pos, textdim)) return; - float tbh = Palladium::R2::GetTextSize() * 40; + float tbh = Palladium::LI::GetTextScale() * 30; auto &list = - (upos.y + textdim.y < tbh) ? ui7_ctx->cm->front : ui7_ctx->cm->main; + (upos[1] + textdim[1] < tbh) ? ui7_ctx->cm->front : ui7_ctx->cm->main; list->AddText( pos, label, Palladium::ThemeActive()->AutoText( - (upos.y + textdim.y < tbh ? PDColor_Header : PDColor_Background)), - flags); + (upos[1] + textdim[1] < tbh ? PDColor_Header : PDColor_Background)), + flags, NVec2(ui7_ctx->cm->screen_size[0], 20)); } void Progressbar(float value) { if (!UI7CtxValidate()) return; NVec2 pos = GetCursorPos(); - NVec2 size = NVec2(Palladium::R2::GetCurrentScreenSize().x - (pos.x * 2), 20); + NVec2 size = NVec2(Palladium::LI::GetScreenSize().x() - (pos[0] * 2), 20); if (ui7_ctx->cm->show_scroolbar && ui7_ctx->cm->enable_scrolling) - size.x -= 16; + size[0] -= 16; MoveCursor(size); ui7_ctx->cm->ctrl->AddObj(); @@ -663,7 +882,7 @@ void Progressbar(float value) { PDColor_FrameBgHovered); if (!(value != value) && !(value < 0.0) && !(value > 1.0)) { ui7_ctx->cm->main->AddRectangle(pos + NVec2(2, 2), - NVec2((size.x - 4) * value, size.y - 4), + NVec2((size[0] - 4) * value, size[1] - 4), PDColor_Progressbar); } } @@ -671,7 +890,7 @@ void Progressbar(float value) { void Image(Palladium::Image::Ref img) { if (!UI7CtxValidate()) return; NVec2 pos = GetCursorPos(); - MoveCursor(NVec2(img->GetSize().x, img->GetSize().y)); + MoveCursor(NVec2(img->GetSize().x(), img->GetSize().y())); ui7_ctx->cm->ctrl->AddObj(); if (HandleScrolling(pos, img->GetSize())) return; @@ -683,20 +902,19 @@ void BrowserList(const std::vector &entrys, int &selection, PDTextFlags txtflags, NVec2 size, int max_entrys) { if (!UI7CtxValidate()) return; if (selection < 0) return; - float tmp_txt = Palladium::R2::GetTextSize(); - Palladium::R2::DefaultTextSize(); + float tmp_txt = Palladium::LI::GetTextScale(); + Palladium::LI::DefaultTextScale(); NVec2 pos = GetCursorPos(); - if (pos.y + 15 * max_entrys > 230) max_entrys = (int)((230 - pos.y) / 15); - if (size.x == 0) - size.x = Palladium::R2::GetCurrentScreenSize().x - (pos.x * 2); - if (size.y == 0) size.y = (max_entrys * 15); + if (pos[1] + 15 * max_entrys > 230) max_entrys = (int)((230 - pos[1]) / 15); + if (size[0] == 0) size[0] = Palladium::LI::GetScreenSize().x() - (pos[0] * 2); + if (size[1] == 0) size[1] = (max_entrys * 15); MoveCursor(size); ui7_ctx->cm->ctrl->AddObj(); int selindex = (selection < max_entrys ? selection : (max_entrys - 1)); for (int i = 0; i < max_entrys; i++) { ui7_ctx->cm->main->AddRectangle( - pos + NVec2(0, 15 * i), NVec2(size.x, 15), + pos + NVec2(0, 15 * i), NVec2(size[0], 15), (i % 2 == 0 ? PDColor_List0 : PDColor_List1)); } for (size_t i = 0; @@ -707,7 +925,7 @@ void BrowserList(const std::vector &entrys, int &selection, (selection < max_entrys ? i : (i + selection - (max_entrys - 1))); if (i == (size_t)selindex) { ui7_ctx->cm->main->AddRectangle( - pos + NVec2(0, 15 * i), NVec2(size.x, 15), + pos + NVec2(0, 15 * i), NVec2(size[0], 15), (unsigned int)Palladium::Color::RGBA(PDColor_Selector) .fade_to(PDColor_SelectorFade, std::sin(Palladium::GetTime())) .toRGBA()); @@ -717,18 +935,18 @@ void BrowserList(const std::vector &entrys, int &selection, Palladium::ThemeActive()->AutoText( selindex == (int)i ? PDColor_Selector : (i % 2 == 0 ? PDColor_List0 : PDColor_List1)), - txtflags | PDTextFlags_Short, NVec2(size.x, 15)); + txtflags | PDTextFlags_Short, NVec2(size[0], 15)); } - Palladium::R2::SetTextSize(tmp_txt); + Palladium::LI::SetTextScale(tmp_txt); } void InputText(const std::string &label, std::string &text, const std::string &hint) { if (!UI7CtxValidate()) return; - float sv = (Palladium::R2::GetTextSize() * 40) * 0.9; + float sv = (Palladium::LI::GetTextScale() * 30) * 0.9; NVec2 cbs = NVec2(144, sv); - NVec2 txtdim = Palladium::R2::GetTextDimensions(label); - NVec2 inp = cbs + NVec2(txtdim.x + 5, 0); + NVec2 txtdim = Palladium::LI::GetTextDimensions(label); + NVec2 inp = cbs + NVec2(txtdim[0] + 5, 0); PDColor bg = PDColor_FrameBg; auto id = UI7ID(label); PDKeyboardState kbd_state; // tmp (goes out of scope) @@ -736,26 +954,31 @@ void InputText(const std::string &label, std::string &text, NVec2 pos = GetCursorPos(); MoveCursor(inp); ui7_ctx->cm->ctrl->AddObj(); + ui7_ctx->obj_id->id++; if (HandleScrolling(pos, inp)) return; - + auto obj = UI7CtxGetObject("ipt" + ui7_ctx->obj_id->str()); if (ui7_ctx->cm->has_touch) { - if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up) && - InBox(Palladium::Hid::GetLastTouchPosition(), pos, inp)) { - bg = PDColor_FrameBgHovered; - Palladium::AddOvl( - std::make_unique(text, kbd_state, hint)); + if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up)) { + obj->is_dragged = false; + if (InBox(Palladium::Hid::GetLastTouchPosition(), pos, inp)) { + bg = PDColor_FrameBgHovered; + Palladium::AddOvl( + std::make_unique(text, kbd_state, hint)); + } } else if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Held) && - InBox(Palladium::Hid::GetTouchPosition(), pos, inp)) { - bg = PDColor_FrameBgHovered; + InBox(Palladium::Hid::GetTouchPosition(), pos, inp) && + !UI7CtxIsOtherObjDragged(obj->id)) { + obj->is_dragged = true; } + if (obj->is_dragged) bg = PDColor_FrameBgHovered; } ui7_ctx->cm->main->AddRectangle(pos, cbs, bg); ui7_ctx->cm->main->AddText(pos + NVec2(5, 1), (text != "" ? text : hint), Palladium::ThemeActive()->AutoText(bg)); ui7_ctx->cm->main->AddText( - pos + NVec2(cbs.x + 5, 1), id.Title(), + pos + NVec2(cbs[0] + 5, 1), id.Title(), Palladium::ThemeActive()->AutoText(PDColor_Background)); } @@ -766,14 +989,14 @@ bool BeginMenu(const std::string &title, NVec2 size, UI7MenuFlags flags) { auto ret = UI7CtxBeginMenu(title); if (!ret) return ret; bool titlebar = true; - if (size.x == 0) { - size.x = Palladium::R2::GetCurrentScreen() ? 400 : 320; + if (size[0] == 0) { + size[0] = Palladium::LI::GetScreenSize().x(); } - if (size.y == 0) { - size.y = 240; + if (size[1] == 0) { + size[1] = 240; } PDTextFlags txtflags = 0; - float tbh = Palladium::R2::GetTextSize() * 40; + float tbh = Palladium::LI::GetTextScale() * 30; ui7_ctx->cm->tbh = tbh; if (flags & UI7MenuFlags_NoTitlebar) { @@ -782,95 +1005,16 @@ bool BeginMenu(const std::string &title, NVec2 size, UI7MenuFlags flags) { } if (flags & UI7MenuFlags_TitleMid) txtflags = PDTextFlags_AlignMid; ui7_ctx->cm->enable_scrolling = (flags & UI7MenuFlags_Scrolling); - if (ui7_ctx->cm->enable_scrolling && !Palladium::R2::GetCurrentScreen() && - ui7_ctx->cm->scrolling_possible) { - // Patch that sets scrolling to 0 if max pos is not out of screen - if (ui7_ctx->cm->scrolling_offset != 0.f && ui7_ctx->cm->ms.y < 235) { - ui7_ctx->cm->scrolling_offset = 0.f; - } - // Auto scroll back if last object is on screen - if (ui7_ctx->cm->scrolling_offset > ui7_ctx->cm->ms.y - 240 && - ui7_ctx->cm->ms.y != 0 && ui7_ctx->cm->ms.y >= 235) { - ui7_ctx->cm->scrolling_offset -= 3; - // Patch to Scroll to perfect pos - if (ui7_ctx->cm->scrolling_offset < ui7_ctx->cm->ms.y - 240) { - ui7_ctx->cm->scrolling_offset = ui7_ctx->cm->ms.y - 240; - } - } - // Auto Scroll back if offset gets below 0 - if (ui7_ctx->cm->scrolling_offset < 0) { - ui7_ctx->cm->scrolling_offset += 3; - if (ui7_ctx->cm->scrolling_offset > 0) ui7_ctx->cm->scrolling_offset = 0; - } - // Zero out scrolling_mod if it goeas < -40 - // or > 40 over the max size - if (ui7_ctx->cm->scrolling_offset < -40 || - ui7_ctx->cm->scrolling_offset > ui7_ctx->cm->ms.y - 200) { - ui7_ctx->cm->scrolling_mod = 0.f; - } - if (ui7_ctx->cm->has_touch) { - auto np = Palladium::Hid::GetTouchPosition(); - if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Down)) { - // Set the mdp Value as Start Pos - ui7_ctx->cm->mdp = np; - } else if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up)) { - // 0 out the start pos - ui7_ctx->cm->mdp = NVec2(); - } - if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Held)) { - // Set modifier - if (!InBox(np, - NVec2(Palladium::R2::GetCurrentScreenSize().x - 8 - 5, - 5 + ui7_ctx->cm->tbh), - NVec2(8, 240 - ui7_ctx->cm->tbh - 10))) { - // Check if and do nothing if the scrolling ofset goes out of screen - if (ui7_ctx->cm->scrolling_offset < ui7_ctx->cm->ms.y - 200 && - ui7_ctx->cm->scrolling_offset > -40) { - float cursor_mod = (ui7_ctx->cm->mdp.y - np.y); - if (ui7_ctx->cm->scrolling_mod <= 4.f && - ui7_ctx->cm->scrolling_mod >= -4 && cursor_mod != 0.0f) { - if (cursor_mod > 2) { - ui7_ctx->cm->scrolling_mod = cursor_mod; - } else if (cursor_mod < -2) { - ui7_ctx->cm->scrolling_mod = cursor_mod; - } - } - } - } - // Update Start pos - ui7_ctx->cm->mdp = np; - } - } - // New Scrolling efect - if (ui7_ctx->cm->scrolling_mod != 0) - ui7_ctx->cm->scrolling_offset += ui7_ctx->cm->scrolling_mod; - // Slow out the effect - if (ui7_ctx->cm->scrolling_mod < 0.f) { - ui7_ctx->cm->scrolling_mod += 0.4f; - if (ui7_ctx->cm->scrolling_mod > 0.f) { - ui7_ctx->cm->scrolling_mod = 0.f; - } - } else if (ui7_ctx->cm->scrolling_mod > 0.f) { - ui7_ctx->cm->scrolling_mod -= 0.4f; - if (ui7_ctx->cm->scrolling_mod < 0.f) { - ui7_ctx->cm->scrolling_mod = 0.f; - } - } - } else { - // Set scrollingoffset and mod to 0 if not scrolling enabled - ui7_ctx->cm->scrolling_offset = 0.f; - ui7_ctx->cm->scrolling_mod = 0.f; - } + // Render ui7_ctx->cm->background->AddRectangle(NVec2(), size, PDColor_Background); if (titlebar) { - ui7_ctx->cm->front->AddRectangle(NVec2(), NVec2(size.x, tbh), + ui7_ctx->cm->front->AddRectangle(NVec2(), NVec2(size[0], tbh), PDColor_Header); - ui7_ctx->cm->front->AddText( NVec2(5, 2), id.Title(), Palladium::ThemeActive()->AutoText(PDColor_Header), txtflags, - NVec2(size.x, 0)); + NVec2(size[0], 0)); } SetCursorPos(NVec2(5, ui7_ctx->cm->tbh + 5)); @@ -889,15 +1033,16 @@ void Grid(const std::string &name, const NVec2 &size, const NVec2 &entry_size, NVec2 pos = GetCursorPos(); NVec2 cpos(pos); - int neh = std::floor(size.x / (entry_size.x + 4)); - int nev = std::floor(size.y / (entry_size.y + 4)); + int neh = std::floor(size[0] / (entry_size[0] + 4)); + int nev = std::floor(size[1] / (entry_size[1] + 4)); // Inside Grid Offset NVec2 igoff = NVec2(); if (neh >= 2 && nev >= 2) { - igoff = NVec2( - ((size.x) / 2 - (((neh - 1) * (entry_size.x + 4)) + entry_size.x) / 2), - ((size.y) / 2 - ((nev - 1) * ((entry_size.y + 4)) + entry_size.y) / 2)); + igoff = NVec2(((size[0]) / 2 - + (((neh - 1) * (entry_size[0] + 4)) + entry_size[0]) / 2), + ((size[1]) / 2 - + ((nev - 1) * ((entry_size[1] + 4)) + entry_size[1]) / 2)); } // Y-Offset int yoff = 0; @@ -907,14 +1052,14 @@ void Grid(const std::string &name, const NVec2 &size, const NVec2 &entry_size, display_func(data_array[i], pos); // if (ui7_ctx->debugging) // Palladium::Draw2::Text(pos + NVec2(4, 4), std::to_string(i)); - if (pos.x + (entry_size.x * 2) > (cpos.x + size.x) && - pos.y + (entry_size.y * 2) > cpos.y + size.y) { + if (pos[0] + (entry_size[0] * 2) > (cpos[0] + size[0]) && + pos[1] + (entry_size[1] * 2) > cpos[1] + size[1]) { break; - } else if (pos.x + (entry_size.x * 2) > (cpos.x + size.x)) { - pos = NVec2(5 + igoff.x, pos.y + entry_size.y + 4); + } else if (pos[0] + (entry_size[0] * 2) > (cpos[0] + size[0])) { + pos = NVec2(5 + igoff[0], pos[1] + entry_size[1] + 4); yoff++; } else { - pos += NVec2(entry_size.x + 4, 0); + pos += NVec2(entry_size[0] + 4, 0); } } @@ -923,10 +1068,10 @@ void Grid(const std::string &name, const NVec2 &size, const NVec2 &entry_size, void ColorSelector(const std::string &label, unsigned int &color) { if (!UI7CtxValidate()) return; - float sv = (Palladium::R2::GetTextSize() * 40) * 0.9; + float sv = (Palladium::LI::GetTextScale() * 30) * 0.9; NVec2 cbs = NVec2(sv, sv); - NVec2 txtdim = Palladium::R2::GetTextDimensions(label); - NVec2 inp = cbs + NVec2(txtdim.x + 5, 0); + NVec2 txtdim = Palladium::LI::GetTextDimensions(label); + NVec2 inp = cbs + NVec2(txtdim[0] + 5, 0); auto outline = Palladium::Color::RGBA(color).is_light() ? 0xff000000 : 0xffffffff; auto id = UI7ID(label); @@ -982,8 +1127,8 @@ void ColorSelector(const std::string &label, unsigned int &color) { if (!inkbd) Palladium::Hid::Unlock(); bool isunlock = false; NVec2 npos = pos; - if (npos.y < ui7_ctx->cm->tbh + 2) npos.y = ui7_ctx->cm->tbh; - if (npos.y + 97 > 235) npos.y = 137; + if (npos[1] < ui7_ctx->cm->tbh + 2) npos[1] = ui7_ctx->cm->tbh; + if (npos[1] + 97 > 235) npos[1] = 137; // Input if (ui7_ctx->cm->has_touch) { auto ltp = Palladium::Hid::GetLastTouchPosition(); @@ -998,28 +1143,28 @@ void ColorSelector(const std::string &label, unsigned int &color) { Palladium::Hid::Clear(); } if (Palladium::Hid::IsEvent("touch", Palladium::Hid::Up)) { - if (InBox(ltp, npos + NVec2(2, cbs.y * 3 + 4), NVec2(50, cbs.y))) { + if (InBox(ltp, npos + NVec2(2, cbs[1] * 3 + 4), NVec2(50, cbs[1]))) { inkbd = true; kbd_txt = std::to_string(clr.m_r); kbd_rgba = 1; Palladium::AddOvl(std::make_unique( kbd_txt, kbd_state, "", PDKeyboard_Numpad)); - } else if (InBox(ltp, npos + NVec2(54, cbs.y * 3 + 4), - NVec2(50, cbs.y))) { + } else if (InBox(ltp, npos + NVec2(54, cbs[1] * 3 + 4), + NVec2(50, cbs[1]))) { inkbd = true; kbd_txt = std::to_string(clr.m_g); kbd_rgba = 2; Palladium::AddOvl(std::make_unique( kbd_txt, kbd_state, "", PDKeyboard_Numpad)); - } else if (InBox(ltp, npos + NVec2(2, cbs.y * 4 + 4), - NVec2(50, cbs.y))) { + } else if (InBox(ltp, npos + NVec2(2, cbs[1] * 4 + 4), + NVec2(50, cbs[1]))) { inkbd = true; kbd_txt = std::to_string(clr.m_b); kbd_rgba = 3; Palladium::AddOvl(std::make_unique( kbd_txt, kbd_state, "", PDKeyboard_Numpad)); - } else if (InBox(ltp, npos + NVec2(54, cbs.y * 4 + 4), - NVec2(50, cbs.y))) { + } else if (InBox(ltp, npos + NVec2(54, cbs[1] * 4 + 4), + NVec2(50, cbs[1]))) { inkbd = true; kbd_txt = std::to_string(clr.m_a); kbd_rgba = 4; @@ -1038,71 +1183,70 @@ void ColorSelector(const std::string &label, unsigned int &color) { color); // Draw Color Name Shorted if needed ui7_ctx->cm->front->AddText( - npos + NVec2(cbs.x + 7, 1), label, + npos + NVec2(cbs[0] + 7, 1), label, Palladium::ThemeActive()->AutoText(PDColor_FrameBg), PDTextFlags_Short); // Add luminance text ui7_ctx->cm->front->AddText( - npos + NVec2(2, cbs.y + 4), "lum: " + std::to_string(clr.luminance()), + npos + NVec2(2, cbs[1] + 4), "lum: " + std::to_string(clr.luminance()), Palladium::ThemeActive()->AutoText(PDColor_FrameBg)); // Add Hex value ui7_ctx->cm->front->AddText( - npos + NVec2(2, cbs.y * 2 + 4), + npos + NVec2(2, cbs[1] * 2 + 4), "hex: " + Palladium::Color::RGBA2Hex(color), Palladium::ThemeActive()->AutoText(PDColor_FrameBg)); // Red { - ui7_ctx->cm->front->AddRectangle(npos + NVec2(2, cbs.y * 3 + 4), - NVec2(50, cbs.y), + ui7_ctx->cm->front->AddRectangle(npos + NVec2(2, cbs[1] * 3 + 4), + NVec2(50, cbs[1]), PDColor_FrameBgHovered); ui7_ctx->cm->front->AddRectangle( - npos + NVec2(2, cbs.y * 3 + 4), - NVec2(50 * ((float)clr.m_r / 255.f), cbs.y), 0xff0000ff); - ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs.y * 3 + 4), + npos + NVec2(2, cbs[1] * 3 + 4), + NVec2(50 * ((float)clr.m_r / 255.f), cbs[1]), 0xff0000ff); + ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs[1] * 3 + 4), "R: " + std::to_string(clr.m_r), PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); } // Green { - ui7_ctx->cm->front->AddRectangle(npos + NVec2(54, cbs.y * 3 + 4), - NVec2(50, cbs.y), + ui7_ctx->cm->front->AddRectangle(npos + NVec2(54, cbs[1] * 3 + 4), + NVec2(50, cbs[1]), PDColor_FrameBgHovered); ui7_ctx->cm->front->AddRectangle( - npos + NVec2(54, cbs.y * 3 + 4), - NVec2(50 * ((float)clr.m_g / 255.f), cbs.y), 0xff00ff00); - ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs.y * 3 + 4), + npos + NVec2(54, cbs[1] * 3 + 4), + NVec2(50 * ((float)clr.m_g / 255.f), cbs[1]), 0xff00ff00); + ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs[1] * 3 + 4), "G: " + std::to_string(clr.m_g), PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); } // Blue { - ui7_ctx->cm->front->AddRectangle(npos + NVec2(2, cbs.y * 4 + 4), - NVec2(50, cbs.y), + ui7_ctx->cm->front->AddRectangle(npos + NVec2(2, cbs[1] * 4 + 4), + NVec2(50, cbs[1]), PDColor_FrameBgHovered); ui7_ctx->cm->front->AddRectangle( - npos + NVec2(2, cbs.y * 4 + 4), - NVec2(50 * ((float)clr.m_b / 255.f), cbs.y), 0xffff0000); - ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs.y * 4 + 4), + npos + NVec2(2, cbs[1] * 4 + 4), + NVec2(50 * ((float)clr.m_b / 255.f), cbs[1]), 0xffff0000); + ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs[1] * 4 + 4), "B: " + std::to_string(clr.m_b), PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); } // Alpha { - ui7_ctx->cm->front->AddRectangle(npos + NVec2(54, cbs.y * 4 + 4), - NVec2(50, cbs.y), + ui7_ctx->cm->front->AddRectangle(npos + NVec2(54, cbs[1] * 4 + 4), + NVec2(50, cbs[1]), PDColor_FrameBgHovered); ui7_ctx->cm->front->AddRectangle( - npos + NVec2(54, cbs.y * 4 + 4), - NVec2(50 * ((float)clr.m_a / 255.f), cbs.y), 0xffffffff); - ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs.y * 4 + 4), + npos + NVec2(54, cbs[1] * 4 + 4), + NVec2(50 * ((float)clr.m_a / 255.f), cbs[1]), 0xffffffff); + ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs[1] * 4 + 4), "A: " + std::to_string(clr.m_a), PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); } } - ui7_ctx->cm->main->AddRectangle(pos, cbs, outline); ui7_ctx->cm->main->AddRectangle(pos + NVec2(2, 2), cbs - NVec2(4, 4), color); ui7_ctx->cm->main->AddText( - pos + NVec2(cbs.x + 5, 1), label, + pos + NVec2(cbs[0] + 5, 1), label, Palladium::ThemeActive()->AutoText(PDColor_Background)); } @@ -1115,6 +1259,23 @@ void EndTree() { // TODO } +void Prompt(const std::string &label, int &res, const std::string &lcf, + const std::string &lcc) { + if (!UI7CtxValidate()) return; + if (ui7_ctx->promt) return; + auto p = UI7Promt::New(); + p->text = label; + p->res_ptr = &res; + p->confirm = lcf; + p->cancel = lcc; + ui7_ctx->promt = p; +} + +void ClosePromts() { + if (!UI7CtxValidate()) return; + ui7_ctx->promt = nullptr; +} + NVec2 GetCursorPos() { if (!UI7CtxValidate()) return NVec2(); if (!UI7CtxInMenu()) return NVec2(); @@ -1142,6 +1303,19 @@ void SameLine() { ui7_ctx->cm->cursor = ui7_ctx->cm->slc; } +void Separator() { + if (!UI7CtxValidate()) return; + if (!UI7CtxInMenu()) return; + NVec2 pos = GetCursorPos(); + NVec2 size = NVec2( + ui7_ctx->cm->screen_size[0] - (ui7_ctx->cm->enable_scrolling ? 24 : 10), + 1); + MoveCursor(size); + ui7_ctx->cm->ctrl->AddObj(); + if (HandleScrolling(pos, size)) return; + ui7_ctx->cm->main->AddRectangle(pos, size, PDColor_TextDisabled); +} + void Debug() { if (!UI7CtxValidate()) return; if (ui7_ctx->debugging) { @@ -1173,23 +1347,23 @@ void MoveCursor(NVec2 size) { if (!UI7CtxValidate()) return; if (!UI7CtxInMenu()) return; ui7_ctx->cm->lszs = size; - ui7_ctx->cm->slc = ui7_ctx->cm->cursor + NVec2(size.x + 5, 0); - ui7_ctx->cm->cursor.x = 5; - if (ui7_ctx->cm->bslp.y) { - ui7_ctx->cm->cursor += NVec2(0, ui7_ctx->cm->bslp.y + 5); + ui7_ctx->cm->slc = ui7_ctx->cm->cursor + NVec2(size[0] + 5, 0); + ui7_ctx->cm->cursor[0] = 5; + if (ui7_ctx->cm->bslp[1]) { + ui7_ctx->cm->cursor += NVec2(0, ui7_ctx->cm->bslp[1] + 5); ui7_ctx->cm->bslp = NVec2(); } else { - ui7_ctx->cm->cursor += NVec2(0, size.y + 5); + ui7_ctx->cm->cursor += NVec2(0, size[1] + 5); } - ui7_ctx->cm->ms = NVec2(ui7_ctx->cm->slc.x, ui7_ctx->cm->cursor.y); + ui7_ctx->cm->ms = NVec2(ui7_ctx->cm->slc[0], ui7_ctx->cm->cursor[1]); } bool HandleScrolling(NVec2 &pos, NVec2 size) { if (ui7_ctx->cm->enable_scrolling) { NVec2 pb = pos; pos -= NVec2(0, ui7_ctx->cm->scrolling_offset); - if (pos.y > 240 || - (pos.y + size.y < ui7_ctx->cm->tbh - 5 && pb.y > ui7_ctx->cm->tbh)) + if (pos[1] > 240 || + (pos[1] + size[1] < ui7_ctx->cm->tbh - 5 && pb[1] > ui7_ctx->cm->tbh)) return true; } return false; diff --git a/source/Color.cpp b/source/base/Color.cpp similarity index 97% rename from source/Color.cpp rename to source/base/Color.cpp index 58e2074..f3690c7 100644 --- a/source/Color.cpp +++ b/source/base/Color.cpp @@ -1,229 +1,229 @@ -#include -#include -#include -#include -#include -#include -#include - -void pdi_swap32(unsigned int& c) { - c = ((c & 0xFF) << 24) | ((c & 0xFF00) << 8) | ((c & 0xFF0000) >> 8) | - ((c & 0xFF000000) >> 24); -} - -std::string Palladium::Color::RGBA2Hex(unsigned int c32) { - pdi_swap32(c32); - std::stringstream ss; - ss << "#"; - ss << std::hex << std::setw(8) << std::setfill('0') << c32; - return ss.str(); -} - -// Standart Color Converter -static const std::map HEX_TO_DEC = { - {'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5}, - {'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'a', 10}, {'b', 11}, - {'c', 12}, {'d', 13}, {'e', 14}, {'f', 15}, {'A', 10}, {'B', 11}, - {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}}; - -unsigned int pdi_special_color_hex(const std::string& hex) { - if (hex.length() < 9 || std::find_if(hex.begin() + 1, hex.end(), [](char c) { - return !std::isxdigit(c); - }) != hex.end()) { - return pdi_special_color_hex("#00000000"); - } - - int r = HEX_TO_DEC.at(hex[1]) * 16 + HEX_TO_DEC.at(hex[2]); - int g = HEX_TO_DEC.at(hex[3]) * 16 + HEX_TO_DEC.at(hex[4]); - int b = HEX_TO_DEC.at(hex[5]) * 16 + HEX_TO_DEC.at(hex[6]); - int a = HEX_TO_DEC.at(hex[7]) * 16 + HEX_TO_DEC.at(hex[8]); - - return RGBA8(r, g, b, a); -} - -// Default Theme -const std::map pdi_default_theme = { - {PDColor_Text, RGBA8(0, 0, 0, 255)}, - {PDColor_Text2, RGBA8(255, 255, 255, 255)}, // For Background change or so - {PDColor_TextDisabled, RGBA8(170, 170, 170, 255)}, - {PDColor_Background, RGBA8(238, 238, 238, 255)}, - {PDColor_Header, RGBA8(17, 17, 17, 255)}, - {PDColor_Selector, RGBA8(34, 34, 34, 255)}, - {PDColor_SelectorFade, RGBA8(90, 90, 90, 255)}, - {PDColor_List0, RGBA8(204, 204, 204, 255)}, // List0 = % 2 - {PDColor_List1, RGBA8(187, 187, 187, 255)}, - {PDColor_MessageBackground, RGBA8(51, 51, 51, 255)}, - {PDColor_Button, RGBA8(17, 17, 17, 255)}, - {PDColor_ButtonHovered, RGBA8(34, 34, 34, 255)}, - {PDColor_ButtonDisabled, RGBA8(8, 8, 8, 255)}, - {PDColor_ButtonActive, RGBA8(42, 42, 42, 255)}, - {PDColor_Checkmark, RGBA8(42, 42, 42, 255)}, - {PDColor_FrameBg, RGBA8(85, 85, 85, 255)}, - {PDColor_FrameBgHovered, RGBA8(119, 119, 119, 255)}, - {PDColor_Progressbar, RGBA8(0, 255, 0, 255)}, -}; - -void Palladium::Theme::Load(const std::string& path) { - std::ifstream file(path); - if (!file.is_open()) { - return; - } - nlohmann::json js; - file >> js; - // clang-format off - if(THEMEVER != js["version"]) { - file.close(); - return; - } - this->clr_tab.clear(); - this->clr_tab.resize(PDColor_Len); - this->clr_tab[PDColor_Text] = pdi_special_color_hex(js["PDColor_Text"].get()); - this->clr_tab[PDColor_Text2] = pdi_special_color_hex(js["PDColor_Text2"].get()); - this->clr_tab[PDColor_TextDisabled] = pdi_special_color_hex(js["PDColor_TextDisabled"].get()); - this->clr_tab[PDColor_Background] = pdi_special_color_hex(js["PDColor_Background"].get()); - this->clr_tab[PDColor_Header] = pdi_special_color_hex(js["PDColor_Header"].get()); - this->clr_tab[PDColor_Selector] = pdi_special_color_hex(js["PDColor_Selector"].get()); - this->clr_tab[PDColor_SelectorFade] = pdi_special_color_hex(js["PDColor_SelectorFade"].get()); - this->clr_tab[PDColor_List0] = pdi_special_color_hex(js["PDColor_List0"].get()); - this->clr_tab[PDColor_List1] = pdi_special_color_hex(js["PDColor_List1"].get()); - this->clr_tab[PDColor_MessageBackground] = pdi_special_color_hex(js["PDColor_MessageBackground"].get()); - this->clr_tab[PDColor_Button] = pdi_special_color_hex(js["PDColor_Button"].get()); - this->clr_tab[PDColor_ButtonHovered] = pdi_special_color_hex(js["PDColor_ButtonHovered"].get()); - this->clr_tab[PDColor_ButtonDisabled] = pdi_special_color_hex(js["PDColor_ButtonDisabled"].get()); - this->clr_tab[PDColor_ButtonActive] = pdi_special_color_hex(js["PDColor_ButtonActive"].get()); - this->clr_tab[PDColor_Checkmark] = pdi_special_color_hex(js["PDColor_Checkmark"].get()); - this->clr_tab[PDColor_FrameBg] = pdi_special_color_hex(js["PDColor_FrameBg"].get()); - this->clr_tab[PDColor_FrameBgHovered] = pdi_special_color_hex(js["PDColor_FrameBgHovered"].get()); - this->clr_tab[PDColor_Progressbar] = pdi_special_color_hex(js["PDColor_Progressbar"].get()); - // clang-format on - file.close(); -} - -void Palladium::Theme::Default() { - this->clr_tab.clear(); - this->clr_tab.resize(PDColor_Len); - for (auto& it : pdi_default_theme) { - this->clr_tab[it.first] = it.second; - } -} - -void Palladium::Theme::CopyOther(Theme::Ref theme) { - this->clr_tab.clear(); - this->clr_tab.resize(PDColor_Len); - for (int i = 0; i < (int)PDColor_Len; i++) { - this->clr_tab[i] = theme->Get(i); - } -} - -unsigned int Palladium::Theme::Get(PDColor clr) { - if (clr < 0 || clr >= PDColor_Len) return 0; - return this->clr_tab[clr]; -} - -void Palladium::Theme::Set(PDColor clr, unsigned int v) { - if (clr < 0 || clr >= PDColor_Len) return; - this->changes.push_back(change(clr, this->clr_tab[clr], v)); - this->clr_tab[clr] = v; -} -void Palladium::Theme::Swap(PDColor a, PDColor b) { - if (a < 0 || a >= PDColor_Len || b < 0 || b >= PDColor_Len) return; - auto c = this->clr_tab[a]; - this->clr_tab[a] = this->clr_tab[b]; - this->clr_tab[b] = c; - this->changes.push_back(change(a, b, c, this->clr_tab[a])); -} - -void Palladium::Theme::TextBy(PDColor bg) { - if (!Color::RGBA(bg).is_light()) Swap(PDColor_Text, PDColor_Text2); -} - -PDColor Palladium::Theme::AutoText(PDColor bg) { - return Color::RGBA(bg).is_light() ? PDColor_Text : PDColor_Text2; -} - -bool Palladium::Theme::Undo() { - if (!this->changes.size()) return false; - auto ch = this->changes[this->changes.size() - 1]; - this->changes.pop_back(); - if (ch.clr2) { - this->clr_tab[ch.clr2] = ch.to; - this->clr_tab[ch.clr] = ch.from; - } else { - this->clr_tab[ch.clr] = ch.from; - } - return true; -} - -void Palladium::Theme::UndoAll() { - while (Undo()) { - // Just Run Undo Until all is undone - } -} - -void Palladium::Theme::Save(const std::string& path) { - if (std::filesystem::path(path).filename().string() == "Palladium.theme") { - if (!pdi_amdt) { - Palladium::PushMessage("Theme", "Default Theme cannot\nbe overwritten!"); - return; - } - } - std::ofstream file(path); - if (!file.is_open()) { - Palladium::PushMessage("Theme", "Unable to\ncreate file!"); - return; - } - nlohmann::json js; - // clang-format off - js["version"] = THEMEVER; - js["PDColor_Text"] = Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Text]); - js["PDColor_Text2"] = Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Text2]); - js["PDColor_TextDisabled"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_TextDisabled]); js["PDColor_Background"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Background]); js["PDColor_Header"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Header]); js["PDColor_Selector"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Selector]); js["PDColor_SelectorFade"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_SelectorFade]); js["PDColor_List0"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_List0]); js["PDColor_List1"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_List1]); js["PDColor_MessageBackground"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_MessageBackground]); js["PDColor_Button"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Button]); js["PDColor_ButtonHovered"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_ButtonHovered]); - js["PDColor_ButtonDisabled"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_ButtonDisabled]); - js["PDColor_ButtonActive"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_ButtonActive]); js["PDColor_Checkmark"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Checkmark]); js["PDColor_FrameBg"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_FrameBg]); js["PDColor_FrameBgHovered"] = -Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_FrameBgHovered]); js["PDColor_Progressbar"] -= Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Progressbar]); - // clang-format on - file << js.dump(4); - file.close(); -} - -Palladium::Theme::Ref Palladium::ThemeActive() { return pdi_active_theme; } - -void Palladium::ThemeSet(Palladium::Theme::Ref theme) { - pdi_active_theme = theme; -} - -unsigned int Palladium::Color::Hex(const std::string& color, uint8_t a) { - if (color.length() < 7 || - std::find_if(color.begin() + 1, color.end(), - [](char c) { return !std::isxdigit(c); }) != color.end()) { - return Palladium::Color::Hex("#000000", 0); - } - - int r = HEX_TO_DEC.at(color[1]) * 16 + HEX_TO_DEC.at(color[2]); - int g = HEX_TO_DEC.at(color[3]) * 16 + HEX_TO_DEC.at(color[4]); - int b = HEX_TO_DEC.at(color[5]) * 16 + HEX_TO_DEC.at(color[6]); - - return RGBA8(r, g, b, a); -} - -std::string Palladium::Color::RGB2Hex(int r, int g, int b) { - std::stringstream ss; - ss << "#"; - ss << std::hex << (r << 16 | g << 8 | b); - return ss.str(); +#include +#include +#include +#include +#include +#include +#include + +void pdi_swap32(unsigned int& c) { + c = ((c & 0xFF) << 24) | ((c & 0xFF00) << 8) | ((c & 0xFF0000) >> 8) | + ((c & 0xFF000000) >> 24); +} + +std::string Palladium::Color::RGBA2Hex(unsigned int c32) { + pdi_swap32(c32); + std::stringstream ss; + ss << "#"; + ss << std::hex << std::setw(8) << std::setfill('0') << c32; + return ss.str(); +} + +// Standart Color Converter +static const std::map HEX_TO_DEC = { + {'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5}, + {'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'a', 10}, {'b', 11}, + {'c', 12}, {'d', 13}, {'e', 14}, {'f', 15}, {'A', 10}, {'B', 11}, + {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}}; + +unsigned int pdi_special_color_hex(const std::string& hex) { + if (hex.length() < 9 || std::find_if(hex.begin() + 1, hex.end(), [](char c) { + return !std::isxdigit(c); + }) != hex.end()) { + return pdi_special_color_hex("#00000000"); + } + + int r = HEX_TO_DEC.at(hex[1]) * 16 + HEX_TO_DEC.at(hex[2]); + int g = HEX_TO_DEC.at(hex[3]) * 16 + HEX_TO_DEC.at(hex[4]); + int b = HEX_TO_DEC.at(hex[5]) * 16 + HEX_TO_DEC.at(hex[6]); + int a = HEX_TO_DEC.at(hex[7]) * 16 + HEX_TO_DEC.at(hex[8]); + + return RGBA8(r, g, b, a); +} + +// Default Theme +const std::map pdi_default_theme = { + {PDColor_Text, RGBA8(0, 0, 0, 255)}, + {PDColor_Text2, RGBA8(255, 255, 255, 255)}, // For Background change or so + {PDColor_TextDisabled, RGBA8(170, 170, 170, 255)}, + {PDColor_Background, RGBA8(238, 238, 238, 255)}, + {PDColor_Header, RGBA8(17, 17, 17, 255)}, + {PDColor_Selector, RGBA8(34, 34, 34, 255)}, + {PDColor_SelectorFade, RGBA8(90, 90, 90, 255)}, + {PDColor_List0, RGBA8(204, 204, 204, 255)}, // List0 = % 2 + {PDColor_List1, RGBA8(187, 187, 187, 255)}, + {PDColor_MessageBackground, RGBA8(51, 51, 51, 255)}, + {PDColor_Button, RGBA8(17, 17, 17, 255)}, + {PDColor_ButtonHovered, RGBA8(34, 34, 34, 255)}, + {PDColor_ButtonDisabled, RGBA8(8, 8, 8, 255)}, + {PDColor_ButtonActive, RGBA8(42, 42, 42, 255)}, + {PDColor_Checkmark, RGBA8(42, 42, 42, 255)}, + {PDColor_FrameBg, RGBA8(85, 85, 85, 255)}, + {PDColor_FrameBgHovered, RGBA8(119, 119, 119, 255)}, + {PDColor_Progressbar, RGBA8(0, 255, 0, 255)}, +}; + +void Palladium::Theme::Load(const std::string& path) { + std::ifstream file(path); + if (!file.is_open()) { + return; + } + nlohmann::json js; + file >> js; + // clang-format off + if(THEMEVER != js["version"]) { + file.close(); + return; + } + this->clr_tab.clear(); + this->clr_tab.resize(PDColor_Len); + this->clr_tab[PDColor_Text] = pdi_special_color_hex(js["PDColor_Text"].get()); + this->clr_tab[PDColor_Text2] = pdi_special_color_hex(js["PDColor_Text2"].get()); + this->clr_tab[PDColor_TextDisabled] = pdi_special_color_hex(js["PDColor_TextDisabled"].get()); + this->clr_tab[PDColor_Background] = pdi_special_color_hex(js["PDColor_Background"].get()); + this->clr_tab[PDColor_Header] = pdi_special_color_hex(js["PDColor_Header"].get()); + this->clr_tab[PDColor_Selector] = pdi_special_color_hex(js["PDColor_Selector"].get()); + this->clr_tab[PDColor_SelectorFade] = pdi_special_color_hex(js["PDColor_SelectorFade"].get()); + this->clr_tab[PDColor_List0] = pdi_special_color_hex(js["PDColor_List0"].get()); + this->clr_tab[PDColor_List1] = pdi_special_color_hex(js["PDColor_List1"].get()); + this->clr_tab[PDColor_MessageBackground] = pdi_special_color_hex(js["PDColor_MessageBackground"].get()); + this->clr_tab[PDColor_Button] = pdi_special_color_hex(js["PDColor_Button"].get()); + this->clr_tab[PDColor_ButtonHovered] = pdi_special_color_hex(js["PDColor_ButtonHovered"].get()); + this->clr_tab[PDColor_ButtonDisabled] = pdi_special_color_hex(js["PDColor_ButtonDisabled"].get()); + this->clr_tab[PDColor_ButtonActive] = pdi_special_color_hex(js["PDColor_ButtonActive"].get()); + this->clr_tab[PDColor_Checkmark] = pdi_special_color_hex(js["PDColor_Checkmark"].get()); + this->clr_tab[PDColor_FrameBg] = pdi_special_color_hex(js["PDColor_FrameBg"].get()); + this->clr_tab[PDColor_FrameBgHovered] = pdi_special_color_hex(js["PDColor_FrameBgHovered"].get()); + this->clr_tab[PDColor_Progressbar] = pdi_special_color_hex(js["PDColor_Progressbar"].get()); + // clang-format on + file.close(); +} + +void Palladium::Theme::Default() { + this->clr_tab.clear(); + this->clr_tab.resize(PDColor_Len); + for (auto& it : pdi_default_theme) { + this->clr_tab[it.first] = it.second; + } +} + +void Palladium::Theme::CopyOther(Theme::Ref theme) { + this->clr_tab.clear(); + this->clr_tab.resize(PDColor_Len); + for (int i = 0; i < (int)PDColor_Len; i++) { + this->clr_tab[i] = theme->Get(i); + } +} + +unsigned int Palladium::Theme::Get(PDColor clr) { + if (clr < 0 || clr >= PDColor_Len) return 0; + return this->clr_tab[clr]; +} + +void Palladium::Theme::Set(PDColor clr, unsigned int v) { + if (clr < 0 || clr >= PDColor_Len) return; + this->changes.push_back(change(clr, this->clr_tab[clr], v)); + this->clr_tab[clr] = v; +} +void Palladium::Theme::Swap(PDColor a, PDColor b) { + if (a < 0 || a >= PDColor_Len || b < 0 || b >= PDColor_Len) return; + auto c = this->clr_tab[a]; + this->clr_tab[a] = this->clr_tab[b]; + this->clr_tab[b] = c; + this->changes.push_back(change(a, b, c, this->clr_tab[a])); +} + +void Palladium::Theme::TextBy(PDColor bg) { + if (!Color::RGBA(bg).is_light()) Swap(PDColor_Text, PDColor_Text2); +} + +PDColor Palladium::Theme::AutoText(PDColor bg) { + return Color::RGBA(bg).is_light() ? PDColor_Text : PDColor_Text2; +} + +bool Palladium::Theme::Undo() { + if (!this->changes.size()) return false; + auto ch = this->changes[this->changes.size() - 1]; + this->changes.pop_back(); + if (ch.clr2) { + this->clr_tab[ch.clr2] = ch.to; + this->clr_tab[ch.clr] = ch.from; + } else { + this->clr_tab[ch.clr] = ch.from; + } + return true; +} + +void Palladium::Theme::UndoAll() { + while (Undo()) { + // Just Run Undo Until all is undone + } +} + +void Palladium::Theme::Save(const std::string& path) { + if (std::filesystem::path(path).filename().string() == "Palladium.theme") { + if (!pdi_amdt) { + Palladium::PushMessage("Theme", "Default Theme cannot\nbe overwritten!"); + return; + } + } + std::ofstream file(path); + if (!file.is_open()) { + Palladium::PushMessage("Theme", "Unable to\ncreate file!"); + return; + } + nlohmann::json js; + // clang-format off + js["version"] = THEMEVER; + js["PDColor_Text"] = Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Text]); + js["PDColor_Text2"] = Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Text2]); + js["PDColor_TextDisabled"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_TextDisabled]); js["PDColor_Background"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Background]); js["PDColor_Header"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Header]); js["PDColor_Selector"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Selector]); js["PDColor_SelectorFade"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_SelectorFade]); js["PDColor_List0"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_List0]); js["PDColor_List1"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_List1]); js["PDColor_MessageBackground"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_MessageBackground]); js["PDColor_Button"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Button]); js["PDColor_ButtonHovered"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_ButtonHovered]); + js["PDColor_ButtonDisabled"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_ButtonDisabled]); + js["PDColor_ButtonActive"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_ButtonActive]); js["PDColor_Checkmark"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Checkmark]); js["PDColor_FrameBg"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_FrameBg]); js["PDColor_FrameBgHovered"] = +Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_FrameBgHovered]); js["PDColor_Progressbar"] += Palladium::Color::RGBA2Hex(this->clr_tab[PDColor_Progressbar]); + // clang-format on + file << js.dump(4); + file.close(); +} + +Palladium::Theme::Ref Palladium::ThemeActive() { return pdi_active_theme; } + +void Palladium::ThemeSet(Palladium::Theme::Ref theme) { + pdi_active_theme = theme; +} + +unsigned int Palladium::Color::Hex(const std::string& color, uint8_t a) { + if (color.length() < 7 || + std::find_if(color.begin() + 1, color.end(), + [](char c) { return !std::isxdigit(c); }) != color.end()) { + return Palladium::Color::Hex("#000000", 0); + } + + int r = HEX_TO_DEC.at(color[1]) * 16 + HEX_TO_DEC.at(color[2]); + int g = HEX_TO_DEC.at(color[3]) * 16 + HEX_TO_DEC.at(color[4]); + int b = HEX_TO_DEC.at(color[5]) * 16 + HEX_TO_DEC.at(color[6]); + + return RGBA8(r, g, b, a); +} + +std::string Palladium::Color::RGB2Hex(int r, int g, int b) { + std::stringstream ss; + ss << "#"; + ss << std::hex << (r << 16 | g << 8 | b); + return ss.str(); } \ No newline at end of file diff --git a/source/FileSystem.cpp b/source/base/FileSystem.cpp similarity index 94% rename from source/FileSystem.cpp rename to source/base/FileSystem.cpp index 84c61f5..ca77a0e 100644 --- a/source/FileSystem.cpp +++ b/source/base/FileSystem.cpp @@ -1,70 +1,70 @@ -#include <3ds.h> -#include -#include -#include - -#include -#include -// Debugging -#include -#include -#include - -bool ___dir__predicate__(const Palladium::FileSystem::Entry &lhs, - const Palladium::FileSystem::Entry &rhs) { - if (!lhs.dir && rhs.dir) return false; - if (lhs.dir && !rhs.dir) return true; - std::string a = lhs.name; - std::string b = rhs.name; - std::transform(a.begin(), a.end(), a.begin(), - [](int i) { return std::tolower(i); }); - std::transform(b.begin(), b.end(), b.begin(), - [](int i) { return std::tolower(i); }); - return a.compare(b) < 0; -} - -std::string Palladium::FileSystem::GetParentPath(std::string path, - std::string mount_point) { - std::string tcl = path; - if (path.substr(path.length() - 1, 1) != "/") { - tcl += "/"; - } - std::string res = - std::filesystem::path(tcl).parent_path().parent_path().string(); - if (res.length() > mount_point.length()) { - return res; - } - - return mount_point; -} - -std::vector Palladium::FileSystem::GetDirContent( - std::string path) { - std::vector res; - for (const auto &entry : - std::filesystem::directory_iterator(std::filesystem::path(path))) { - res.push_back({entry.path().string(), GetFileName(entry.path().string()), - entry.is_directory()}); - } - return res; -} - -std::vector -Palladium::FileSystem::GetDirContentsExt( - std::string &path, const std::vector &extensions) { - std::vector res; - for (auto const &it : - std::filesystem::directory_iterator(std::filesystem::path(path))) { - Palladium::FileSystem::Entry temp; - std::string fn = it.path().string(); - temp.name = GetFileName(fn); - temp.path = it.path().string().c_str(); - temp.dir = it.is_directory(); - if (NameIsEndingWith(GetFileName(it.path().string()), extensions) || - it.is_directory()) { - res.push_back(temp); - } - } - std::sort(res.begin(), res.end(), ___dir__predicate__); - return res; -} +#include <3ds.h> +#include +#include +#include + +#include +#include +// Debugging +#include +#include +#include + +bool ___dir__predicate__(const Palladium::FileSystem::Entry &lhs, + const Palladium::FileSystem::Entry &rhs) { + if (!lhs.dir && rhs.dir) return false; + if (lhs.dir && !rhs.dir) return true; + std::string a = lhs.name; + std::string b = rhs.name; + std::transform(a.begin(), a.end(), a.begin(), + [](int i) { return std::tolower(i); }); + std::transform(b.begin(), b.end(), b.begin(), + [](int i) { return std::tolower(i); }); + return a.compare(b) < 0; +} + +std::string Palladium::FileSystem::GetParentPath(std::string path, + std::string mount_point) { + std::string tcl = path; + if (path.substr(path.length() - 1, 1) != "/") { + tcl += "/"; + } + std::string res = + std::filesystem::path(tcl).parent_path().parent_path().string(); + if (res.length() > mount_point.length()) { + return res; + } + + return mount_point; +} + +std::vector Palladium::FileSystem::GetDirContent( + std::string path) { + std::vector res; + for (const auto &entry : + std::filesystem::directory_iterator(std::filesystem::path(path))) { + res.push_back({entry.path().string(), GetFileName(entry.path().string()), + entry.is_directory()}); + } + return res; +} + +std::vector +Palladium::FileSystem::GetDirContentsExt( + std::string &path, const std::vector &extensions) { + std::vector res; + for (auto const &it : + std::filesystem::directory_iterator(std::filesystem::path(path))) { + Palladium::FileSystem::Entry temp; + std::string fn = it.path().string(); + temp.name = GetFileName(fn); + temp.path = it.path().string().c_str(); + temp.dir = it.is_directory(); + if (NameIsEndingWith(GetFileName(it.path().string()), extensions) || + it.is_directory()) { + res.push_back(temp); + } + } + std::sort(res.begin(), res.end(), ___dir__predicate__); + return res; +} diff --git a/source/FunctionTrace.cpp b/source/base/FunctionTrace.cpp similarity index 67% rename from source/FunctionTrace.cpp rename to source/base/FunctionTrace.cpp index a50d2b8..03acfc2 100644 --- a/source/FunctionTrace.cpp +++ b/source/base/FunctionTrace.cpp @@ -1,3 +1,3 @@ -#include - +#include + std::map Palladium::Ftrace::pd_traces; \ No newline at end of file diff --git a/source/lang.cpp b/source/base/Lang.cpp similarity index 94% rename from source/lang.cpp rename to source/base/Lang.cpp index 7f48ea8..b3370c2 100644 --- a/source/lang.cpp +++ b/source/base/Lang.cpp @@ -1,118 +1,118 @@ -#include <3ds.h> - -#include -#include -#include - -static nlohmann::json appJson; - -std::string Palladium::Lang::GetSys() { - u8 language = 1; - CFGU_GetSystemLanguage(&language); - - switch (language) { - case 0: - return "jp"; // Japanese - break; - - case 1: - return "en"; // English - break; - - case 2: - return "fr"; // French - break; - - case 3: - return "de"; // German - break; - - case 4: - return "it"; // Italian - break; - - case 5: - return "es"; // Spanish - break; - - case 6: - return "zh-CN"; // Chinese (Simplified) - break; - - case 7: - return "ko"; // Korean - break; - - case 8: - return "nl"; // Dutch - break; - - case 9: - return "pt"; // Portuguese - break; - - case 10: - return "ru"; // Russian - break; - - case 11: - return "zh-TW"; // Chinese (Traditional) - break; - - default: - return "en"; // Fall back to English if missing - break; - } -} -std::string Palladium::Lang::Get(const std::string &key) { - if (!appJson.contains("keys")) return "ERR-01"; - nlohmann::json js = appJson["keys"]; - if (!js.contains(key)) return key; - return js.at(key).get(); -} - -void Palladium::Lang::Load(const std::string &lang) { - std::fstream values; - if (std::filesystem::exists("romfs:/lang/" + lang + "/app.json")) { - values.open("romfs:/lang/" + lang + "/app.json", std::ios::in); - if (values.is_open()) { - appJson = nlohmann::json::parse(values); - } - values.close(); - if (appJson.is_discarded()) { - appJson = {}; - } - return; - } else { - values.open("romfs:/lang/en/app.json", std::ios::in); - if (values.is_open()) { - appJson = nlohmann::json::parse(values); - } - values.close(); - if (appJson.is_discarded()) { - appJson = {}; - } - return; - } -} - -std::string Palladium::Lang::GetName() { - if (!appJson.contains("info")) return ""; - nlohmann::json js = appJson["info"]; - if (!js.contains("name")) return "Unknown"; - return js.at("name").get(); -} - -std::string Palladium::Lang::GetAuthor() { - if (!appJson.contains("info")) return ""; - nlohmann::json js = appJson["info"]; - if (!js.contains("author")) return "Unknown"; - return js.at("author").get(); -} - -std::string Palladium::Lang::GetShortcut() { - if (!appJson.contains("info")) return ""; - nlohmann::json js = appJson["info"]; - if (!js.contains("shortcut")) return "Unknown"; - return js.at("shortcut").get(); +#include <3ds.h> + +#include +#include +#include + +static nlohmann::json appJson; + +std::string Palladium::Lang::GetSys() { + u8 language = 1; + CFGU_GetSystemLanguage(&language); + + switch (language) { + case 0: + return "jp"; // Japanese + break; + + case 1: + return "en"; // English + break; + + case 2: + return "fr"; // French + break; + + case 3: + return "de"; // German + break; + + case 4: + return "it"; // Italian + break; + + case 5: + return "es"; // Spanish + break; + + case 6: + return "zh-CN"; // Chinese (Simplified) + break; + + case 7: + return "ko"; // Korean + break; + + case 8: + return "nl"; // Dutch + break; + + case 9: + return "pt"; // Portuguese + break; + + case 10: + return "ru"; // Russian + break; + + case 11: + return "zh-TW"; // Chinese (Traditional) + break; + + default: + return "en"; // Fall back to English if missing + break; + } +} +std::string Palladium::Lang::Get(const std::string &key) { + if (!appJson.contains("keys")) return "ERR-01"; + nlohmann::json js = appJson["keys"]; + if (!js.contains(key)) return key; + return js.at(key).get(); +} + +void Palladium::Lang::Load(const std::string &lang) { + std::fstream values; + if (std::filesystem::exists("romfs:/lang/" + lang + "/app.json")) { + values.open("romfs:/lang/" + lang + "/app.json", std::ios::in); + if (values.is_open()) { + appJson = nlohmann::json::parse(values); + } + values.close(); + if (appJson.is_discarded()) { + appJson = {}; + } + return; + } else { + values.open("romfs:/lang/en/app.json", std::ios::in); + if (values.is_open()) { + appJson = nlohmann::json::parse(values); + } + values.close(); + if (appJson.is_discarded()) { + appJson = {}; + } + return; + } +} + +std::string Palladium::Lang::GetName() { + if (!appJson.contains("info")) return ""; + nlohmann::json js = appJson["info"]; + if (!js.contains("name")) return "Unknown"; + return js.at("name").get(); +} + +std::string Palladium::Lang::GetAuthor() { + if (!appJson.contains("info")) return ""; + nlohmann::json js = appJson["info"]; + if (!js.contains("author")) return "Unknown"; + return js.at("author").get(); +} + +std::string Palladium::Lang::GetShortcut() { + if (!appJson.contains("info")) return ""; + nlohmann::json js = appJson["info"]; + if (!js.contains("shortcut")) return "Unknown"; + return js.at("shortcut").get(); } \ No newline at end of file diff --git a/source/Memory.cpp b/source/base/Memory.cpp similarity index 76% rename from source/Memory.cpp rename to source/base/Memory.cpp index 77acece..bdf1467 100644 --- a/source/Memory.cpp +++ b/source/base/Memory.cpp @@ -1,56 +1,55 @@ -#include -#include -#include - -static Palladium::Memory::memory_metrics metrics; - -bool pdi_enable_memtrack; - -void *operator new(size_t size) { - void *ptr = malloc(size); - if (pdi_enable_memtrack) metrics.t_TotalAllocated += size; - return ptr; -} - -void operator delete(void *memory, size_t size) { - if (pdi_enable_memtrack) metrics.t_TotalFreed += size; - free(memory); -} - -int allocations = 0; -int total_size = 0; -std::map sizes; - -void *operator new[](size_t size) { - void *ptr = malloc(size); - if (pdi_enable_memtrack) { - allocations++; - total_size += size; - sizes[ptr] = size; - metrics.t_TotalAllocated += size; - } - - return ptr; -} - -void operator delete[](void *ptr) { - if (pdi_enable_memtrack) { - allocations--; - total_size -= sizes[ptr]; - metrics.t_TotalFreed += sizes[ptr]; - sizes.erase(ptr); - } - free(ptr); -} - -namespace Palladium { - -namespace Memory { - -size_t GetTotalAllocated() { return metrics.t_TotalAllocated; } - -size_t GetTotalFreed() { return metrics.t_TotalFreed; } - -size_t GetCurrent() { return metrics.t_CurrentlyAllocated(); } -} // namespace Memory -} // namespace Palladium +#include +#include +#include +#include + +static Palladium::Memory::memory_metrics metrics; + +void *operator new(size_t size) { + void *ptr = malloc(size); + if (pd_flags & PDFlags_MemTrack) metrics.t_TotalAllocated += size; + return ptr; +} + +void operator delete(void *memory, size_t size) { + if (pd_flags & PDFlags_MemTrack) metrics.t_TotalFreed += size; + free(memory); +} + +int allocations = 0; +int total_size = 0; +std::map sizes; + +void *operator new[](size_t size) { + void *ptr = malloc(size); + if (pd_flags & PDFlags_MemTrack) { + allocations++; + total_size += size; + sizes[ptr] = size; + metrics.t_TotalAllocated += size; + } + + return ptr; +} + +void operator delete[](void *ptr) { + if (pd_flags & PDFlags_MemTrack) { + allocations--; + total_size -= sizes[ptr]; + metrics.t_TotalFreed += sizes[ptr]; + sizes.erase(ptr); + } + free(ptr); +} + +namespace Palladium { + +namespace Memory { + +size_t GetTotalAllocated() { return metrics.t_TotalAllocated; } + +size_t GetTotalFreed() { return metrics.t_TotalFreed; } + +size_t GetCurrent() { return metrics.t_CurrentlyAllocated(); } +} // namespace Memory +} // namespace Palladium diff --git a/source/internal_db.cpp b/source/internal_db.cpp index ed85c2e..f2e53b9 100644 --- a/source/internal_db.cpp +++ b/source/internal_db.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include @@ -23,9 +23,6 @@ u8 pdi_system_region = CFG_REGION_USA; bool pdi_is_citra = false; bool pdi_settings = false; NVec2 pdi_hid_touch_pos; -C2D_TextBuf pdi_text_buffer; -C2D_Font pdi_base_font; -C2D_TextBuf pdi_d2_dimbuf; bool pdi_is_ndsp = false; bool pdi_running = false; std::stack> Palladium::Scene::scenes; @@ -34,15 +31,15 @@ std::vector> pdi_overlays; unsigned int pdi_frames = 0; u64 pdi_last_time = 0; float pdi_framerate = 0.0f; -u32 pdi_mt_color = 0xaa000000; -u32 pdi_mt_txtcolor = 0xbbffffff; +unsigned int pdi_mt_color = 0xaa000000; +unsigned int pdi_mt_txtcolor = 0xbbffffff; bool pdi_mt_screen; float pdi_mt_txtSize; bool pdi_metrikd = false; bool pdi_ftraced = false; u64 pdi_delta_time; -u64 pdi_last_tm; -float pdi_dtm; +u64 pdi_last_tm = 0; +float pdi_dtm = 0.f; float pdi_time; bool pdi_fadeout = false, pdi_fadein = false, pdi_fadeout2 = false, pdi_fadein2 = false; @@ -58,17 +55,8 @@ bool pdi_amdt = false; void *pdi_soc_buf = nullptr; bool pdi_is_am_init = false; Palladium::Theme::Ref pdi_active_theme; -Palladium::LoggerBase::Ref pdi_logger; bool pdi_lggrf = false; -Palladium::LoggerBase::Ref _pdi_logger() { - if (!pdi_logger) { - Palladium::Error( - "You're trying to use a Palladium Func without Init Palladium!"); - } - return pdi_logger; -} - /// Global /// // Outdated HidApi (HidV2Patched) u32 d7_hDown; @@ -78,12 +66,13 @@ u32 d7_hRepeat; // Inofficial lol touchPosition d7_touch; // Modern Global Api -int pd_max_objects = C2D_DEFAULT_MAX_OBJECTS; bool pdi_enable_scene_system = true; bool pdi_debugging = false; C3D_RenderTarget *pd_top; C3D_RenderTarget *pd_top_right; C3D_RenderTarget *pd_bottom; +PDMetrikOverlayFlags pd_ovl_flags = PDMetrikOverlayFlags_Default; +PDFTraceOverlayFlags pd_ftrace_ovl_flags = PDFTraceOverlayFlags_Default; Palladium::Net::Error pdi_soc_init() { if (pdi_soc_buf != nullptr) { @@ -183,8 +172,7 @@ struct pak32 { pak32() {} pak32(const std::string &n0, float n1, unsigned char n2, unsigned char n3, bool n4, bool n5, bool n6, float n7, float n8, float n9, float n10, - unsigned int n11, unsigned int n12, unsigned int n13, - unsigned int n14) { + unsigned int n11, unsigned int n12, unsigned int n13) { magic = 0x44772277; for (int i = 0; i < 64; i++) app_name[i] = (char)0; int l = n0.length(); @@ -203,7 +191,6 @@ struct pak32 { mem_alloc = n11; mem_dalloc = n12; mem_ialloc = n13; - tbs = n14; } uint32_t magic; char app_name[64]; @@ -220,7 +207,6 @@ struct pak32 { unsigned int mem_alloc; unsigned int mem_dalloc; unsigned int mem_ialloc; - unsigned int tbs; }; static bool pdi_idb_fp = false; @@ -249,8 +235,7 @@ void ServerThread(Palladium::Parameter param) { pdi_is_citra, pdi_is_ndsp, pdi_settings, pdi_dtm, pdi_time, C3D_GetProcessingTime(), C3D_GetDrawingTime(), Palladium::Memory::GetTotalAllocated(), - Palladium::Memory::GetTotalFreed(), Palladium::Memory::GetCurrent(), - C2D_TextBufGetNumGlyphs(pdi_text_buffer)); + Palladium::Memory::GetTotalFreed(), Palladium::Memory::GetCurrent()); server.snd(stupid(pak)); } else if (cmd == 2) { pdi_reacttion(2); diff --git a/source/palladium.cpp b/source/palladium.cpp index a55fdbf..830560a 100644 --- a/source/palladium.cpp +++ b/source/palladium.cpp @@ -1,5 +1,5 @@ #include // Integate HidApi -#include +#include #include #include #include @@ -12,6 +12,7 @@ // C++ includes #include +#include #include #define DISPLAY_TRANSFER_FLAGS \ @@ -20,11 +21,19 @@ GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) -Palladium::LoggerBase::Ref pdi_glogger; -extern Palladium::LoggerBase::Ref pdi_logger; +void exit_romfs() { romfsExit(); } -void exit_romfs() { - romfsExit(); +// OVL FLAG ENTRY +void OverlayFlag(PDMetrikOverlayFlags &flags, int flag, std::string name) { + bool val = flags & flag; + bool valb = val; + UI7::Checkbox(name, val); + if (val != valb) { + if (val) + flags |= flag; + else + flags &= ~flag; + } } // TODO: Better Fader @@ -60,11 +69,11 @@ void Npifade() { // No fade } /*if (pdi_fadein || pdi_fadeout) { - Palladium::R2::OnScreen(Palladium::R2Screen_Top); - Palladium::R2::AddRect(NVec2(0, 0), NVec2(400, 240), + LI::OnScreen(LIScreen_Top); + LI::AddRect(NVec2(0, 0), NVec2(400, 240), ((pdi_fadealpha << 24) | 0x00000000)); - Palladium::R2::OnScreen(Palladium::R2Screen_Bottom); - Palladium::R2::AddRect(NVec2(0, 0), NVec2(320, 240), + LI::OnScreen(LIScreen_Bottom); + LI::AddRect(NVec2(0, 0), NVec2(320, 240), ((pdi_fadealpha << 24) | 0x00000000)); }*/ } @@ -140,10 +149,10 @@ void pdi_init_config() { pdi_config["info"]["Palladiumver"] = PDVSTRING; pdi_config["metrik-settings"]["show"] = false; pdi_config["metrik-settings"]["Screen"] = true; - pdi_config["metrik-settings"]["Text"] = "#ffffffff"; - pdi_config["metrik-settings"]["Bg"] = "#aa000000"; + pdi_config["metrik-settings"]["Text"] = 0xffffffff; + pdi_config["metrik-settings"]["Bg"] = 0xaa000000; pdi_config["metrik-settings"]["Size"] = 0.7f; - pdi_config["internal_logger"]["nowritetxt"] = true; + pdi_config["metrik-settings"]["config"] = PDMetrikOverlayFlags_Default; std::fstream cfg_wrt(pdi_config_path + "/config.rc7", std::ios::out); cfg_wrt << pdi_config.dump(4); cfg_wrt.close(); @@ -155,7 +164,9 @@ void pdi_init_config() { pdi_metrikd = pdi_config["metrik-settings"]["show"].get(); pdi_mt_txtSize = pdi_config["metrik-settings"]["Size"].get(); pdi_mt_screen = pdi_config["metrik-settings"]["Screen"].get(); - pdi_lggrf = pdi_config["internal_logger"]["nowritetxt"].get(); + pdi_mt_txtcolor = pdi_config["metrik-settings"]["Text"].get(); + pdi_mt_color = pdi_config["metrik-settings"]["Bg"].get(); + pd_ovl_flags = pdi_config["metrik-settings"]["config"].get(); if (pdi_metrikd) Palladium::AddOvl(std::make_unique( @@ -188,15 +199,7 @@ void pdi_init_theme() { } } -Palladium::LoggerBase::Ref Palladium::Logger() { - if (!pdi_glogger) { - Palladium::Error("Logger Was Called before being Init!"); - // return schould not be reached then - } - return pdi_glogger; -} - -float Palladium::GetDeltaTime() { return (float)pdi_dtm; } +float Palladium::GetDeltaTime() { return pdi_dtm; } void Palladium::Init::NdspFirm() { if (access("sdmc:/3ds/dspfirm.cdc", F_OK) != -1) { @@ -249,14 +252,11 @@ std::string Palladium::GetFramerate() { } bool Palladium::MainLoop() { - Palladium::Ftrace::ScopedTrace st("pd-core", f2s(MainLoop)); if (!aptMainLoop()) return false; // Deltatime uint64_t currentTime = svcGetSystemTick(); - pdi_dtm = ((float)(currentTime / (float)TICKS_PER_MSEC) - - (float)(pdi_last_tm / (float)TICKS_PER_MSEC)) / - 1000.f; - pdi_time += pdi_dtm; + pdi_dtm = static_cast(currentTime - pdi_last_tm) / TICKS_PER_MSEC; + pdi_time += pdi_dtm * 0.001f; pdi_last_tm = currentTime; hidScanInput(); @@ -269,8 +269,9 @@ bool Palladium::MainLoop() { Hid::Update(); pdi_hid_touch_pos = NVec2(d7_touch.px, d7_touch.py); - // Palladium::ClearTextBufs(); + Palladium::Ftrace::End("pd-core", f2s(MainLoop)); C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + Palladium::Ftrace::Beg("pd-core", f2s(MainLoop)); C3D_RenderTargetClear(pd_top, C3D_CLEAR_ALL, 0x00000000, 0); C3D_RenderTargetClear(pd_top_right, C3D_CLEAR_ALL, 0x00000000, 0); @@ -284,26 +285,19 @@ bool Palladium::MainLoop() { } void Palladium::Init::Graphics() { - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - C2D_Init((size_t)pd_max_objects); - C2D_Prepare(); - pd_top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); - pd_top_right = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); - pd_bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); - pdi_text_buffer = C2D_TextBufNew(4096); - pdi_d2_dimbuf = C2D_TextBufNew(4096); - pdi_base_font = C2D_FontLoadSystem(CFG_REGION_USA); - R2::Init(); + // C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + // C2D_Init((size_t)pd_max_objects); + // C2D_Prepare(); + // pd_top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); + // pd_top_right = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); + // pd_bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); } Result Palladium::Init::Main(std::string app_name) { Palladium::Ftrace::ScopedTrace st("pd-core", f2s(Init::Main)); pdi_app_name = app_name; - pdi_logger = LoggerBase::New(); - pdi_glogger = LoggerBase::New(); pdi_enable_scene_system = (pd_flags & PDFlags_SceneSystem); - pdi_enable_memtrack = (pd_flags & PDFlags_MemTrack); gfxInitDefault(); atexit(gfxExit); @@ -320,14 +314,12 @@ Result Palladium::Init::Main(std::string app_name) { romfsInit(); pdi_init_config(); - _pdi_logger()->Init("Palladium", pdi_lggrf); pdi_active_theme = Theme::New(); pdi_active_theme->Default(); auto ret = pdi_soc_init(); if (ret) { - pdi_logger->Write("Failed to Init Soc!"); Palladium::PushMessage("Palladium", "Failed to\nInit Soc!"); } else { atexit(pdi_soc_deinit); @@ -354,11 +346,9 @@ Result Palladium::Init::Main(std::string app_name) { C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetOutput(pd_bottom, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); - LI7::Init(); - atexit(LI7::Exit); + LI::Init(); + atexit(LI::Exit); atexit(exit_romfs); - R2::Init(); - R2::Init(); pdi_graphics_on = true; pdi_last_tm = svcGetSystemTick(); @@ -374,25 +364,20 @@ Result Palladium::Init::Main(std::string app_name) { Result Palladium::Init::Minimal(std::string app_name) { Palladium::Ftrace::ScopedTrace st("pd-core", f2s(Init::Minimal)); pdi_app_name = app_name; - pdi_logger = LoggerBase::New(); - pdi_glogger = LoggerBase::New(); pdi_enable_scene_system = (pd_flags & PDFlags_SceneSystem); - pdi_enable_memtrack = (pd_flags & PDFlags_MemTrack); gfxInitDefault(); atexit(gfxExit); romfsInit(); pdi_init_config(); - _pdi_logger()->Init("Palladium", pdi_lggrf); pdi_active_theme = Theme::New(); pdi_active_theme->Default(); auto ret = pdi_soc_init(); if (ret) { - pdi_logger->Write("Failed to Init Soc!"); Palladium::PushMessage("Palladium", "Failed to\nInit Soc!"); } else { atexit(pdi_soc_deinit); @@ -420,10 +405,9 @@ Result Palladium::Init::Minimal(std::string app_name) { C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetOutput(pd_bottom, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); - LI7::Init(); - atexit(LI7::Exit); + LI::Init(); + atexit(LI::Exit); atexit(exit_romfs); - R2::Init(); pdi_graphics_on = true; @@ -441,20 +425,10 @@ Result Palladium::Init::Minimal(std::string app_name) { } Result Palladium::Init::Reload() { - pdi_graphics_on = false; - C2D_TextBufDelete(pdi_text_buffer); - C2D_Fini(); - C3D_Fini(); - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - C2D_Init((size_t)pd_max_objects); - C2D_Prepare(); - pd_top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); - pd_top_right = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); - pd_bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); - pdi_text_buffer = C2D_TextBufNew(4096); - pdi_base_font = C2D_FontLoadSystem(CFG_REGION_USA); - R2::Init(); - pdi_graphics_on = true; + // pdi_graphics_on = false; + // C3D_Fini(); + // C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + // pdi_graphics_on = true; return 0; } @@ -501,20 +475,20 @@ void Palladium::FrameEnd() { } UI7::Update(); UI7::Debug(); + // Use Heigh Layer for Overlays + LI::Layer(LI::Layer() + 100); Palladium::ProcessMessages(); OvlHandler(); Npifade(); - R2::Process(); - LI7::Render(pd_top, pd_bottom); + LI::Render(pd_top, pd_bottom); C3D_FrameEnd(0); } Palladium::RSettings::RSettings() { // Palladium Settings is designed for // System Font - R2::DefaultFont(); - tmp_txt = R2::GetTextSize(); - R2::DefaultTextSize(); + tmp_txt = LI::GetTextScale(); + LI::DefaultTextScale(); Palladium::FadeIn(); std::fstream cfg_ldr(pdi_config_path + "/config.rc7", std::ios::in); cfg_ldr >> pdi_config; @@ -524,7 +498,7 @@ Palladium::RSettings::RSettings() { stateftold = pdi_ftraced; } -Palladium::RSettings::~RSettings() { R2::SetTextSize(tmp_txt); } +Palladium::RSettings::~RSettings() { LI::SetTextScale(tmp_txt); } std::vector StrHelper(std::string input) { std::string ss(input); @@ -536,16 +510,9 @@ std::vector StrHelper(std::string input) { return test1; } -void DisplayCodepoint(char cp) { - if(!UI7::InMenu()) return; - NVec2 szs = NVec2(297, 52); - NVec2 pos = UI7::GetCursorPos(); - UI7::MoveCursor(szs); -} - void Palladium::RSettings::Draw(void) const { if (m_state == RSETTINGS) { - Palladium::R2::OnScreen(R2Screen_Top); + LI::OnScreen(false); if (UI7::BeginMenu("Palladium -> Settings")) { UI7::SetCursorPos(NVec2(395, 2)); UI7::Label(PDVSTRING, PDTextFlags_AlignRight); @@ -557,10 +524,11 @@ void Palladium::RSettings::Draw(void) const { UI7::Label("Current: " + std::to_string(Palladium::Memory::GetCurrent()) + "b"); UI7::Label("Delta: " + std::to_string(Palladium::GetDeltaTime())); + UI7::Label("Time: " + std::to_string(Palladium::GetTime())); UI7::Label("Kbd test: " + kbd_test); UI7::EndMenu(); } - Palladium::R2::OnScreen(R2Screen_Bottom); + LI::OnScreen(true); if (UI7::BeginMenu("Press B to go back!")) { if (UI7::Button("FTrace")) { shared_request[0x00000001] = RFTRACE; @@ -581,11 +549,6 @@ void Palladium::RSettings::Draw(void) const { if (UI7::Button("ThemeEditor")) { Palladium::LoadThemeEditor(); } - if (UI7::Button("Logs")) { - shared_request[0x00000001] = RLOGS; - } - UI7::SameLine(); - UI7::Checkbox("No File", pdi_lggrf); if (UI7::Button("Back")) { shared_request[0x00000002] = 1U; } @@ -596,7 +559,7 @@ void Palladium::RSettings::Draw(void) const { } } else if (m_state == RIDB) { - Palladium::R2::OnScreen(R2Screen_Top); + LI::OnScreen(false); if (UI7::BeginMenu("Palladium -> Debugger")) { UI7::SetCursorPos(NVec2(395, 2)); UI7::Label(PDVSTRING, PDTextFlags_AlignRight); @@ -605,7 +568,7 @@ void Palladium::RSettings::Draw(void) const { std::string(pdi_idb_running ? "true" : "false")); UI7::EndMenu(); } - Palladium::R2::OnScreen(R2Screen_Bottom); + LI::OnScreen(true); if (UI7::BeginMenu("Press B to go back!")) { if (UI7::Button("Start Server")) { Palladium::IDB::Start(); @@ -623,45 +586,44 @@ void Palladium::RSettings::Draw(void) const { } } else if (m_state == RFTRACE) { - Palladium::R2::OnScreen(R2Screen_Top); + LI::OnScreen(false); + auto list = UI7::GetBackgroundList(); + list->Layer(10); + int lrb = list->Layer(); // Draw Top Screen Into Background DrawList - UI7::GetBackgroundList()->AddRectangle(NVec2(0, 0), NVec2(400, 240), - PDColor_Background); - UI7::GetBackgroundList()->AddRectangle(NVec2(0, 0), NVec2(400, 20), - PDColor_Header); - UI7::GetBackgroundList()->AddText( - NVec2(5, 2), "Palladium -> FTrace", - Palladium::ThemeActive()->AutoText(PDColor_Header)); - UI7::GetBackgroundList()->AddText( - NVec2(395, 2), PDVSTRING, - Palladium::ThemeActive()->AutoText(PDColor_Header), - PDTextFlags_AlignRight); - UI7::GetBackgroundList()->AddRectangle( - NVec2(0, 220), NVec2(400, 20), - Palladium::ThemeActive()->Get(PDColor_Header)); - UI7::GetBackgroundList()->AddText( - NVec2(5, 222), - "Traces: " + std::to_string(ftrace_index + 1) + "/" + - std::to_string(Palladium::Ftrace::pd_traces.size()), - Palladium::ThemeActive()->AutoText(PDColor_Header)); - UI7::GetBackgroundList()->AddRectangle(NVec2(0, 20), NVec2(400, 20), - PDColor_TextDisabled); - UI7::GetBackgroundList()->AddText( - NVec2(5, 22), - "Function:", Palladium::ThemeActive()->AutoText(PDColor_TextDisabled)); - UI7::GetBackgroundList()->AddText( - NVec2(395, 22), - "Time (ms):", Palladium::ThemeActive()->AutoText(PDColor_TextDisabled), - PDTextFlags_AlignRight); - + list->AddRectangle(NVec2(0, 0), NVec2(400, 240), PDColor_Background); + list->AddRectangle(NVec2(0, 0), NVec2(400, 20), PDColor_Header); + list->Layer(lrb + 1); + list->AddText(NVec2(5, 2), "Palladium -> FTrace", + Palladium::ThemeActive()->AutoText(PDColor_Header)); + list->AddText(NVec2(395, 2), PDVSTRING, + Palladium::ThemeActive()->AutoText(PDColor_Header), + PDTextFlags_AlignRight); + list->Layer(lrb); + list->AddRectangle(NVec2(0, 220), NVec2(400, 20), + Palladium::ThemeActive()->Get(PDColor_Header)); + list->Layer(lrb + 1); + list->AddText(NVec2(5, 222), + "Traces: " + std::to_string(ftrace_index + 1) + "/" + + std::to_string(Palladium::Ftrace::pd_traces.size()), + Palladium::ThemeActive()->AutoText(PDColor_Header)); + list->Layer(lrb); + list->AddRectangle(NVec2(0, 20), NVec2(400, 20), PDColor_TextDisabled); + list->Layer(lrb + 1); + list->AddText(NVec2(5, 22), "Function:", + Palladium::ThemeActive()->AutoText(PDColor_TextDisabled)); + list->AddText(NVec2(395, 22), "Time (ms):", + Palladium::ThemeActive()->AutoText(PDColor_TextDisabled), + PDTextFlags_AlignRight); + list->Layer(lrb); // List Bg for (int i = 0; i < 12; i++) { if ((i % 2 == 0)) - UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i)*15), - NVec2(400, 15), PDColor_List0); + list->AddRectangle(NVec2(0, 40 + (i)*15), NVec2(400, 15), + PDColor_List0); else - UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i)*15), - NVec2(400, 15), PDColor_List1); + list->AddRectangle(NVec2(0, 40 + (i)*15), NVec2(400, 15), + PDColor_List1); } Palladium::Ftrace::Beg("PDft", "display_traces"); @@ -675,27 +637,28 @@ void Palladium::RSettings::Draw(void) const { ix < start_index + 12 && it != Palladium::Ftrace::pd_traces.end()) { if (ix == ftrace_index) { _fkey__ = it->first; - UI7::GetBackgroundList()->AddRectangle( - NVec2(0, 40 + (ix - start_index) * 15), NVec2(400, 15), - PDColor_Selector); + list->Layer(lrb + 1); + list->AddRectangle(NVec2(0, 40 + (ix - start_index) * 15), + NVec2(400, 15), PDColor_Selector); } + list->Layer(lrb + 2); auto clr = ix == ftrace_index ? PDColor_Selector : (ix % 2 == 0 ? PDColor_List0 : PDColor_List1); - UI7::GetBackgroundList()->AddText( - NVec2(5, 40 + (ix - start_index) * 15), it->second.func_name, - Palladium::ThemeActive()->AutoText(clr)); - UI7::GetBackgroundList()->AddText( - NVec2(395, 40 + (ix - start_index) * 15), - Palladium::MsTimeFmt(it->second.time_of), - Palladium::ThemeActive()->AutoText(clr), PDTextFlags_AlignRight); + list->AddText(NVec2(5, 40 + (ix - start_index) * 15), + it->second.func_name, + Palladium::ThemeActive()->AutoText(clr)); + list->AddText(NVec2(395, 40 + (ix - start_index) * 15), + Palladium::MsTimeFmt(it->second.time_of), + Palladium::ThemeActive()->AutoText(clr), + PDTextFlags_AlignRight); ++it; ++ix; } Palladium::Ftrace::End("PDft", "display_traces"); - Palladium::R2::OnScreen(R2Screen_Bottom); + LI::OnScreen(true); if (UI7::BeginMenu("Press B to go back!")) { auto jt = Palladium::Ftrace::pd_traces.begin(); std::advance(jt, ftrace_index); @@ -703,38 +666,41 @@ void Palladium::RSettings::Draw(void) const { UI7::Label("Function: " + jt->second.func_name); UI7::Checkbox("In Overlay", jt->second.is_ovl); UI7::Label("Time: " + Palladium::MsTimeFmt(jt->second.time_of)); - UI7::Label("Max: " + Palladium::MsTimeFmt(jt->second.time_ofm)); UI7::Label("TS: " + std::to_string(jt->second.time_start)); UI7::Label("TE: " + std::to_string(jt->second.time_end)); UI7::Label("SVC_Stk: " + std::to_string(svcGetSystemTick())); + UI7::Label("Last 60 frames:"); + UI7::Label("Max: " + Palladium::MsTimeFmt(jt->second.ts.GetMax())); + UI7::Label("Min: " + Palladium::MsTimeFmt(jt->second.ts.GetMax())); + UI7::Label("Avg: " + Palladium::MsTimeFmt(jt->second.ts.GetMax())); UI7::EndMenu(); } } else if (m_state == RUI7) { - Palladium::R2::OnScreen(R2Screen_Top); + LI::OnScreen(false); if (UI7::BeginMenu("Palladium -> UI7")) { UI7::SetCursorPos(NVec2(395, 2)); UI7::Label(PDVSTRING, PDTextFlags_AlignRight); UI7::RestoreCursor(); UI7::Label("Time: " + std::to_string(UI7::GetTime())); - UI7::Label("Delta: " + std::to_string(UI7::GetDeltaTime() * 1000.f)); + UI7::Label("Delta: " + std::to_string(UI7::GetDeltaTime())); UI7::Label("Hid Down Touch: " + std::to_string(Hid::IsEvent("touch", Hid::Down))); UI7::Label("Hid Held Touch: " + std::to_string(Hid::IsEvent("touch", Hid::Held))); UI7::Label("Hid Up Touch: " + std::to_string(Hid::IsEvent("touch", Hid::Up))); - UI7::Label("Touch Pos: " + std::to_string(Hid::GetTouchPosition().x) + - ", " + std::to_string(Hid::GetTouchPosition().y)); + UI7::Label("Touch Pos: " + std::to_string(Hid::GetTouchPosition().x()) + + ", " + std::to_string(Hid::GetTouchPosition().y())); UI7::Label( - "Touch Last Pos: " + std::to_string(Hid::GetLastTouchPosition().x) + - ", " + std::to_string(Hid::GetLastTouchPosition().y)); + "Touch Last Pos: " + std::to_string(Hid::GetLastTouchPosition().x()) + + ", " + std::to_string(Hid::GetLastTouchPosition().y())); UI7::Label( - "Touch Down Pos: " + std::to_string(Hid::GetTouchDownPosition().x) + - ", " + std::to_string(Hid::GetTouchDownPosition().y)); + "Touch Down Pos: " + std::to_string(Hid::GetTouchDownPosition().x()) + + ", " + std::to_string(Hid::GetTouchDownPosition().y())); UI7::EndMenu(); } - Palladium::R2::OnScreen(R2Screen_Bottom); + LI::OnScreen(true); if (UI7::BeginMenu("Press B to go back!", NVec2(), UI7MenuFlags_Scrolling)) { if (UI7::Button("Go back")) { @@ -746,7 +712,7 @@ void Palladium::RSettings::Draw(void) const { UI7::EndMenu(); } } else if (m_state == ROVERLAYS) { - Palladium::R2::OnScreen(R2Screen_Top); + LI::OnScreen(false); if (UI7::BeginMenu("Palladium -> Overlays")) { UI7::SetCursorPos(NVec2(395, 2)); UI7::Label(PDVSTRING, PDTextFlags_AlignRight); @@ -756,51 +722,74 @@ void Palladium::RSettings::Draw(void) const { UI7::EndMenu(); } - Palladium::R2::OnScreen(R2Screen_Bottom); - if (UI7::BeginMenu("Press B to go back!")) { - UI7::Label("Metrik:"); - UI7::Checkbox("Enable Overlay", pdi_metrikd); - UI7::Checkbox("Bottom Screen", pdi_mt_screen); - UI7::Label("FTrace:"); - UI7::Checkbox("Enable Overlay", pdi_ftraced); - UI7::SetCursorPos(NVec2(5, 215)); + LI::OnScreen(true); + if (UI7::BeginMenu("Press B to go back!", NVec2(), + UI7MenuFlags_Scrolling)) { if (UI7::Button("Go back")) { /// Request a state switch to state RSETTINGS shared_request[0x00000001] = RSETTINGS; } - UI7::EndMenu(); - } - } else if (m_state == RLOGS) { - Palladium::R2::OnScreen(R2Screen_Top); - if (UI7::BeginMenu("Palladium -> Logs")) { - UI7::SetCursorPos(NVec2(395, 2)); - UI7::Label(PDVSTRING, PDTextFlags_AlignRight); - UI7::RestoreCursor(); - UI7::EndMenu(); - } - - Palladium::R2::OnScreen(R2Screen_Bottom); - if (UI7::BeginMenu("Press B to go back!", NVec2(), - UI7MenuFlags_Scrolling)) { - for (auto &it : pdi_logger->Lines()) UI7::Label(it, PDTextFlags_Wrap); + UI7::Separator(); + UI7::Label("FTrace:"); + UI7::Checkbox("Enable Overlay", pdi_ftraced); + UI7::Separator(); + UI7::Label("FTrace Flags:"); + auto &pd_ft_ovl = pd_ftrace_ovl_flags; + OverlayFlag(pd_ft_ovl, PDFTraceOverlayFlags_DisplayName, + "Display Func Name"); + OverlayFlag(pd_ft_ovl, PDFTraceOverlayFlags_DisplayHelp, "Display Help"); + OverlayFlag(pd_ft_ovl, PDFTraceOverlayFlags_DisplayAverage, + "Average Time"); + OverlayFlag(pd_ft_ovl, PDFTraceOverlayFlags_DisplayMin, "Minimum Time"); + OverlayFlag(pd_ft_ovl, PDFTraceOverlayFlags_DisplayMax, "Maximum Time"); + OverlayFlag(pd_ft_ovl, PDFTraceOverlayFlags_FillBg, "Darker Background"); + UI7::Separator(); + UI7::Label("Metrik"); + UI7::Label("Format: Usage | Current Time -> Average"); + UI7::Checkbox("Enable Overlay", pdi_metrikd); + UI7::Checkbox("Bottom Screen", pdi_mt_screen); + UI7::ColorSelector("Text", pdi_mt_txtcolor); + UI7::ColorSelector("Text Background", pdi_mt_color); + UI7::Label("TextSize: " + std::to_string(pdi_mt_txtSize)); + UI7::SameLine(); + if (UI7::Button("+")) { + pdi_mt_txtSize += 0.1; + } + UI7::SameLine(); + if (UI7::Button("-")) { + pdi_mt_txtSize -= 0.1; + } + UI7::Separator(); + UI7::Label("Metrik Flags:"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_FPS, + "Application average"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_CPU, "CPU Usage"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_GPU, "GPU Usage"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_CMD, "Command Buf Usage"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_LMM, "Linear Space Free"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_LVT, "LI Vertices"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_LID, "LI Indices"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_LDM, "LI Draw Commands"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_LDC, "LI Draw Calls"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_PDO, "Display Info Line"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_MTD, "MemTrack Info"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_CGR, "Display CPU Graph"); + OverlayFlag(pd_ovl_flags, PDMetrikOverlayFlags_GGR, "Display GPU Graph"); UI7::EndMenu(); } } else if (m_state == RFV) { - Palladium::R2::OnScreen(R2Screen_Top); + LI::OnScreen(false); if (UI7::BeginMenu("Palladium -> Font Viewer")) { UI7::SetCursorPos(NVec2(395, 2)); UI7::Label(PDVSTRING, PDTextFlags_AlignRight); UI7::RestoreCursor(); - UI7::Label("Font: "+LI7::GetFont()->GetName()); + UI7::Label("Font: " + LI::GetFont()->GetName()); UI7::EndMenu(); } - Palladium::R2::OnScreen(R2Screen_Bottom); + LI::OnScreen(true); if (UI7::BeginMenu("Press B to go back!", NVec2(), UI7MenuFlags_Scrolling)) { - for(int i = 0; i < 255; i++) { - DisplayCodepoint(i); - } UI7::EndMenu(); } } @@ -816,7 +805,10 @@ void Palladium::RSettings::Logic() { std::fstream cfg_wrt(pdi_config_path + "/config.rc7", std::ios::out); pdi_config["metrik-settings"]["show"] = pdi_metrikd; pdi_config["metrik-settings"]["Screen"] = pdi_mt_screen; - pdi_config["internal_logger"]["nowritetxt"] = pdi_lggrf; + pdi_config["metrik-settings"]["config"] = pd_ovl_flags; + pdi_config["metrik-settings"]["Text"] = pdi_mt_txtcolor; + pdi_config["metrik-settings"]["Size"] = pdi_mt_txtSize; + pdi_config["metrik-settings"]["Bg"] = pdi_mt_color; cfg_wrt << pdi_config.dump(4); cfg_wrt.close(); pdi_settings = false; @@ -847,7 +839,10 @@ void Palladium::RSettings::Logic() { std::fstream cfg_wrt(pdi_config_path + "/config.rc7", std::ios::out); pdi_config["metrik-settings"]["show"] = pdi_metrikd; pdi_config["metrik-settings"]["Screen"] = pdi_mt_screen; - pdi_config["internal_logger"]["nowritetxt"] = pdi_lggrf; + pdi_config["metrik-settings"]["config"] = pd_ovl_flags; + pdi_config["metrik-settings"]["Text"] = pdi_mt_txtcolor; + pdi_config["metrik-settings"]["Size"] = pdi_mt_txtSize; + pdi_config["metrik-settings"]["Bg"] = pdi_mt_color; cfg_wrt << pdi_config.dump(4); cfg_wrt.close(); pdi_settings = false; @@ -867,11 +862,6 @@ void Palladium::RSettings::Logic() { m_state = RSETTINGS; } } - if (m_state == RIDB || m_state == RLOGS) { - if (d7_hUp & KEY_B) { - m_state = RSETTINGS; - } - } if (m_state == RFTRACE) { if (d7_hDown & KEY_DOWN) { if (ftrace_index < (int)Palladium::Ftrace::pd_traces.size() - 1)