- 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:
2024-08-30 14:54:49 +02:00
parent a58dc20562
commit 224daffaf7
54 changed files with 3723 additions and 3107 deletions

View File

@ -0,0 +1,40 @@
#pragma once
#include <3ds.h>
#include <memory>
#include <pd/Error.hpp>
// Write own LinearAllocator for learning
namespace Palladium {
template <typename T>
class LinearAllocator : public std::allocator<T> {
public:
typedef size_t size_type;
typedef T* pointer;
typedef const T* const_pointer;
template <typename T1>
struct rebind {
typedef LinearAllocator<T1> other;
};
pointer allocate(size_type n, const void* hint = nullptr) {
if (n > this->max_size()) {
Palladium::Error(
"Linear Allocator: \nBad Alloc -> size is larger than free space!");
return nullptr;
}
return (pointer)linearAlloc(n * sizeof(T));
}
void deallocate(pointer p, size_type) { linearFree((void*)p); }
size_type max_size() { return linearSpaceFree(); }
LinearAllocator() throw() {}
LinearAllocator(const LinearAllocator<T>& a) throw() : std::allocator<T>(a) {}
~LinearAllocator() throw() {}
};
} // namespace Palladium

204
include/pd/base/Color.hpp Normal file
View File

@ -0,0 +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

View File

@ -0,0 +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
} // namespace Palladium

View File

@ -0,0 +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 {
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

24
include/pd/base/Lang.hpp Normal file
View File

@ -0,0 +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

View File

@ -0,0 +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

View File

@ -0,0 +1,98 @@
#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();
}