Changes:
- Start Restructuring Project - Add Makefile for Testbuilds - Optimize Lithium as much as possible - Remove Render2 to get wasted time - Optimize UI7 for LRS
This commit is contained in:
parent
a58dc20562
commit
224daffaf7
@ -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
|
||||
|
152
Makefile
Normal file
152
Makefile
Normal file
@ -0,0 +1,152 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>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
|
||||
#---------------------------------------------------------------------------------------
|
@ -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"
|
||||
- "include/pd/base/*.h"
|
@ -1,25 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/Allocator.hpp>
|
||||
#include <pd/base/Allocator.hpp>
|
||||
#include <pd/Error.hpp>
|
||||
#include <pd/FileSystem.hpp>
|
||||
#include <pd/base/FileSystem.hpp>
|
||||
#include <pd/Hid.hpp>
|
||||
#include <pd/Image.hpp>
|
||||
#include <pd/Installer.hpp>
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/Lithium.hpp>
|
||||
#include <pd/Message.hpp>
|
||||
#include <pd/Net.hpp>
|
||||
#include <pd/Overlays.hpp>
|
||||
#include <pd/Rubidium.hpp>
|
||||
#include <pd/Sound.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/Sheet.hpp>
|
||||
#include <pd/Timer.hpp>
|
||||
#include <pd/UI7.hpp>
|
||||
#include <pd/global_db.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
|
||||
namespace Palladium {
|
||||
using Render2 = R2;
|
||||
using Lithium = LI;
|
||||
using RB = Rubidium;
|
||||
} // namespace Palladium
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <citro2d.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <pd/Error.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
|
||||
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
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/maths/NVec.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace Palladium {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/maths/NVec.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/nimg.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
@ -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();
|
||||
|
||||
|
@ -1,166 +0,0 @@
|
||||
#pragma once
|
||||
#include <citro3d.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pd/Allocator.hpp>
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
#include <vector>
|
||||
|
||||
#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<CPI> cpmap;
|
||||
std::vector<Texture::Ref> 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<Cmd> m_top_draw_cmds;
|
||||
static std::vector<Cmd> m_bot_draw_cmds;
|
||||
static Texture::Ref m_current_texture;
|
||||
static Texture::Ref m_white;
|
||||
static std::vector<Vtx, LinearAllocator<Vtx>> m_vtx_list[2];
|
||||
// static Font* m_font;
|
||||
static LIFont::Ref m_font;
|
||||
static std::vector<char> 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
|
236
include/pd/Lithium.hpp
Normal file
236
include/pd/Lithium.hpp
Normal file
@ -0,0 +1,236 @@
|
||||
#pragma once
|
||||
#include <citro3d.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <map>
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/base/Allocator.hpp>
|
||||
#include <pd/maths/NVec.hpp>
|
||||
#include <vector>
|
||||
|
||||
#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<unsigned int, CPI> cpmap;
|
||||
std::vector<Texture::Ref> 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<Cmd> draw_lists[2];
|
||||
static Texture::Ref active_texture;
|
||||
static Texture::Ref single_color;
|
||||
static std::vector<Vtx, LinearAllocator<Vtx>> vertex_buffer;
|
||||
static std::vector<unsigned short, LinearAllocator<unsigned short>>
|
||||
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<std::string, TextBox> 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
|
@ -1,35 +0,0 @@
|
||||
#pragma once
|
||||
#include <fstream>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<std::string>& 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<std::string> lines;
|
||||
};
|
||||
} // namespace Palladium
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/Ovl.hpp>
|
||||
#include <pd/Timer.hpp>
|
||||
#include <pd/base/FunctionTrace.hpp>
|
||||
#include <pd/maths/NVec.hpp>
|
||||
#include <string>
|
||||
|
||||
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
|
@ -1,83 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/Font.hpp>
|
||||
#include <pd/Image.hpp>
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/Sprite.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
|
||||
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<std::string, float> ts;
|
||||
static std::map<std::string, int> mln;
|
||||
static bool next_lined;
|
||||
static std::vector<R2Cmd::Ref> commands;
|
||||
static R2Screen current_screen;
|
||||
};
|
||||
} // namespace Palladium
|
@ -1,35 +1,24 @@
|
||||
#pragma once
|
||||
#include <3ds.h> // Result
|
||||
#include <citro2d.h>
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <pd/Image.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <string>
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/Image.hpp>
|
||||
|
||||
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 <tex3ds.h>
|
||||
|
||||
private:
|
||||
/// \param spritesheet The Sheet
|
||||
C2D_SpriteSheet spritesheet;
|
||||
};
|
||||
} // namespace Palladium
|
||||
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<Texture::Ref> sprites;
|
||||
Tex3DS_Texture sheet;
|
||||
C3D_Tex* sheet_tex = nullptr;
|
||||
};
|
||||
} // namespace Palladium
|
||||
|
@ -1,10 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <citro2d.h>
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <pd/Image.hpp>
|
||||
#include <pd/Sheet.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
|
||||
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
|
@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <citro2d.h>
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <pd/Sheet.hpp>
|
||||
#include <pd/Sprite.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
|
||||
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
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/maths/NVec.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -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)
|
||||
|
@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/Image.hpp>
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/Render2.hpp>
|
||||
#include <pd/Lithium.hpp>
|
||||
#include <pd/base/Color.hpp>
|
||||
#include <pd/maths/NVec.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
|
||||
#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<DrawCmd> cmd);
|
||||
std::vector<std::shared_ptr<DrawCmd>> 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);
|
||||
|
@ -1,204 +1,204 @@
|
||||
#pragma once
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<unsigned int> &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<unsigned int> clr_tab;
|
||||
std::vector<change> 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<unsigned char>((color.m_a - m_a) * ((p + 1.0f) / 2));
|
||||
m_b =
|
||||
m_b + static_cast<unsigned char>((color.m_b - m_b) * ((p + 1.0f) / 2));
|
||||
m_g =
|
||||
m_g + static_cast<unsigned char>((color.m_g - m_g) * ((p + 1.0f) / 2));
|
||||
m_r =
|
||||
m_r + static_cast<unsigned char>((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 <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<unsigned int> &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<unsigned int> clr_tab;
|
||||
std::vector<change> 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<unsigned char>((color.m_a - m_a) * ((p + 1.0f) / 2));
|
||||
m_b =
|
||||
m_b + static_cast<unsigned char>((color.m_b - m_b) * ((p + 1.0f) / 2));
|
||||
m_g =
|
||||
m_g + static_cast<unsigned char>((color.m_g - m_g) * ((p + 1.0f) / 2));
|
||||
m_r =
|
||||
m_r + static_cast<unsigned char>((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
|
@ -1,24 +1,24 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<Palladium::FileSystem::Entry> GetDirContent(std::string path);
|
||||
std::string GetParentPath(std::string path, std::string mount_point);
|
||||
std::vector<Entry> GetDirContentsExt(
|
||||
std::string &path, const std::vector<std::string> &extensions);
|
||||
} // namespace FileSystem
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<Palladium::FileSystem::Entry> GetDirContent(std::string path);
|
||||
std::string GetParentPath(std::string path, std::string mount_point);
|
||||
std::vector<Entry> GetDirContentsExt(
|
||||
std::string &path, const std::vector<std::string> &extensions);
|
||||
} // namespace FileSystem
|
||||
} // namespace Palladium
|
@ -1,76 +1,137 @@
|
||||
#pragma once
|
||||
// Base includes
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// 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<std::string, Palladium::Ftrace::FTRes> 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<float>(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<void()> 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 <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
// 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<float>& 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<float> 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<std::string, Palladium::Ftrace::FTRes> 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<float>(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<void()> 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
|
@ -1,24 +1,24 @@
|
||||
#pragma once
|
||||
// clang-format off
|
||||
#include <string>
|
||||
#include <pd/external/json.hpp>
|
||||
// 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 <string>
|
||||
#include <pd/external/json.hpp>
|
||||
// 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
|
@ -1,26 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
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 <cstddef>
|
||||
|
||||
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
|
@ -1,103 +1,98 @@
|
||||
#pragma once
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
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<std::string> &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<int>(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<int>(t_time / 60000.0f);
|
||||
int seconds = static_cast<int>((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 <class T>
|
||||
T GetFileName(T const &path, T const &delims = "/\\") {
|
||||
return path.substr(path.find_last_of(delims) + 1);
|
||||
}
|
||||
template <class T>
|
||||
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 <typename T>
|
||||
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 <format>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
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<std::string> &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<int>(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<int>(t_time / 60000.0f);
|
||||
int seconds = static_cast<int>((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 <class T>
|
||||
T GetFileName(T const &path, T const &delims = "/\\") {
|
||||
return path.substr(path.find_last_of(delims) + 1);
|
||||
}
|
||||
template <class T>
|
||||
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 <typename T>
|
||||
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();
|
||||
}
|
@ -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;
|
@ -4,7 +4,7 @@
|
||||
#include <pd/global_db.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
|
||||
#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<Palladium::Scene> pdi_fade_scene;
|
||||
@ -36,8 +33,8 @@ extern std::vector<std::unique_ptr<Palladium::Ovl>> 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();
|
45
include/pd/maths/NMat.hpp
Normal file
45
include/pd/maths/NMat.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/maths/NVec.hpp>
|
||||
|
||||
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];
|
||||
};
|
||||
};
|
366
include/pd/maths/NVec.hpp
Normal file
366
include/pd/maths/NVec.hpp
Normal file
@ -0,0 +1,366 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
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];
|
||||
};
|
@ -13,26 +13,21 @@
|
||||
#include <unistd.h>
|
||||
/// 3ds Includes
|
||||
#include <3ds.h>
|
||||
#include <citro2d.h>
|
||||
#include <citro3d.h>
|
||||
/// Palladium Includes
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/FunctionTrace.hpp>
|
||||
#include <pd/base/Color.hpp>
|
||||
#include <pd/base/FunctionTrace.hpp>
|
||||
#include <pd/Hardware.hpp>
|
||||
#include <pd/Logger.hpp>
|
||||
#include <pd/Memory.hpp>
|
||||
#include <pd/base/Memory.hpp>
|
||||
#include <pd/Overlays.hpp>
|
||||
#include <pd/Ovl.hpp>
|
||||
#include <pd/Render2.hpp>
|
||||
#include <pd/ResultDecoder.hpp>
|
||||
#include <pd/Sheet.hpp>
|
||||
#include <pd/Sprite.hpp>
|
||||
#include <pd/SpriteAnimation.hpp>
|
||||
#include <pd/Tasks.hpp>
|
||||
#include <pd/Time.hpp>
|
||||
#include <pd/lang.hpp>
|
||||
#include <pd/base/Lang.hpp>
|
||||
#include <pd/parameter.hpp>
|
||||
#include <pd/stringtool.hpp>
|
||||
#include <pd/base/stringtool.hpp>
|
||||
#include <pd/thread.hpp>
|
||||
|
||||
#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();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <pd/UI7.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
#include <fstream>
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
489
source/LI7.cpp
489
source/LI7.cpp
@ -1,489 +0,0 @@
|
||||
#include <pd/external/stb_truetype.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/li7_shader.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
|
||||
#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::Cmd> LI7::m_top_draw_cmds;
|
||||
std::vector<LI7::Cmd> LI7::m_bot_draw_cmds;
|
||||
Texture::Ref LI7::m_current_texture;
|
||||
Texture::Ref LI7::m_white;
|
||||
std::vector<LI7::Vtx, LinearAllocator<LI7::Vtx>> LI7::m_vtx_list[2];
|
||||
// LI7::Font *LI7::m_font;
|
||||
LIFont::Ref LI7::m_font;
|
||||
std::vector<char> 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<char*>(buffer), len);
|
||||
loader.close();
|
||||
stbtt_InitFont(&inf, buffer, 0);
|
||||
std::vector<unsigned char> 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<int>(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>((float)offset.x / (float)type);
|
||||
codepoint.uv.y = 1.0f - static_cast<float>((float)offset.y / (float)type);
|
||||
codepoint.uv.z =
|
||||
static_cast<float>(float(offset.x + width) / (float)type);
|
||||
codepoint.uv.w =
|
||||
1.0f - static_cast<float>(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<unsigned char> 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<std::string> 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
|
767
source/Lithium.cpp
Normal file
767
source/Lithium.cpp
Normal file
@ -0,0 +1,767 @@
|
||||
#include <pd/external/stb_truetype.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <codecvt>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <pd/Lithium.hpp>
|
||||
#include <pd/base/Color.hpp>
|
||||
#include <pd/li7_shader.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
std::wstring make_wstring(const std::string& str) {
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, 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::Cmd> LI::draw_lists[2];
|
||||
Texture::Ref LI::active_texture;
|
||||
Texture::Ref LI::single_color;
|
||||
std::vector<LI::Vtx, LinearAllocator<LI::Vtx>> LI::vertex_buffer;
|
||||
std::vector<unsigned short, LinearAllocator<unsigned short>> 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<std::string, LI::TextBox> 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<char*>(buffer), len);
|
||||
loader.close();
|
||||
stbtt_InitFont(&inf, buffer, 0);
|
||||
std::vector<unsigned char> 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<int>(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>((float)offset[0] / (float)type);
|
||||
codepoint.uv[1] = 1.0f - static_cast<float>((float)offset[1] / (float)type);
|
||||
codepoint.uv[2] =
|
||||
static_cast<float>(float(offset[0] + width) / (float)type);
|
||||
codepoint.uv[3] =
|
||||
1.0f - static_cast<float>(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<unsigned int> 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<unsigned char> 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<std::string> 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<std::string> 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
|
@ -1,44 +0,0 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <pd/Logger.hpp>
|
||||
#include <pd/Time.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
|
||||
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<std::string>& LoggerBase::Lines() { return this->lines; }
|
||||
} // namespace Palladium
|
@ -1,8 +1,9 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/base/Color.hpp>
|
||||
#include <pd/Message.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
#include <pd/Lithium.hpp>
|
||||
#include <vector>
|
||||
|
||||
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<int>(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<int>(-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) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <pd/FunctionTrace.hpp>
|
||||
#include <format>
|
||||
#include <pd/Hid.hpp>
|
||||
#include <pd/Lithium.hpp>
|
||||
#include <pd/Overlays.hpp>
|
||||
#include <pd/base/FunctionTrace.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
|
||||
@ -257,8 +259,9 @@ std::vector<Key> 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<Palladium::Ftrace::FTRes> 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<float>(size.x() / s.GetLen());
|
||||
float ys = static_cast<float>(size.y() / (range.y() - range.x()));
|
||||
|
||||
std::vector<NVec2> 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() {
|
||||
|
@ -1,325 +0,0 @@
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/Render2.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
namespace Palladium {
|
||||
const float R2::default_text_size = 0.5f;
|
||||
float R2::text_size = 0.5;
|
||||
Font::Ref R2::font;
|
||||
std::map<std::string, float> R2::ts;
|
||||
std::map<std::string, int> R2::mln;
|
||||
bool R2::next_lined = false;
|
||||
std::vector<R2::R2Cmd::Ref> 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
|
@ -1,6 +1,6 @@
|
||||
#include <pd/external/stb_image.h>
|
||||
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/base/Color.hpp>
|
||||
#include <pd/Rubidium.hpp>
|
||||
|
||||
void d7_pixel_blend(Palladium::Rubidium* rb, int x, int y, unsigned int clr,
|
||||
|
@ -1,22 +1,51 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <pd/Sheet.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
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<unsigned char> dat(f.tellg());
|
||||
f.seekg(0, std::ios::beg);
|
||||
f.read(reinterpret_cast<char*>(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);
|
||||
}
|
||||
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
|
@ -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;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <pd/Sprite.hpp>
|
||||
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}*/
|
@ -1,29 +0,0 @@
|
||||
#include <pd/SpriteAnimation.hpp>
|
||||
|
||||
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();
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
#include <pd/Error.hpp>
|
||||
|
||||
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<unsigned char> &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<unsigned char> &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<unsigned char> &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<unsigned char> &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
|
@ -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")) {
|
||||
|
866
source/UI7.cpp
866
source/UI7.cpp
File diff suppressed because it is too large
Load Diff
@ -1,229 +1,229 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/Message.hpp>
|
||||
#include <pd/external/json.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
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<char, int> 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<PDColor, unsigned int> 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<std::string>());
|
||||
this->clr_tab[PDColor_Text2] = pdi_special_color_hex(js["PDColor_Text2"].get<std::string>());
|
||||
this->clr_tab[PDColor_TextDisabled] = pdi_special_color_hex(js["PDColor_TextDisabled"].get<std::string>());
|
||||
this->clr_tab[PDColor_Background] = pdi_special_color_hex(js["PDColor_Background"].get<std::string>());
|
||||
this->clr_tab[PDColor_Header] = pdi_special_color_hex(js["PDColor_Header"].get<std::string>());
|
||||
this->clr_tab[PDColor_Selector] = pdi_special_color_hex(js["PDColor_Selector"].get<std::string>());
|
||||
this->clr_tab[PDColor_SelectorFade] = pdi_special_color_hex(js["PDColor_SelectorFade"].get<std::string>());
|
||||
this->clr_tab[PDColor_List0] = pdi_special_color_hex(js["PDColor_List0"].get<std::string>());
|
||||
this->clr_tab[PDColor_List1] = pdi_special_color_hex(js["PDColor_List1"].get<std::string>());
|
||||
this->clr_tab[PDColor_MessageBackground] = pdi_special_color_hex(js["PDColor_MessageBackground"].get<std::string>());
|
||||
this->clr_tab[PDColor_Button] = pdi_special_color_hex(js["PDColor_Button"].get<std::string>());
|
||||
this->clr_tab[PDColor_ButtonHovered] = pdi_special_color_hex(js["PDColor_ButtonHovered"].get<std::string>());
|
||||
this->clr_tab[PDColor_ButtonDisabled] = pdi_special_color_hex(js["PDColor_ButtonDisabled"].get<std::string>());
|
||||
this->clr_tab[PDColor_ButtonActive] = pdi_special_color_hex(js["PDColor_ButtonActive"].get<std::string>());
|
||||
this->clr_tab[PDColor_Checkmark] = pdi_special_color_hex(js["PDColor_Checkmark"].get<std::string>());
|
||||
this->clr_tab[PDColor_FrameBg] = pdi_special_color_hex(js["PDColor_FrameBg"].get<std::string>());
|
||||
this->clr_tab[PDColor_FrameBgHovered] = pdi_special_color_hex(js["PDColor_FrameBgHovered"].get<std::string>());
|
||||
this->clr_tab[PDColor_Progressbar] = pdi_special_color_hex(js["PDColor_Progressbar"].get<std::string>());
|
||||
// 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 <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <pd/base/Color.hpp>
|
||||
#include <pd/Message.hpp>
|
||||
#include <pd/external/json.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
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<char, int> 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<PDColor, unsigned int> 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<std::string>());
|
||||
this->clr_tab[PDColor_Text2] = pdi_special_color_hex(js["PDColor_Text2"].get<std::string>());
|
||||
this->clr_tab[PDColor_TextDisabled] = pdi_special_color_hex(js["PDColor_TextDisabled"].get<std::string>());
|
||||
this->clr_tab[PDColor_Background] = pdi_special_color_hex(js["PDColor_Background"].get<std::string>());
|
||||
this->clr_tab[PDColor_Header] = pdi_special_color_hex(js["PDColor_Header"].get<std::string>());
|
||||
this->clr_tab[PDColor_Selector] = pdi_special_color_hex(js["PDColor_Selector"].get<std::string>());
|
||||
this->clr_tab[PDColor_SelectorFade] = pdi_special_color_hex(js["PDColor_SelectorFade"].get<std::string>());
|
||||
this->clr_tab[PDColor_List0] = pdi_special_color_hex(js["PDColor_List0"].get<std::string>());
|
||||
this->clr_tab[PDColor_List1] = pdi_special_color_hex(js["PDColor_List1"].get<std::string>());
|
||||
this->clr_tab[PDColor_MessageBackground] = pdi_special_color_hex(js["PDColor_MessageBackground"].get<std::string>());
|
||||
this->clr_tab[PDColor_Button] = pdi_special_color_hex(js["PDColor_Button"].get<std::string>());
|
||||
this->clr_tab[PDColor_ButtonHovered] = pdi_special_color_hex(js["PDColor_ButtonHovered"].get<std::string>());
|
||||
this->clr_tab[PDColor_ButtonDisabled] = pdi_special_color_hex(js["PDColor_ButtonDisabled"].get<std::string>());
|
||||
this->clr_tab[PDColor_ButtonActive] = pdi_special_color_hex(js["PDColor_ButtonActive"].get<std::string>());
|
||||
this->clr_tab[PDColor_Checkmark] = pdi_special_color_hex(js["PDColor_Checkmark"].get<std::string>());
|
||||
this->clr_tab[PDColor_FrameBg] = pdi_special_color_hex(js["PDColor_FrameBg"].get<std::string>());
|
||||
this->clr_tab[PDColor_FrameBgHovered] = pdi_special_color_hex(js["PDColor_FrameBgHovered"].get<std::string>());
|
||||
this->clr_tab[PDColor_Progressbar] = pdi_special_color_hex(js["PDColor_Progressbar"].get<std::string>());
|
||||
// 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();
|
||||
}
|
@ -1,70 +1,70 @@
|
||||
#include <3ds.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <pd/FileSystem.hpp>
|
||||
// Debugging
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <pd/stringtool.hpp>
|
||||
|
||||
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::Entry> Palladium::FileSystem::GetDirContent(
|
||||
std::string path) {
|
||||
std::vector<Palladium::FileSystem::Entry> 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::Entry>
|
||||
Palladium::FileSystem::GetDirContentsExt(
|
||||
std::string &path, const std::vector<std::string> &extensions) {
|
||||
std::vector<Palladium::FileSystem::Entry> 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <pd/base/FileSystem.hpp>
|
||||
// Debugging
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <pd/base/stringtool.hpp>
|
||||
|
||||
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::Entry> Palladium::FileSystem::GetDirContent(
|
||||
std::string path) {
|
||||
std::vector<Palladium::FileSystem::Entry> 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::Entry>
|
||||
Palladium::FileSystem::GetDirContentsExt(
|
||||
std::string &path, const std::vector<std::string> &extensions) {
|
||||
std::vector<Palladium::FileSystem::Entry> 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;
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
#include <pd/FunctionTrace.hpp>
|
||||
|
||||
#include <pd/base/FunctionTrace.hpp>
|
||||
|
||||
std::map<std::string, Palladium::Ftrace::FTRes> Palladium::Ftrace::pd_traces;
|
@ -1,118 +1,118 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <pd/lang.hpp>
|
||||
|
||||
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<std::string>();
|
||||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
|
||||
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<std::string>();
|
||||
#include <3ds.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <pd/base/Lang.hpp>
|
||||
|
||||
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<std::string>();
|
||||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
|
||||
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<std::string>();
|
||||
}
|
@ -1,56 +1,55 @@
|
||||
#include <cstdlib>
|
||||
#include <map>
|
||||
#include <pd/Memory.hpp>
|
||||
|
||||
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<void *, size_t> 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 <cstdlib>
|
||||
#include <map>
|
||||
#include <pd/base/Memory.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
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<void *, size_t> 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
|
@ -7,7 +7,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <pd/Error.hpp>
|
||||
#include <pd/FileSystem.hpp>
|
||||
#include <pd/base/FileSystem.hpp>
|
||||
#include <pd/external/json.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
@ -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<std::unique_ptr<Palladium::Scene>> Palladium::Scene::scenes;
|
||||
@ -34,15 +31,15 @@ std::vector<std::unique_ptr<Palladium::Ovl>> 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);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <pd/Hid.hpp> // Integate HidApi
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/Lithium.hpp>
|
||||
#include <pd/Message.hpp>
|
||||
#include <pd/Overlays.hpp>
|
||||
#include <pd/ThemeEditor.hpp>
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
// C++ includes
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <random>
|
||||
|
||||
#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<bool>();
|
||||
pdi_mt_txtSize = pdi_config["metrik-settings"]["Size"].get<float>();
|
||||
pdi_mt_screen = pdi_config["metrik-settings"]["Screen"].get<bool>();
|
||||
pdi_lggrf = pdi_config["internal_logger"]["nowritetxt"].get<bool>();
|
||||
pdi_mt_txtcolor = pdi_config["metrik-settings"]["Text"].get<unsigned int>();
|
||||
pdi_mt_color = pdi_config["metrik-settings"]["Bg"].get<unsigned int>();
|
||||
pd_ovl_flags = pdi_config["metrik-settings"]["config"].get<int>();
|
||||
|
||||
if (pdi_metrikd)
|
||||
Palladium::AddOvl(std::make_unique<Palladium::Ovl_Metrik>(
|
||||
@ -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<float>(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<std::string> StrHelper(std::string input) {
|
||||
std::string ss(input);
|
||||
@ -536,16 +510,9 @@ std::vector<std::string> 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)
|
||||
|
Loading…
Reference in New Issue
Block a user