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:
229
source/base/Color.cpp
Normal file
229
source/base/Color.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
#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();
|
||||
}
|
70
source/base/FileSystem.cpp
Normal file
70
source/base/FileSystem.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#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;
|
||||
}
|
3
source/base/FunctionTrace.cpp
Normal file
3
source/base/FunctionTrace.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include <pd/base/FunctionTrace.hpp>
|
||||
|
||||
std::map<std::string, Palladium::Ftrace::FTRes> Palladium::Ftrace::pd_traces;
|
118
source/base/Lang.cpp
Normal file
118
source/base/Lang.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#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>();
|
||||
}
|
55
source/base/Memory.cpp
Normal file
55
source/base/Memory.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#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
|
Reference in New Issue
Block a user