# Changes -> 0.5.1

- 3ds
  - Remove Gfx values that are present in Backend Tamplate
  - Move to default Palladium Namespace
  - Set the Input Flags
- Desktop
  - Move to PD Namespace
  - Comment out old keyboard stuff
  - HidDriver needs a rewrite but is functional enough
- Core
  - Add u128 class (only used in input driver so far
- Drivers (Core)
  - Move Gfx to PD namespace
  - Move Vertex/Index Pos and Projection Mtx to Gfx template
  - Add Keyboard support with u128 to Hid
  - Add a Update func if no hiddriver is specified (to prevent crashes when requestign inputs)
- Image
   - Add RGBA -> BGRA support (used in windows bitmaps iirc)
- Lithium
  - Add Vertex/Index counters to drawlist
  - Add a LoadTTF from Mem func and let the loadfile func use PD::IO::LoadFile2Mem (looks cleaner)
  - Add LoadDefaultFont (which loads one of the integrated fonts if the PD_LI_INCLUDE_FONTS flag was passed on palaldium build) !!! Note that there are no fonts integrated yet due to i dont know how to handle licensing...
- UI7
  - Add MouseLeft support to Input handler
  - Use xy coords of the Viewport to create Menus inside it
  - Get num of Vertices/Indices out of FinalDrawList
  - Add some Palladium Info to metrics Menu
  - Readd Compiler string
- pdfm
  - New tool that creates fonts.cpp/fonts.hpp
This commit is contained in:
2025-08-14 20:37:55 +02:00
parent 87910b57de
commit 310b44caf5
38 changed files with 644 additions and 166 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.22)
# Set Project
project(palladium LANGUAGES C CXX VERSION 0.5.0)
project(palladium LANGUAGES C CXX VERSION 0.5.1)
# Required to add this Variable
set(PD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

View File

@ -40,8 +40,6 @@ class LinearAlloc : public Allocator<T> {
T* Allocate(size_t n) override { return (T*)linearAlloc(n * sizeof(T)); }
void Deallocate(T* ptr) { linearFree(ptr); }
};
namespace Li {
class GfxC3D : public GfxDriver {
public:
GfxC3D() : GfxDriver("Citro3D") {}
@ -63,16 +61,9 @@ class GfxC3D : public GfxDriver {
Vec<Vertex, LinearAlloc<Vertex>> VertexBuffer;
Vec<u16, LinearAlloc<u16>> IndexBuffer;
size_t CurrentVertex = 0;
size_t CurrentIndex = 0;
Mat4 Projection;
int pLocProjection = 0;
DVLB_s* ShaderCode;
shaderProgram_s Shader;
C3D_AttrInfo ShaderInfo;
// Stats oder so IDNK zu lange her
PD::u32 NumVtx;
PD::u32 NumIdx;
};
} // namespace Li
} // namespace PD

View File

@ -25,6 +25,9 @@ SOFTWARE.
#include <pd-3ds/bknd-gfx.hpp>
/// @brief Shader Code (Unused as i dont want to use libpicasso here (yet))
/// Update: Picasso breaks the linearRam or ram for somereason
/// as far as i found out loading anything into linear ram after
/// using libpicasso to compile a shader leads into a system freeze
const char* LIShaderCTR = R"(
; LI7 Shader
; Constants
@ -70,7 +73,6 @@ unsigned char li_shader[] = {
size_t li_shader_size = 0x124;
namespace PD {
namespace Li {
GPU_TEXCOLOR GetTexFmt(Texture::Type type) {
if (type == Texture::RGBA32)
return GPU_RGBA8;
@ -249,5 +251,4 @@ PD::Li::Texture::Ref GfxC3D::LoadTex(const std::vector<PD::u8>& pixels, int w,
<< std::endl;
return res;
}
} // namespace Li
} // namespace PD

View File

@ -28,6 +28,8 @@ SOFTWARE.
namespace PD {
Hid3DS::Hid3DS() : HidDriver("Hid3DS") {
this->Flags |= Flags_HasTouch;
this->Flags |= FLags_HasGamepad;
pBinds[KEY_A] = A;
pBinds[KEY_B] = B;
pBinds[KEY_X] = X;

View File

@ -30,7 +30,7 @@ void Init(void* data) {
// Dekstop Init Stage
// First use default OS Driver
PD::OS::Init();
PD::Li::Gfx::Init(PD::Li::GfxC3D::New());
PD::Gfx::Init(PD::GfxC3D::New());
PD::Hid::Init(PD::Hid3DS::New());
}
} // namespace PD

View File

@ -33,7 +33,6 @@ SOFTWARE.
#include <pd/lithium/lithium.hpp>
namespace PD {
namespace Li {
class GfxGL2 : public GfxDriver {
public:
GfxGL2() : GfxDriver("OpenGL2") {}
@ -53,18 +52,11 @@ class GfxGL2 : public GfxDriver {
PD::Li::Texture::Filter filter =
PD::Li::Texture::Filter::LINEAR) override;
PD::Vec<Vertex> VertexBuffer;
PD::Vec<Li::Vertex> VertexBuffer;
PD::Vec<PD::u16> IndexBuffer;
size_t CurrentVertex = 0;
size_t CurrentIndex = 0;
GLuint Shader;
GLuint pLocProjection;
GLuint pLocTex;
Mat4 Projection;
GLuint VBO, IBO;
// Stats oder so IDNK zu lange her
PD::u32 NumVtx;
PD::u32 NumIdx;
};
} // namespace Li
} // namespace PD

View File

@ -25,7 +25,6 @@ SOFTWARE.
#include <pd-desktop/bknd-gfx.hpp>
namespace PD {
namespace Li {
const char* vertex_shader = R"(
#version 120
@ -161,13 +160,11 @@ void GfxGL2::NewFrame() {
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
CurrentIndex = 0;
CurrentVertex = 0;
FrameCounter++;
VertexCounter = NumVtx;
IndexCounter = NumIdx;
NumVtx = 0;
NumIdx = 0;
VertexCounter = CurrentVertex;
IndexCounter = CurrentIndex;
CurrentVertex = 0;
CurrentIndex = 0;
}
void GfxGL2::BindTex(PD::Li::TexAddress addr) {
@ -194,11 +191,9 @@ void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
Commands[index]->ScissorRect == ScissorRect) {
auto c = Commands[index].get();
for (size_t i = 0; i < c->IndexBuffer.Size(); i++) {
NumIdx++;
IndexBuffer[CurrentIndex++] = CurrentVertex + c->IndexBuffer.At(i);
}
for (size_t i = 0; i < c->VertexBuffer.Size(); i++) {
NumVtx++;
VertexBuffer[CurrentVertex++] = c->VertexBuffer.At(i);
}
index++;
@ -258,5 +253,4 @@ PD::Li::Texture::Ref GfxGL2::LoadTex(const std::vector<PD::u8>& pixels, int w,
auto res = PD::Li::Texture::New(texID, PD::ivec2(w, h));
return res;
}
} // namespace Li
} // namespace PD

View File

@ -40,7 +40,7 @@ HidGLFW::HidGLFW(GLFWwindow* win) : HidDriver("HidGLFW") {
Flags |= Flags_HasKeyboard;
Flags |= Flags_HasMouse;
pBinds[GLFW_MOUSE_BUTTON_LEFT] = Touch;
pBinds[GLFW_KEY_F3] = Kb_3;
/*pBinds[GLFW_KEY_F3] = Kb_3;
pBinds[GLFW_KEY_ESCAPE] = Kb_Escape;
pBinds[GLFW_KEY_F11] = Kb_F11;
pBinds[GLFW_KEY_ESCAPE] = Kb_Escape;
@ -94,7 +94,7 @@ HidGLFW::HidGLFW(GLFWwindow* win) : HidDriver("HidGLFW") {
pBinds[GLFW_KEY_9] = Kb_9;
pBinds[GLFW_KEY_0] = Kb_0;
pBinds[GLFW_KEY_BACKSPACE] = Kb_Backspace;
pBinds[GLFW_KEY_ENTER] = Kb_Enter;
pBinds[GLFW_KEY_ENTER] = Kb_Enter;*/
}
void HidGLFW::Update() {
@ -108,7 +108,7 @@ void HidGLFW::Update() {
}
}
// Keyboard Logic
for (auto& it : pBinds) {
/*for (auto& it : pBinds) {
int kbstate = glfwGetKey(Window, it.first);
if (kbstate == GLFW_PRESS) {
if (PrevStates[it.first] == GLFW_RELEASE) {
@ -119,7 +119,7 @@ void HidGLFW::Update() {
KbKeyEvents[0][it.second] = Event_Up;
}
PrevStates[it.first] = kbstate;
}
}*/
// Mouse Logic (Todo: Support all mouse buttons)
int state = glfwGetMouseButton(Window, GLFW_MOUSE_BUTTON_LEFT);
if (state == GLFW_PRESS) {
@ -155,12 +155,12 @@ void HidGLFW::HandleTextOps() {
if (!pText) {
return;
}
if (pTimedHeld(Kb_Backspace)) {
/*if (pTimedHeld(Kb_Backspace)) {
if (!pText->empty()) {
pText->pop_back();
}
} else if (pTimedHeld(Kb_Enter)) {
*pText += '\n';
}
}*/
}
} // namespace PD

View File

@ -37,7 +37,7 @@ void Init(void* data) {
// Dekstop Init Stage
// First use default OS Driver
PD::OS::Init();
PD::Li::Gfx::Init(PD::Li::GfxGL2::New());
PD::Gfx::Init(PD::GfxGL2::New());
PD::Hid::Init(PD::HidGLFW::New(reinterpret_cast<GLFWwindow*>(data)));
}
} // namespace PD

View File

@ -30,4 +30,5 @@ SOFTWARE.
#include <pd/core/sl/pair.hpp>
#include <pd/core/sl/stack.hpp>
#include <pd/core/sl/tools.hpp>
#include <pd/core/sl/vector.hpp>
#include <pd/core/sl/u128.hpp>
#include <pd/core/sl/vector.hpp>

125
include/pd/core/sl/u128.hpp Normal file
View File

@ -0,0 +1,125 @@
#pragma once
#include <pd/core/common.hpp>
namespace PD {
/**
* 128 Bit support for all platforms probably
* only used for flag checks in Keyboard/Mouse Input driver
*/
class u128 {
public:
u64 pLow = 0;
u64 pHigh = 0;
constexpr u128() : pLow(0), pHigh(0) {}
constexpr u128(u64 l, u64 h = 0) : pLow(l), pHigh(h) {}
/**
* Best way so far to create flags that go over 63
* like `1 << 65` is just `u128::Flag(65)`
*/
constexpr static u128 Flag(u32 i) {
if (i < 64) {
return u128(1ULL << i, 0);
} else if (i < 128) {
return u128(0, 1ULL << (i - 64));
}
return u128();
}
u128 operator+(const u128& v) const {
u128 ret;
ret.pLow = pLow + v.pLow;
ret.pHigh = pHigh + v.pHigh + (ret.pLow < pLow);
return ret;
}
u128 operator&(const u128& v) const {
return u128(pLow & v.pLow, pHigh & v.pHigh);
}
u128 operator<<(u32 s) const {
if (s == 0) {
return *this;
}
if (s >= 128) {
return u128();
}
if (s >= 64) {
return u128(0, pLow << (s - 64));
}
return u128(pLow << s, (pHigh << s) | (pLow >> (64 - s)));
}
u128 operator>>(u32 s) const {
if (s == 0) {
return *this;
}
if (s >= 128) {
return u128();
}
if (s >= 64) {
return u128(pHigh >> (s - 64), 0);
}
return u128((pLow >> s) | (pHigh << (64 - s)), pHigh >> s);
}
u128& operator|=(const u128& v) {
pLow |= v.pLow;
pHigh |= v.pHigh;
return *this;
}
u128 operator|(const u128& v) const {
return u128(pLow | v.pLow, pHigh | v.pHigh);
}
u128& operator&=(const u128& v) {
pLow &= v.pLow;
pHigh &= v.pHigh;
return *this;
}
u128 operator~() const { return u128(~pLow, ~pHigh); }
/**
* Old why to make if checks possible
* Problem was that a operator& is required
* with u128 as result
*/
// bool operator&(const u128& v) const {
// return pLow & v.pLow || pHigh & v.pHigh;
// }
bool operator==(const u128& v) const {
return pLow == v.pLow && pHigh == v.pHigh;
}
/**
* Use explicit here to make sure it is only for checking and not for
* some error leading implicit bool assignments...
*/
explicit operator bool() const { return pLow != 0 || pHigh != 0; }
/** Deprecated way to handle `flag & SomeFlag` */
bool Has(const u128& v) const { return pLow & v.pLow || pHigh & v.pHigh; }
bool operator!=(const u128& v) const { return !(*this == v); }
};
} // namespace PD
namespace std {
/**
* Provide c++ STL support for unordered map to u128
*/
template <>
struct hash<PD::u128> {
size_t operator()(const PD::u128& k) const {
// just combine hashes of the parts usign simple xor op
size_t h0 = std::hash<PD::u64>{}(k.pLow);
size_t h1 = std::hash<PD::u64>{}(k.pHigh);
return h0 ^ (h1 << 1);
}
};
} // namespace std

View File

@ -34,7 +34,6 @@ enum LiBackendFlags_ {
};
namespace PD {
namespace Li {
class GfxDriver {
public:
GfxDriver(const std::string& name = "NullGfx") : pName(name) {};
@ -48,27 +47,29 @@ class GfxDriver {
virtual void Deinit() {}
virtual void NewFrame() {}
virtual void BindTex(TexAddress addr) {}
virtual void BindTex(Li::TexAddress addr) {}
virtual void RenderDrawData(const std::vector<Command::Ref>& Commands) {}
virtual void RenderDrawData(const std::vector<Li::Command::Ref>& Commands) {}
void SetViewPort(const ivec2& vp) { ViewPort = vp; }
virtual Texture::Ref LoadTex(
virtual Li::Texture::Ref LoadTex(
const std::vector<u8>& pixels, int w, int h,
Texture::Type type = Texture::Type::RGBA32,
Texture::Filter filter = Texture::Filter::LINEAR) {
Li::Texture::Type type = Li::Texture::Type::RGBA32,
Li::Texture::Filter filter = Li::Texture::Filter::LINEAR) {
// Texture loading not supported (when this func not get override)
return nullptr;
}
Texture::Ref GetSolidTex() { return pSolid; }
Li::Texture::Ref GetSolidTex() { return pSolid; }
const std::string pName = "NullGfx";
LiBackendFlags Flags = 0;
ivec2 ViewPort;
fvec4 ClearColor;
Texture::Ref pSolid;
Mat4 Projection;
Li::Texture::Ref pSolid;
size_t CurrentVertex = 0;
size_t CurrentIndex = 0;
/** Debug Variables */
@ -91,24 +92,23 @@ class Gfx {
static void Deinit() { pGfx->Deinit(); }
static void NewFrame() { pGfx->NewFrame(); }
static void BindTex(TexAddress addr) { pGfx->BindTex(addr); }
static void BindTex(Li::TexAddress addr) { pGfx->BindTex(addr); }
static void SetViewPort(const ivec2& vp) { pGfx->SetViewPort(vp); }
static void RenderDrawData(const std::vector<Command::Ref>& Commands) {
static void RenderDrawData(const std::vector<Li::Command::Ref>& Commands) {
pGfx->RenderDrawData(Commands);
}
static LiBackendFlags Flags() { return pGfx->Flags; }
static Texture::Ref LoadTex(
static Li::Texture::Ref LoadTex(
const std::vector<u8>& pixels, int w, int h,
Texture::Type type = Texture::Type::RGBA32,
Texture::Filter filter = Texture::Filter::LINEAR) {
Li::Texture::Type type = Li::Texture::Type::RGBA32,
Li::Texture::Filter filter = Li::Texture::Filter::LINEAR) {
return pGfx->LoadTex(pixels, w, h, type, filter);
}
static Texture::Ref GetSolidTex() { return pGfx->GetSolidTex(); }
static Li::Texture::Ref GetSolidTex() { return pGfx->GetSolidTex(); }
static GfxDriver::Ref pGfx;
};
} // namespace Li
} // namespace PD

View File

@ -26,14 +26,70 @@ SOFTWARE.
#include <pd/core/core.hpp>
namespace PD {
/** Did not found a better solution yet sadly */
namespace HidKb {
// Lets use u128 here
using KbKey = u128;
constexpr static KbKey Kb_No = 0;
constexpr static KbKey Kb_Escape = KbKey::Flag(0);
constexpr static KbKey Kb_Q = KbKey::Flag(1);
constexpr static KbKey Kb_W = KbKey::Flag(2);
constexpr static KbKey Kb_E = KbKey::Flag(3);
constexpr static KbKey Kb_R = KbKey::Flag(4);
constexpr static KbKey Kb_T = KbKey::Flag(5);
constexpr static KbKey Kb_Z = KbKey::Flag(6);
constexpr static KbKey Kb_U = KbKey::Flag(7);
constexpr static KbKey Kb_I = KbKey::Flag(8);
constexpr static KbKey Kb_O = KbKey::Flag(9);
constexpr static KbKey Kb_P = KbKey::Flag(10);
constexpr static KbKey Kb_A = KbKey::Flag(11);
constexpr static KbKey Kb_S = KbKey::Flag(12);
constexpr static KbKey Kb_D = KbKey::Flag(13);
constexpr static KbKey Kb_F = KbKey::Flag(14);
constexpr static KbKey Kb_G = KbKey::Flag(15);
constexpr static KbKey Kb_H = KbKey::Flag(16);
constexpr static KbKey Kb_J = KbKey::Flag(17);
constexpr static KbKey Kb_K = KbKey::Flag(18);
constexpr static KbKey Kb_L = KbKey::Flag(19);
constexpr static KbKey Kb_Y = KbKey::Flag(20);
constexpr static KbKey Kb_X = KbKey::Flag(21);
constexpr static KbKey Kb_C = KbKey::Flag(22);
constexpr static KbKey Kb_V = KbKey::Flag(23);
constexpr static KbKey Kb_B = KbKey::Flag(24);
constexpr static KbKey Kb_N = KbKey::Flag(25);
constexpr static KbKey Kb_M = KbKey::Flag(26);
constexpr static KbKey Kb_1 = KbKey::Flag(27);
constexpr static KbKey Kb_2 = KbKey::Flag(28);
constexpr static KbKey Kb_3 = KbKey::Flag(29);
constexpr static KbKey Kb_4 = KbKey::Flag(30);
constexpr static KbKey Kb_5 = KbKey::Flag(31);
constexpr static KbKey Kb_6 = KbKey::Flag(32);
constexpr static KbKey Kb_7 = KbKey::Flag(33);
constexpr static KbKey Kb_8 = KbKey::Flag(34);
constexpr static KbKey Kb_9 = KbKey::Flag(35);
constexpr static KbKey Kb_0 = KbKey::Flag(36);
constexpr static KbKey Kb_F1 = KbKey::Flag(37);
constexpr static KbKey Kb_F2 = KbKey::Flag(38);
constexpr static KbKey Kb_F3 = KbKey::Flag(39);
constexpr static KbKey Kb_F4 = KbKey::Flag(40);
constexpr static KbKey Kb_F5 = KbKey::Flag(41);
constexpr static KbKey Kb_F6 = KbKey::Flag(42);
constexpr static KbKey Kb_F7 = KbKey::Flag(43);
constexpr static KbKey Kb_F8 = KbKey::Flag(44);
constexpr static KbKey Kb_F9 = KbKey::Flag(45);
constexpr static KbKey Kb_F10 = KbKey::Flag(46);
constexpr static KbKey Kb_F11 = KbKey::Flag(47);
constexpr static KbKey Kb_F12 = KbKey::Flag(48);
constexpr static KbKey Kb_MouseLeft = KbKey::Flag(120);
} // namespace HidKb
class HidDriver {
public:
enum Flags : u32 {
Flags_None,
FLags_HasGamepad,
Flags_HasKeyboard,
Flags_HasTouch,
Flags_HasMouse,
Flags_None = 0,
FLags_HasGamepad = 1 << 0,
Flags_HasKeyboard = 1 << 1,
Flags_HasTouch = 1 << 2,
Flags_HasMouse = 1 << 3,
};
// Todo: Name to GpKey (GamepadKey)
/** Key [Controller] */
@ -68,64 +124,7 @@ class HidDriver {
Right = DRight | CPRight, ///< DPad or CPad Right
};
// Dont want to use some hardcoded bitset
// so lets use just numbers
enum KbKey : u8 {
Kb_No = 0,
Kb_Escape = 1,
Kb_Q = 2,
Kb_W = 3,
Kb_E = 4,
Kb_R = 5,
Kb_T = 6,
// Yes i use QWERTZ Keyboard
Kb_Z = 7,
Kb_U = 8,
Kb_I = 9,
Kb_O = 10,
Kb_P = 11,
Kb_A = 12,
Kb_S = 13,
Kb_D = 14,
Kb_F = 15,
Kb_G = 16,
Kb_H = 17,
Kb_J = 18,
Kb_K = 19,
Kb_L = 20,
Kb_Y = 21,
Kb_X = 22,
Kb_C = 23,
Kb_V = 24,
Kb_B = 25,
Kb_N = 26,
Kb_M = 27,
Kb_LShift = 28,
Kb_F1 = 29,
Kb_F2 = 30,
Kb_F3 = 31,
Kb_F4 = 32,
Kb_F5 = 33,
Kb_F6 = 34,
Kb_F7 = 35,
Kb_F8 = 36,
Kb_F9 = 37,
Kb_F10 = 38,
Kb_F11 = 39,
Kb_F12 = 40,
Kb_1 = 41,
Kb_2 = 42,
Kb_3 = 43,
Kb_4 = 44,
Kb_5 = 45,
Kb_6 = 46,
Kb_7 = 47,
Kb_8 = 48,
Kb_9 = 49,
Kb_0 = 50,
Kb_Backspace = 51,
Kb_Enter = 52,
};
using KbKey = HidKb::KbKey;
/** Event */
enum Event {
@ -228,7 +227,7 @@ class HidDriver {
/**
* Template Update Function for a device specific driver
*/
virtual void Update() {}
virtual void Update();
/**
* Get Text from Keyboard
*/
@ -244,6 +243,7 @@ class HidDriver {
/** Key Binds Map */
std::unordered_map<u32, u32> pBinds;
std::unordered_map<u128, u128> pKbBinds;
/** Swap Tabe Function */
void SwapTab();
/** Using 2 Positions for Current and Last */
@ -253,7 +253,7 @@ class HidDriver {
/** Key Event Table Setup */
std::unordered_map<Event, u32> KeyEvents[2];
/** Keyboard Key Event Table Setup */
std::unordered_map<u32, Event> KbKeyEvents[2];
std::unordered_map<Event, u128> KbKeyEvents[2];
};
/** Static Hid Controller */
@ -264,7 +264,7 @@ class Hid {
/** Referenec to Drivers enums */
using Key = HidDriver::Key;
using KbKey = HidDriver::KbKey;
using KbKey = HidKb::KbKey;
using Event = HidDriver::Event;
static void Init(HidDriver::Ref v = nullptr) {

View File

@ -35,7 +35,8 @@ class PD_IMAGE_API Image {
RGB, // bpp == 3
RGB565, // bpp == 2 (not supported in laoding)
BGR, // bpp == 3
ABGR // bpp == 4
ABGR, // bpp == 4
BGRA, // bpp == 4
};
Image() = default;
Image(const std::string& path) { this->Load(path); }

View File

@ -70,8 +70,8 @@ class PD_LITHIUM_API DrawList {
void Merge(DrawList::Ref list);
Command::Ref PreGenerateCmd();
void AddCommand(Command::Ref v) { pDrawList.push_back(std::move(v)); }
void Clear() { pDrawList.clear(); }
void AddCommand(Command::Ref v);
void Clear();
void SetFont(Font::Ref font) { pCurrentFont = font; }
void SetFontScale(float scale) { pFontScale = scale; }
@ -194,6 +194,8 @@ class PD_LITHIUM_API DrawList {
Texture::Ref CurrentTex;
std::vector<Command::Ref> pDrawList;
PD::Vec<fvec2> pPath;
u32 pNumIndices = 0;
u32 pNumVertices = 0;
};
} // namespace Li
} // namespace PD

View File

@ -67,6 +67,18 @@ class PD_LITHIUM_API Font {
* @param px_height Pixelheight of the codepoints (limit by 64)
*/
void LoadTTF(const std::string& path, int px_height = 32);
/**
* Load a TTF File from Memory
* @param data File data
* @param px_height Pixelheight of the codepoints (limit by 64)
*/
void LoadTTF(const std::vector<u8>& data, int px_height = 32);
/**
* Function that loads a default integrated font...
* This will only work if PD_LI_INCLUDE_FONTS was set
* on lithium build cause otherwise the font data is not included
*/
void LoadDefaultFont(int id = 0, int pixel_height = 32);
/**
* Getter for Codepoint reference
* @return codepoint dataholder reference

View File

@ -0,0 +1,41 @@
#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifdef PD_LI_INCLUDE_FONTS
#include <pd/core/common.hpp>
/** Generated with pdfm */
namespace PD {
struct FontFileData {
std::string Name;
u32 StartOff;
u32 Size;
};
extern FontFileData pFontData[];
extern size_t pNumFonts;
extern PD::u8 pFontsDataRaw[];
} // namespace PD
#endif

View File

@ -58,7 +58,9 @@ class InputHandler {
// Get a Short define for touch pos
fvec2 p = Hid::MousePos();
// Check if Drag starts in the area position
if (Hid::IsDown(Hid::Key::Touch) && Li::Renderer::InBox(p, area)) {
if ((Hid::IsDown(Hid::Key::Touch) ||
Hid::IsEvent(PD::Hid::Event::Event_Down, HidKb::Kb_MouseLeft)) &&
Li::Renderer::InBox(p, area)) {
// Set ID and iniatial Positions
DraggedObject = id;
DragSourcePos = p;
@ -69,11 +71,16 @@ class InputHandler {
DragTime->Reset();
DragTime->Rseume();
return false; // To make sure the Object is "Dragged"
} else if (Hid::IsHeld(Hid::Key::Touch) && IsObjectDragged()) {
} else if ((Hid::IsHeld(Hid::Key::Touch) ||
Hid::IsEvent(PD::Hid::Event::Event_Held,
HidKb::Kb_MouseLeft)) &&
IsObjectDragged()) {
// Update DragLast and DragPoisition
DragLastPosition = DragPosition;
DragPosition = p;
} else if (Hid::IsUp(Hid::Key::Touch) && IsObjectDragged()) {
} else if ((Hid::IsUp(Hid::Key::Touch) ||
Hid::IsEvent(PD::Hid::Event::Event_Up, HidKb::Kb_MouseLeft)) &&
IsObjectDragged()) {
// Released... Everything gets reset
DraggedObject = 0;
DragPosition = 0;

View File

@ -43,8 +43,8 @@ class PD_UI7_API IO {
FDL = Li::DrawList::New();
DeltaStats = TimeStats::New(60);
/** Probably not the best solution i guess */
CurrentViewPort.z = PD::Li::Gfx::pGfx->ViewPort.x;
CurrentViewPort.w = PD::Li::Gfx::pGfx->ViewPort.y;
CurrentViewPort.z = PD::Gfx::pGfx->ViewPort.x;
CurrentViewPort.w = PD::Gfx::pGfx->ViewPort.y;
}
~IO() {}

View File

@ -43,8 +43,9 @@ class PD_UI7_API Layout {
Scrolling[0] = false;
Scrolling[1] = false;
CursorInit();
Pos = fvec2(0, 0);
Size = fvec2(io->CurrentViewPort.z, io->CurrentViewPort.w);
Pos = fvec2(io->CurrentViewPort.x, io->CurrentViewPort.y);
Size = fvec2(io->CurrentViewPort.z - io->CurrentViewPort.x,
io->CurrentViewPort.w - io->CurrentViewPort.y);
WorkRect = fvec4(IO->MenuPadding, Size - (fvec2(2) * IO->MenuPadding));
}
~Layout() = default;

View File

@ -37,7 +37,7 @@ SOFTWARE.
* Major Minor Patch Build
* 0x01010000 -> 1.1.0-0
*/
#define UI7_VERSION 0x00050001
#define UI7_VERSION 0x00050100
namespace PD {
namespace UI7 {

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.22)
project(pd-core LANGUAGES CXX VERSION 0.5.0)
project(pd-core LANGUAGES CXX VERSION 0.5.1)
set(SRC
source/bit_util.cpp

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.22)
## The Core Core Library
project(pd-drivers LANGUAGES CXX VERSION 0.5.0)
project(pd-drivers LANGUAGES CXX VERSION 0.5.1)
set(SRC
source/hid.cpp

View File

@ -26,7 +26,6 @@ SOFTWARE.
#include <pd/drivers/pd_p_api.hpp>
namespace PD {
namespace Li {
PD_DEF_EXP(GfxDriver::Ref, Gfx::pGfx);
void Gfx::Init(GfxDriver::Ref d) {
@ -42,5 +41,4 @@ void GfxDriver::PostInit() {
std::vector<PD::u8> white(16 * 16 * 4, 0xff);
pSolid = this->LoadTex(white, 16, 16);
}
} // namespace Li
} // namespace PD

View File

@ -5,11 +5,8 @@ namespace PD {
PD_DEF_EXP(HidDriver::Ref, Hid::pHid);
bool HidDriver::IsEvent(Event e, Key keys) { return KeyEvents[0][e] & keys; }
bool HidDriver::IsEvent(Event e, KbKey key) {
if (!KbKeyEvents[0].count(key)) {
return false;
}
return KbKeyEvents[0][key] == e;
bool HidDriver::IsEvent(Event e, KbKey keys) {
return KbKeyEvents[0][e].Has(keys);
}
void HidDriver::SwapTab() {
@ -23,4 +20,20 @@ void HidDriver::SwapTab() {
KeyEvents[0][Event_Held] = tkh;
KeyEvents[0][Event_Up] = tku;
}
/**
* If this func has no verride, still clear the stats
* cause if they are empty this leads to a crash
*/
void HidDriver::Update() {
// Clear States
for (int i = 0; i < 2; i++) {
KeyEvents[i][Event_Down] = 0;
KeyEvents[i][Event_Held] = 0;
KeyEvents[i][Event_Up] = 0;
for (auto& it : KbKeyEvents[i]) {
it.second = Event_Null;
}
}
}
} // namespace PD

View File

@ -133,6 +133,12 @@ PD_IMAGE_API void Image::Convert(Image::Ref img, Image::Format dst) {
img->pBuffer.resize(img->pWidth * img->pHeight * 3);
ImgConvert::RGB32toRGBA24(img->pBuffer, cpy, img->pWidth, img->pHeight);
img->pFmt = RGB;
} else if (img->pFmt == Image::RGBA && dst == Image::BGRA) {
for (int i = 0; i < (img->pWidth * img->pHeight * 4); i += 4) {
u8 _tmp = img->pBuffer[i + 0];
img->pBuffer[i + 0] = img->pBuffer[i + 2];
img->pBuffer[i + 2] = _tmp;
}
} else if (img->pFmt == Image::RGBA && dst == Image::RGB565) {
Convert(img, Image::RGB);
Convert(img, Image::RGB565);

View File

@ -1,10 +1,13 @@
cmake_minimum_required(VERSION 3.22)
project(pd-lithium LANGUAGES CXX VERSION 0.5.0)
project(pd-lithium LANGUAGES CXX VERSION 0.5.1)
option(PD_LI_INCLUDE_FONTS "Include Fonts" OFF)
set(SRC
source/drawlist.cpp
source/font.cpp
source/fonts.cpp
source/renderer.cpp
)
@ -14,4 +17,10 @@ else()
pd_add_lib(pd-lithium SRC_FILES ${SRC})
endif()
if(${PD_LI_INCLUDE_FONTS})
target_compile_definitions(pd-lithium PUBLIC
-DPD_LI_INCLUDE_FONTS=1
)
endif()
target_link_libraries(pd-lithium PUBLIC pd-core)

View File

@ -33,8 +33,22 @@ namespace PD {
namespace Li {
PD_LITHIUM_API void DrawList::DrawSolid() { CurrentTex = Gfx::GetSolidTex(); }
PD_LITHIUM_API void DrawList::Clear() {
pNumIndices = 0;
pNumVertices = 0;
pDrawList.clear();
}
PD_LITHIUM_API void DrawList::AddCommand(Command::Ref v) {
pNumIndices += v->IndexBuffer.Size();
pNumVertices += v->VertexBuffer.Size();
pDrawList.push_back(std::move(v));
}
PD_LITHIUM_API void DrawList::Merge(DrawList::Ref list) {
for (size_t i = 0; i < list->pDrawList.size(); i++) {
pNumIndices += list->pDrawList[i]->IndexBuffer.Size();
pNumVertices += list->pDrawList[i]->VertexBuffer.Size();
pDrawList.push_back(std::move(list->pDrawList[i]));
}
/** Make sure The list gets cleared */

View File

@ -32,25 +32,42 @@ SOFTWARE.
#include <pd/lithium/renderer.hpp>
#ifdef PD_LI_INCLUDE_FONTS
#include <pd/lithium/fonts.hpp>
#endif
namespace PD {
namespace Li {
PD_LITHIUM_API void Font::LoadDefaultFont(int id, int pixel_height) {
#ifdef PD_LI_INCLUDE_FONTS
if (id < pNumFonts) {
auto font = pFontData[id];
LoadTTF(std::vector<u8>(&pFontsDataRaw[font.StartOff],
&pFontsDataRaw[font.StartOff + font.Size]),
pixel_height);
}
#endif
}
PD_LITHIUM_API void Font::LoadTTF(const std::string &path, int height) {
/**
* Just use LoadFile2Mem which looks way cleaner
* and helps not having the font loading code twice
* when adding LoadTTF with mem support
*/
TT::Scope st("LI_LoadTTF_" + path);
auto font = PD::IO::LoadFile2Mem(path);
LoadTTF(font, height);
}
PD_LITHIUM_API void Font::LoadTTF(const std::vector<u8> &data, int height) {
PixelHeight = height; // Set internel pixel height
// Use NextPow2 to be able to use sizes between for example 16 and 32
// before it only was possible to use 8, 16, 32, 64 as size
int texszs = BitUtil::GetPow2(height * 16);
// Load stbtt
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);
stbtt_InitFont(&inf, data.data(), 0);
// clang-format off
// Disable clang here cause dont want a garbage looking line
std::vector<PD::u8> font_tex(texszs * texszs * 4); // Create font Texture

View File

@ -0,0 +1,48 @@
/*
MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifdef PD_LI_INCLUDE_FONTS
#include <pd/lithium/fonts.hpp>
/** Generated with pdfm */
namespace PD {
FontFileData pFontData[] = {
{
"ComicNeue-Bold.ttf",
0,
1,
},
{
"Roboto-Regular.ttf",
0,
1,
},
};
size_t pNumFonts = 2;
// clang-format off
PD::u8 pFontsDataRaw[] = {
0x0
};
// clang-format on
} // namespace PD
#endif

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.22)
project(pd-ui7 LANGUAGES CXX VERSION 0.5.0)
project(pd-ui7 LANGUAGES CXX VERSION 0.5.1)
set(SRC
source/theme.cpp

View File

@ -26,6 +26,7 @@ SOFTWARE.
namespace PD {
PD_UI7_API void UI7::IO::Update() {
/** Todo: find out if we even still use the Drawlist regestry */
u64 current = OS::GetNanoTime();
Delta = static_cast<float>(current - LastTime) / 1000000.f;
LastTime = current;
@ -37,5 +38,7 @@ PD_UI7_API void UI7::IO::Update() {
DrawListRegestry.PushFront(
Pair<UI7::ID, Li::DrawList::Ref>("CtxBackList", Back));
// RegisterDrawList("CtxBackList", Back);
NumIndices = FDL->pNumIndices;
NumVertices = FDL->pNumVertices;
}
} // namespace PD

View File

@ -119,7 +119,8 @@ PD_UI7_API void Menu::HandleFocus() {
if (!pIsOpen) {
newarea = fvec4(pLayout->Pos, fvec2(pLayout->Size.x, TitleBarHeight));
}
if (Hid::IsDown(Hid::Key::Touch) &&
if ((Hid::IsDown(Hid::Key::Touch) ||
Hid::IsEvent(Hid::Event::Event_Down, HidKb::Kb_MouseLeft)) &&
Li::Renderer::InBox(Hid::MousePos(), newarea) &&
!Li::Renderer::InBox(Hid::MousePos(),
pIO->InputHandler->FocusedMenuRect)) {
@ -190,8 +191,8 @@ PD_UI7_API void Menu::HandleTitlebarActions() {
// Maybe i need to add some operators to vec
pLayout->Pos.x = std::clamp<float>(pLayout->Pos.x, -pLayout->Size.x + 10,
pIO->CurrentViewPort.z - 10);
pLayout->Pos.y =
std::clamp<float>(pLayout->Pos.y, 0.f, pIO->CurrentViewPort.w - 10);
pLayout->Pos.y = std::clamp<float>(pLayout->Pos.y, pIO->CurrentViewPort.y,
pIO->CurrentViewPort.w - 10);
}
}
}

View File

@ -169,7 +169,8 @@ PD_UI7_API void Context::AboutMenu(bool *show) {
m->Label("sizeof(size_t) -> " + std::to_string(sizeof(size_t)));
m->Label("sizeof(LI::Vertex) -> " + std::to_string(sizeof(Li::Vertex)));
m->Label("__cplusplus -> " + std::to_string(__cplusplus));
m->Label("Compiler -> (hidden)"); // + LibInfo::CompiledWith());
m->Label("Compiler -> " +
Strings::GetCompilerVersion()); // + LibInfo::CompiledWith());
}
EndMenu();
}
@ -206,6 +207,23 @@ PD_UI7_API void Context::MetricsMenu(bool *show) {
}
m->EndTreeNode();
}
m->SeparatorText("Palladium Info");
m->Label("Renderer: " + PD::Gfx::pGfx->pName);
if (m->BeginTreeNode("Input: " + PD::Hid::pHid->pName)) {
if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasKeyboard) {
m->Label("- Keyboard Supported");
}
if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasMouse) {
m->Label("- Mouse Supported");
}
if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasTouch) {
m->Label("- Touch Supported");
}
if (PD::Hid::GetFlags() & PD::HidDriver::FLags_HasGamepad) {
m->Label("- Gamepad Supported");
}
m->EndTreeNode();
}
/** Section IO */
m->SeparatorText("IO");
if (m->BeginTreeNode("Menus (" + std::to_string(pMenus.size()) + ")")) {

View File

@ -57,7 +57,7 @@ int main() {
#endif
List->SetFont(font);
PD::Image::Convert(img, img->RGBA);
auto tex = PD::Li::Gfx::LoadTex(img->pBuffer, img->pWidth, img->pHeight);
auto tex = PD::Gfx::LoadTex(img->pBuffer, img->pWidth, img->pHeight);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
auto ui7 = PD::UI7::Context::New();
@ -71,7 +71,7 @@ int main() {
font->DefaultPixelHeight = 32;
while (!glfwWindowShouldClose(win)) {
#else
PD::Li::Gfx::pGfx->ViewPort = PD::ivec2(400, 240);
PD::Gfx::pGfx->ViewPort = PD::ivec2(400, 240);
while (aptMainLoop()) {
#endif
PD::Hid::Update();
@ -79,7 +79,10 @@ int main() {
/** Auto ViewPort Resize */
int wx, wy;
glfwGetWindowSize(win, &wx, &wy);
PD::Li::Gfx::pGfx->ViewPort = PD::ivec2(wx, wy);
PD::Gfx::pGfx->ViewPort = PD::ivec2(wx, wy);
glViewport(0, 0, wx, wy);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
// ui7->pIO->GetViewPort(VpTop)->pSize = PD::ivec4(0, 0, wx, wy);
#endif
/** Rendering some stuff */
@ -127,9 +130,8 @@ int main() {
if (ui7->BeginMenu("Yet another Window")) {
auto menu = ui7->pCurrent;
menu->Label(std::format("this->Pos: {}", menu->pLayout->GetPosition()));
menu->Label(
std::format("Vertices: {}", PD::Li::Gfx::pGfx->VertexCounter));
menu->Label(std::format("Indices: {}", PD::Li::Gfx::pGfx->IndexCounter));
menu->Label(std::format("Vertices: {}", PD::Gfx::pGfx->VertexCounter));
menu->Label(std::format("Indices: {}", PD::Gfx::pGfx->IndexCounter));
ui7->EndMenu();
}
if (ui7->BeginMenu("#Debug (UI7)")) {
@ -173,9 +175,9 @@ int main() {
C3D_RenderTargetClear(Top, C3D_CLEAR_ALL, 0x00000000, 0);
#endif
PD::TT::Beg("REN");
PD::Li::Gfx::NewFrame();
PD::Li::Gfx::RenderDrawData(List->pDrawList);
PD::Li::Gfx::RenderDrawData(ui7->GetDrawData()->pDrawList);
PD::Gfx::NewFrame();
PD::Gfx::RenderDrawData(List->pDrawList);
PD::Gfx::RenderDrawData(ui7->GetDrawData()->pDrawList);
/** Clear The List */
List->Clear();
PD::TT::End("REN");

View File

@ -3,3 +3,4 @@ cmake_minimum_required(VERSION 3.22)
add_subdirectory(lazyvec)
add_subdirectory(ppam)
add_subdirectory(pdlm)
add_subdirectory(pdfm)

11
tools/pdfm/CMakeLists.txt Normal file
View File

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.22)
project(pdfm LANGUAGES CXX VERSION 1.0.0)
### Requires C++ 20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED true)
add_executable(pdfm
source/main.cpp
)

167
tools/pdfm/source/main.cpp Normal file
View File

@ -0,0 +1,167 @@
/*
MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
// C++ 20 capable compiler required (eg. force use
// self compiled clang on debian based systems)
#include <filesystem>
#include <format>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
constexpr std::string_view pdfh_text = R"(#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifdef PD_LI_INCLUDE_FONTS
#include <pd/core/common.hpp>
/** Generated with pdfm */
namespace PD {
struct FontFileData {
std::string Name;
u32 StartOff;
u32 Size;
};
extern FontFileData pFontData[];
extern size_t pNumFonts;
extern PD::u8 pFontsDataRaw[];
} // namespace PD
#endif
)";
constexpr std::string_view pdfs_text = R"(/*
MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifdef PD_LI_INCLUDE_FONTS
#include <pd/lithium/fonts.hpp>
/** Generated with pdfm */
namespace PD {{
FontFileData pFontData[] = {{{0}
}};
size_t pNumFonts = {1};
// clang-format off
PD::u8 pFontsDataRaw[] = {{
{2}
}};
// clang-format on
}} // namespace PD
#endif
)";
std::string File2HexSequence(const std::string& path) {
std::string ret;
std::ifstream iff(path, std::ios::binary);
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(iff), {});
iff.close();
for (size_t i = 0; i < buffer.size(); i++) {
ret += std::format("0x{:x},", (int)buffer[i]);
if ((i % 100) == 0 && i != 0) {
ret += '\n';
}
}
return ret;
}
std::string MakeEntry(const std::string& name, unsigned int off,
unsigned int size) {
std::string ret = "\n {\n";
ret += " \"" + name + "\",\n";
ret += " " + std::to_string(off) + ",\n";
ret += " " + std::to_string(size) + ",\n";
ret += " },";
return ret;
}
/**
* Tool to create in code embeded fonts
*/
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cout << argv[0] << " <file1> <file2>..." << std::endl;
return 0;
}
std::string entries;
std::string filez;
unsigned int pNumEntries = 0;
for (int i = 1; i < argc; i++) {
size_t off = filez.size();
std::string t = File2HexSequence(argv[i]);
filez += t;
entries += MakeEntry(std::filesystem::path(argv[i]).filename().string(),
off, t.size());
pNumEntries++;
}
std::fstream off("fonts.hpp", std::ios::out);
off << pdfh_text;
off.close();
off.open("fonts.cpp", std::ios::out);
off << std::format(pdfs_text, entries, pNumEntries, filez);
off.close();
return 0;
}