Compare commits
6 Commits
01fb149e71
...
devel050
Author | SHA1 | Date | |
---|---|---|---|
3823f08bab | |||
decae031ae | |||
da87c0f7c2 | |||
310b44caf5 | |||
87910b57de | |||
31a0c3656f |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
build/
|
build/
|
||||||
.cache
|
.cache
|
||||||
|
.vscode
|
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
# Set Project
|
# 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
|
# Required to add this Variable
|
||||||
set(PD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
set(PD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
@ -40,8 +40,6 @@ class LinearAlloc : public Allocator<T> {
|
|||||||
T* Allocate(size_t n) override { return (T*)linearAlloc(n * sizeof(T)); }
|
T* Allocate(size_t n) override { return (T*)linearAlloc(n * sizeof(T)); }
|
||||||
void Deallocate(T* ptr) { linearFree(ptr); }
|
void Deallocate(T* ptr) { linearFree(ptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Li {
|
|
||||||
class GfxC3D : public GfxDriver {
|
class GfxC3D : public GfxDriver {
|
||||||
public:
|
public:
|
||||||
GfxC3D() : GfxDriver("Citro3D") {}
|
GfxC3D() : GfxDriver("Citro3D") {}
|
||||||
@ -61,18 +59,11 @@ class GfxC3D : public GfxDriver {
|
|||||||
PD::Li::Texture::Filter filter =
|
PD::Li::Texture::Filter filter =
|
||||||
PD::Li::Texture::Filter::LINEAR) override;
|
PD::Li::Texture::Filter::LINEAR) override;
|
||||||
|
|
||||||
Vec<Vertex, LinearAlloc<Vertex>> VertexBuffer;
|
Vec<Li::Vertex, LinearAlloc<Li::Vertex>> VertexBuffer;
|
||||||
Vec<u16, LinearAlloc<u16>> IndexBuffer;
|
Vec<u16, LinearAlloc<u16>> IndexBuffer;
|
||||||
size_t CurrentVertex = 0;
|
|
||||||
size_t CurrentIndex = 0;
|
|
||||||
Mat4 Projection;
|
|
||||||
int pLocProjection = 0;
|
int pLocProjection = 0;
|
||||||
DVLB_s* ShaderCode;
|
DVLB_s* ShaderCode;
|
||||||
shaderProgram_s Shader;
|
shaderProgram_s Shader;
|
||||||
C3D_AttrInfo ShaderInfo;
|
C3D_AttrInfo ShaderInfo;
|
||||||
// Stats oder so IDNK zu lange her
|
|
||||||
PD::u32 NumVtx;
|
|
||||||
PD::u32 NumIdx;
|
|
||||||
};
|
};
|
||||||
} // namespace Li
|
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -25,6 +25,9 @@ SOFTWARE.
|
|||||||
#include <pd-3ds/bknd-gfx.hpp>
|
#include <pd-3ds/bknd-gfx.hpp>
|
||||||
|
|
||||||
/// @brief Shader Code (Unused as i dont want to use libpicasso here (yet))
|
/// @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"(
|
const char* LIShaderCTR = R"(
|
||||||
; LI7 Shader
|
; LI7 Shader
|
||||||
; Constants
|
; Constants
|
||||||
@ -70,22 +73,21 @@ unsigned char li_shader[] = {
|
|||||||
size_t li_shader_size = 0x124;
|
size_t li_shader_size = 0x124;
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
GPU_TEXCOLOR GetTexFmt(Li::Texture::Type type) {
|
||||||
GPU_TEXCOLOR GetTexFmt(Texture::Type type) {
|
if (type == Li::Texture::RGBA32)
|
||||||
if (type == Texture::RGBA32)
|
|
||||||
return GPU_RGBA8;
|
return GPU_RGBA8;
|
||||||
else if (type == Texture::RGB24)
|
else if (type == Li::Texture::RGB24)
|
||||||
return GPU_RGB8;
|
return GPU_RGB8;
|
||||||
else if (type == Texture::A8)
|
else if (type == Li::Texture::A8)
|
||||||
return GPU_A8;
|
return GPU_A8;
|
||||||
return GPU_RGBA8; // Default
|
return GPU_RGBA8; // Default
|
||||||
}
|
}
|
||||||
int GetBPP(Texture::Type type) {
|
int GetBPP(Li::Texture::Type type) {
|
||||||
if (type == Texture::RGBA32)
|
if (type == Li::Texture::RGBA32)
|
||||||
return 4;
|
return 4;
|
||||||
else if (type == Texture::RGB24)
|
else if (type == Li::Texture::RGB24)
|
||||||
return 3;
|
return 3;
|
||||||
else if (type == Texture::A8)
|
else if (type == Li::Texture::A8)
|
||||||
return 1;
|
return 1;
|
||||||
return 0; // Error
|
return 0; // Error
|
||||||
}
|
}
|
||||||
@ -119,10 +121,9 @@ void GfxC3D::NewFrame() {
|
|||||||
CurrentIndex = 0;
|
CurrentIndex = 0;
|
||||||
CurrentVertex = 0;
|
CurrentVertex = 0;
|
||||||
FrameCounter++;
|
FrameCounter++;
|
||||||
VertexCounter = NumVtx;
|
/** Probably completly incorrect but just do it like that */
|
||||||
IndexCounter = NumIdx;
|
VertexCounter = CurrentVertex;
|
||||||
NumVtx = 0;
|
IndexCounter = CurrentIndex;
|
||||||
NumIdx = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxC3D::BindTex(PD::Li::TexAddress addr) {
|
void GfxC3D::BindTex(PD::Li::TexAddress addr) {
|
||||||
@ -130,11 +131,14 @@ void GfxC3D::BindTex(PD::Li::TexAddress addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
||||||
C3D_BindProgram(&Shader);
|
// C3D_BindProgram(&Shader);
|
||||||
|
shaderProgramUse(&Shader);
|
||||||
C3D_SetAttrInfo(&ShaderInfo);
|
C3D_SetAttrInfo(&ShaderInfo);
|
||||||
C3D_Mtx proj;
|
C3D_Mtx proj;
|
||||||
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
||||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, &proj);
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, &proj);
|
||||||
|
// Mat4 proj = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f);
|
||||||
|
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, (C3D_Mtx*)&proj);
|
||||||
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
|
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
|
||||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||||
C3D_TexEnvInit(env);
|
C3D_TexEnvInit(env);
|
||||||
@ -156,11 +160,9 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
|||||||
Commands[index]->ScissorRect == ScissorRect) {
|
Commands[index]->ScissorRect == ScissorRect) {
|
||||||
auto c = Commands[index].get();
|
auto c = Commands[index].get();
|
||||||
for (size_t i = 0; i < c->IndexBuffer.Size(); i++) {
|
for (size_t i = 0; i < c->IndexBuffer.Size(); i++) {
|
||||||
NumIdx++;
|
|
||||||
IndexBuffer[CurrentIndex++] = CurrentVertex + c->IndexBuffer.At(i);
|
IndexBuffer[CurrentIndex++] = CurrentVertex + c->IndexBuffer.At(i);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < c->VertexBuffer.Size(); i++) {
|
for (size_t i = 0; i < c->VertexBuffer.Size(); i++) {
|
||||||
NumVtx++;
|
|
||||||
VertexBuffer[CurrentVertex++] = c->VertexBuffer.At(i);
|
VertexBuffer[CurrentVertex++] = c->VertexBuffer.At(i);
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
@ -177,7 +179,7 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
|||||||
BindTex(Tex->Address);
|
BindTex(Tex->Address);
|
||||||
auto bufInfo = C3D_GetBufInfo();
|
auto bufInfo = C3D_GetBufInfo();
|
||||||
BufInfo_Init(bufInfo);
|
BufInfo_Init(bufInfo);
|
||||||
BufInfo_Add(bufInfo, VertexBuffer.Data(), sizeof(Vertex), 3, 0x210);
|
BufInfo_Add(bufInfo, VertexBuffer.Data(), sizeof(Li::Vertex), 3, 0x210);
|
||||||
|
|
||||||
C3D_DrawElements(GPU_TRIANGLES, CurrentIndex - StartIndex,
|
C3D_DrawElements(GPU_TRIANGLES, CurrentIndex - StartIndex,
|
||||||
C3D_UNSIGNED_SHORT, IndexBuffer.Data() + StartIndex);
|
C3D_UNSIGNED_SHORT, IndexBuffer.Data() + StartIndex);
|
||||||
@ -208,7 +210,7 @@ PD::Li::Texture::Ref GfxC3D::LoadTex(const std::vector<PD::u8>& pixels, int w,
|
|||||||
1.0 - ((float)h / (float)tex_size.y));
|
1.0 - ((float)h / (float)tex_size.y));
|
||||||
|
|
||||||
// Texture Setup
|
// Texture Setup
|
||||||
auto fltr = (filter == Texture::NEAREST ? GPU_NEAREST : GPU_LINEAR);
|
auto fltr = (filter == Li::Texture::NEAREST ? GPU_NEAREST : GPU_LINEAR);
|
||||||
auto tex_fmt = GetTexFmt(type);
|
auto tex_fmt = GetTexFmt(type);
|
||||||
auto tex = new C3D_Tex;
|
auto tex = new C3D_Tex;
|
||||||
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);
|
||||||
@ -240,11 +242,10 @@ PD::Li::Texture::Ref GfxC3D::LoadTex(const std::vector<PD::u8>& pixels, int w,
|
|||||||
|
|
||||||
tex->border = 0x00000000;
|
tex->border = 0x00000000;
|
||||||
C3D_TexSetWrap(tex, GPU_REPEAT, GPU_REPEAT);
|
C3D_TexSetWrap(tex, GPU_REPEAT, GPU_REPEAT);
|
||||||
res->Address = (TexAddress)tex;
|
res->Address = (Li::TexAddress)tex;
|
||||||
std::cout << std::format("Tex {:#08x} Addr {:#08X}", (TexAddress)res.get(),
|
std::cout << std::format("Tex {:#08x} Addr {:#08X}",
|
||||||
res->Address)
|
(Li::TexAddress)res.get(), res->Address)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
} // namespace Li
|
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -28,6 +28,8 @@ SOFTWARE.
|
|||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
Hid3DS::Hid3DS() : HidDriver("Hid3DS") {
|
Hid3DS::Hid3DS() : HidDriver("Hid3DS") {
|
||||||
|
this->Flags |= Flags_HasTouch;
|
||||||
|
this->Flags |= FLags_HasGamepad;
|
||||||
pBinds[KEY_A] = A;
|
pBinds[KEY_A] = A;
|
||||||
pBinds[KEY_B] = B;
|
pBinds[KEY_B] = B;
|
||||||
pBinds[KEY_X] = X;
|
pBinds[KEY_X] = X;
|
||||||
|
@ -30,7 +30,7 @@ void Init(void* data) {
|
|||||||
// Dekstop Init Stage
|
// Dekstop Init Stage
|
||||||
// First use default OS Driver
|
// First use default OS Driver
|
||||||
PD::OS::Init();
|
PD::OS::Init();
|
||||||
PD::Li::Gfx::Init(PD::Li::GfxC3D::New());
|
PD::Gfx::Init(PD::GfxC3D::New());
|
||||||
PD::Hid::Init(PD::Hid3DS::New());
|
PD::Hid::Init(PD::Hid3DS::New());
|
||||||
}
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -33,7 +33,6 @@ SOFTWARE.
|
|||||||
#include <pd/lithium/lithium.hpp>
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
|
||||||
class GfxGL2 : public GfxDriver {
|
class GfxGL2 : public GfxDriver {
|
||||||
public:
|
public:
|
||||||
GfxGL2() : GfxDriver("OpenGL2") {}
|
GfxGL2() : GfxDriver("OpenGL2") {}
|
||||||
@ -53,18 +52,11 @@ class GfxGL2 : public GfxDriver {
|
|||||||
PD::Li::Texture::Filter filter =
|
PD::Li::Texture::Filter filter =
|
||||||
PD::Li::Texture::Filter::LINEAR) override;
|
PD::Li::Texture::Filter::LINEAR) override;
|
||||||
|
|
||||||
PD::Vec<Vertex> VertexBuffer;
|
PD::Vec<Li::Vertex> VertexBuffer;
|
||||||
PD::Vec<PD::u16> IndexBuffer;
|
PD::Vec<PD::u16> IndexBuffer;
|
||||||
size_t CurrentVertex = 0;
|
|
||||||
size_t CurrentIndex = 0;
|
|
||||||
GLuint Shader;
|
GLuint Shader;
|
||||||
GLuint pLocProjection;
|
GLuint pLocProjection;
|
||||||
GLuint pLocTex;
|
GLuint pLocTex;
|
||||||
Mat4 Projection;
|
|
||||||
GLuint VBO, IBO;
|
GLuint VBO, IBO;
|
||||||
// Stats oder so IDNK zu lange her
|
|
||||||
PD::u32 NumVtx;
|
|
||||||
PD::u32 NumIdx;
|
|
||||||
};
|
};
|
||||||
} // namespace Li
|
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -37,9 +37,36 @@ class HidGLFW : public HidDriver {
|
|||||||
PD_SHARED(HidGLFW);
|
PD_SHARED(HidGLFW);
|
||||||
|
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
void GetInputStr(std::string& str) override;
|
||||||
|
void HandleTextOps();
|
||||||
|
bool pTimedHeld(KbKey k) {
|
||||||
|
if (pTimings.count(k)) {
|
||||||
|
if (IsEvent(Event_Up, k)) {
|
||||||
|
pTimings.erase(k);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (PD::OS::GetTime() - pTimings[k]) > 50;
|
||||||
|
}
|
||||||
|
if (!IsEvent(Event_Held, k)) {
|
||||||
|
if (pTimings.count(k)) {
|
||||||
|
pTimings.erase(k);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IsEvent(Event_Held, k)) {
|
||||||
|
pTimings[k] = PD::OS::GetTime();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Data section */
|
/** Data section */
|
||||||
GLFWwindow* Window;
|
GLFWwindow* Window;
|
||||||
int PrevState;
|
int PrevState;
|
||||||
|
std::unordered_map<int, int> PrevStates;
|
||||||
|
static std::string* pText;
|
||||||
|
bool pInTextMode = false;
|
||||||
|
PD::u64 pLastUpdate = 0;
|
||||||
|
std::unordered_map<KbKey, u64> pTimings;
|
||||||
};
|
};
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -25,7 +25,6 @@ SOFTWARE.
|
|||||||
#include <pd-desktop/bknd-gfx.hpp>
|
#include <pd-desktop/bknd-gfx.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
|
||||||
const char* vertex_shader = R"(
|
const char* vertex_shader = R"(
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
@ -36,7 +35,7 @@ const char* vertex_shader = R"(
|
|||||||
varying vec2 oUV;
|
varying vec2 oUV;
|
||||||
varying vec4 oColor;
|
varying vec4 oColor;
|
||||||
|
|
||||||
// Probably forgot about this matric and
|
// Probably forgot about this matrix and
|
||||||
// searched hours for why the rendering isn't working :/
|
// searched hours for why the rendering isn't working :/
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
|
|
||||||
@ -103,17 +102,7 @@ GLuint createShaderProgram(const std::string& vertexShaderSource,
|
|||||||
return shaderProgram;
|
return shaderProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Actual Backend */
|
void SetupShaderAttribs(GLuint Shader) {
|
||||||
|
|
||||||
void GfxGL2::Init() {
|
|
||||||
VertexBuffer.Resize(4 * 8192);
|
|
||||||
IndexBuffer.Resize(6 * 8192);
|
|
||||||
Shader = createShaderProgram(vertex_shader, frag_shader);
|
|
||||||
glUseProgram(Shader);
|
|
||||||
|
|
||||||
glGenBuffers(1, &VBO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
|
|
||||||
GLint _pos = glGetAttribLocation(Shader, "pos");
|
GLint _pos = glGetAttribLocation(Shader, "pos");
|
||||||
GLint _uv = glGetAttribLocation(Shader, "uv");
|
GLint _uv = glGetAttribLocation(Shader, "uv");
|
||||||
GLint _color = glGetAttribLocation(Shader, "color");
|
GLint _color = glGetAttribLocation(Shader, "color");
|
||||||
@ -129,6 +118,21 @@ void GfxGL2::Init() {
|
|||||||
sizeof(PD::Li::Vertex),
|
sizeof(PD::Li::Vertex),
|
||||||
(void*)offsetof(PD::Li::Vertex, Color));
|
(void*)offsetof(PD::Li::Vertex, Color));
|
||||||
glEnableVertexAttribArray(_color);
|
glEnableVertexAttribArray(_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Actual Backend */
|
||||||
|
|
||||||
|
void GfxGL2::Init() {
|
||||||
|
VertexBuffer.Resize(4 * 8192);
|
||||||
|
IndexBuffer.Resize(6 * 8192);
|
||||||
|
Shader = createShaderProgram(vertex_shader, frag_shader);
|
||||||
|
glUseProgram(Shader);
|
||||||
|
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
|
||||||
|
// Attribs Setup
|
||||||
|
SetupShaderAttribs(Shader);
|
||||||
|
|
||||||
glGenBuffers(1, &IBO);
|
glGenBuffers(1, &IBO);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
@ -146,20 +150,21 @@ void GfxGL2::Deinit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GfxGL2::NewFrame() {
|
void GfxGL2::NewFrame() {
|
||||||
|
/*
|
||||||
glViewport(0, 0, ViewPort.x, ViewPort.y);
|
glViewport(0, 0, ViewPort.x, ViewPort.y);
|
||||||
glClearColor(ClearColor.x, ClearColor.y, ClearColor.z, ClearColor.w);
|
glClearColor(ClearColor.x, ClearColor.y, ClearColor.z, ClearColor.w);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
Projection.Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, -1.f, 1.f);
|
*/
|
||||||
glUniformMatrix4fv(pLocProjection, 1, GL_TRUE, Projection.m);
|
Projection = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, -1.f, 1.f);
|
||||||
|
glUseProgram(Shader);
|
||||||
|
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
CurrentIndex = 0;
|
|
||||||
CurrentVertex = 0;
|
|
||||||
FrameCounter++;
|
FrameCounter++;
|
||||||
VertexCounter = NumVtx;
|
VertexCounter = CurrentVertex;
|
||||||
IndexCounter = NumIdx;
|
IndexCounter = CurrentIndex;
|
||||||
NumVtx = 0;
|
CurrentVertex = 0;
|
||||||
NumIdx = 0;
|
CurrentIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxGL2::BindTex(PD::Li::TexAddress addr) {
|
void GfxGL2::BindTex(PD::Li::TexAddress addr) {
|
||||||
@ -170,7 +175,6 @@ void GfxGL2::BindTex(PD::Li::TexAddress addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
||||||
glUseProgram(Shader);
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
while (index < Commands.size()) {
|
while (index < Commands.size()) {
|
||||||
PD::Li::Texture::Ref Tex = Commands[index]->Tex;
|
PD::Li::Texture::Ref Tex = Commands[index]->Tex;
|
||||||
@ -187,11 +191,9 @@ void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
|||||||
Commands[index]->ScissorRect == ScissorRect) {
|
Commands[index]->ScissorRect == ScissorRect) {
|
||||||
auto c = Commands[index].get();
|
auto c = Commands[index].get();
|
||||||
for (size_t i = 0; i < c->IndexBuffer.Size(); i++) {
|
for (size_t i = 0; i < c->IndexBuffer.Size(); i++) {
|
||||||
NumIdx++;
|
|
||||||
IndexBuffer[CurrentIndex++] = CurrentVertex + c->IndexBuffer.At(i);
|
IndexBuffer[CurrentIndex++] = CurrentVertex + c->IndexBuffer.At(i);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < c->VertexBuffer.Size(); i++) {
|
for (size_t i = 0; i < c->VertexBuffer.Size(); i++) {
|
||||||
NumVtx++;
|
|
||||||
VertexBuffer[CurrentVertex++] = c->VertexBuffer.At(i);
|
VertexBuffer[CurrentVertex++] = c->VertexBuffer.At(i);
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
@ -207,6 +209,9 @@ void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
||||||
&VertexBuffer[0], GL_DYNAMIC_DRAW);
|
&VertexBuffer[0], GL_DYNAMIC_DRAW);
|
||||||
|
// For some reason we need to set these every frame for every buffer
|
||||||
|
// Found that out when creating My 3d Engine
|
||||||
|
SetupShaderAttribs(Shader);
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
|
||||||
@ -248,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));
|
auto res = PD::Li::Texture::New(texID, PD::ivec2(w, h));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
} // namespace Li
|
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -23,19 +23,104 @@ SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pd-desktop/bknd-hid.hpp>
|
#include <pd-desktop/bknd-hid.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
|
std::string* HidGLFW::pText;
|
||||||
|
// Default Call back (If no Text input is requsted)
|
||||||
|
void NullTextCB(GLFWwindow* win, unsigned int c) {}
|
||||||
|
// Text callback if requested
|
||||||
|
void TextCB(GLFWwindow* win, unsigned int c) {
|
||||||
|
if (!HidGLFW::pText) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*HidGLFW::pText += (char)c;
|
||||||
|
}
|
||||||
HidGLFW::HidGLFW(GLFWwindow* win) : HidDriver("HidGLFW") {
|
HidGLFW::HidGLFW(GLFWwindow* win) : HidDriver("HidGLFW") {
|
||||||
Window = win;
|
Window = win;
|
||||||
|
glfwSetCharCallback(Window, NullTextCB);
|
||||||
|
Flags |= Flags_HasKeyboard;
|
||||||
|
Flags |= Flags_HasMouse;
|
||||||
pBinds[GLFW_MOUSE_BUTTON_LEFT] = Touch;
|
pBinds[GLFW_MOUSE_BUTTON_LEFT] = Touch;
|
||||||
|
/*pBinds[GLFW_KEY_F3] = Kb_3;
|
||||||
|
pBinds[GLFW_KEY_ESCAPE] = Kb_Escape;
|
||||||
|
pBinds[GLFW_KEY_F11] = Kb_F11;
|
||||||
|
pBinds[GLFW_KEY_ESCAPE] = Kb_Escape;
|
||||||
|
pBinds[GLFW_KEY_Q] = Kb_Q;
|
||||||
|
pBinds[GLFW_KEY_W] = Kb_W;
|
||||||
|
pBinds[GLFW_KEY_E] = Kb_E;
|
||||||
|
pBinds[GLFW_KEY_R] = Kb_R;
|
||||||
|
pBinds[GLFW_KEY_T] = Kb_T;
|
||||||
|
pBinds[GLFW_KEY_Z] = Kb_Z;
|
||||||
|
pBinds[GLFW_KEY_U] = Kb_U;
|
||||||
|
pBinds[GLFW_KEY_I] = Kb_I;
|
||||||
|
pBinds[GLFW_KEY_O] = Kb_O;
|
||||||
|
pBinds[GLFW_KEY_P] = Kb_P;
|
||||||
|
pBinds[GLFW_KEY_A] = Kb_A;
|
||||||
|
pBinds[GLFW_KEY_S] = Kb_S;
|
||||||
|
pBinds[GLFW_KEY_D] = Kb_D;
|
||||||
|
pBinds[GLFW_KEY_F] = Kb_F;
|
||||||
|
pBinds[GLFW_KEY_G] = Kb_G;
|
||||||
|
pBinds[GLFW_KEY_H] = Kb_H;
|
||||||
|
pBinds[GLFW_KEY_J] = Kb_J;
|
||||||
|
pBinds[GLFW_KEY_K] = Kb_K;
|
||||||
|
pBinds[GLFW_KEY_L] = Kb_L;
|
||||||
|
pBinds[GLFW_KEY_Y] = Kb_Y;
|
||||||
|
pBinds[GLFW_KEY_X] = Kb_X;
|
||||||
|
pBinds[GLFW_KEY_C] = Kb_C;
|
||||||
|
pBinds[GLFW_KEY_V] = Kb_V;
|
||||||
|
pBinds[GLFW_KEY_B] = Kb_B;
|
||||||
|
pBinds[GLFW_KEY_N] = Kb_N;
|
||||||
|
pBinds[GLFW_KEY_M] = Kb_M;
|
||||||
|
pBinds[GLFW_KEY_LEFT_SHIFT] = Kb_LShift;
|
||||||
|
pBinds[GLFW_KEY_F1] = Kb_F1;
|
||||||
|
pBinds[GLFW_KEY_F2] = Kb_F2;
|
||||||
|
pBinds[GLFW_KEY_F3] = Kb_F3;
|
||||||
|
pBinds[GLFW_KEY_F4] = Kb_F4;
|
||||||
|
pBinds[GLFW_KEY_F5] = Kb_F5;
|
||||||
|
pBinds[GLFW_KEY_F6] = Kb_F6;
|
||||||
|
pBinds[GLFW_KEY_F7] = Kb_F7;
|
||||||
|
pBinds[GLFW_KEY_F8] = Kb_F8;
|
||||||
|
pBinds[GLFW_KEY_F9] = Kb_F9;
|
||||||
|
pBinds[GLFW_KEY_F10] = Kb_F10;
|
||||||
|
pBinds[GLFW_KEY_F11] = Kb_F11;
|
||||||
|
pBinds[GLFW_KEY_F12] = Kb_F12;
|
||||||
|
pBinds[GLFW_KEY_1] = Kb_1;
|
||||||
|
pBinds[GLFW_KEY_2] = Kb_2;
|
||||||
|
pBinds[GLFW_KEY_3] = Kb_3;
|
||||||
|
pBinds[GLFW_KEY_4] = Kb_4;
|
||||||
|
pBinds[GLFW_KEY_5] = Kb_5;
|
||||||
|
pBinds[GLFW_KEY_6] = Kb_6;
|
||||||
|
pBinds[GLFW_KEY_7] = Kb_7;
|
||||||
|
pBinds[GLFW_KEY_8] = Kb_8;
|
||||||
|
pBinds[GLFW_KEY_9] = Kb_9;
|
||||||
|
pBinds[GLFW_KEY_0] = Kb_0;
|
||||||
|
pBinds[GLFW_KEY_BACKSPACE] = Kb_Backspace;
|
||||||
|
pBinds[GLFW_KEY_ENTER] = Kb_Enter;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void HidGLFW::Update() {
|
void HidGLFW::Update() {
|
||||||
|
// Clear States
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
KeyEvents[i][Event_Down] = 0;
|
KeyEvents[i][Event_Down] = 0;
|
||||||
KeyEvents[i][Event_Held] = 0;
|
KeyEvents[i][Event_Held] = 0;
|
||||||
KeyEvents[i][Event_Up] = 0;
|
KeyEvents[i][Event_Up] = 0;
|
||||||
|
for (auto& it : KbKeyEvents[i]) {
|
||||||
|
it.second = Event_Null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Keyboard Logic
|
||||||
|
/*for (auto& it : pBinds) {
|
||||||
|
int kbstate = glfwGetKey(Window, it.first);
|
||||||
|
if (kbstate == GLFW_PRESS) {
|
||||||
|
if (PrevStates[it.first] == GLFW_RELEASE) {
|
||||||
|
KbKeyEvents[0][it.second] = Event_Down;
|
||||||
|
}
|
||||||
|
KbKeyEvents[0][it.second] = Event_Held;
|
||||||
|
} else if (kbstate == GLFW_RELEASE && PrevStates[it.first] == GLFW_PRESS) {
|
||||||
|
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);
|
int state = glfwGetMouseButton(Window, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
if (state == GLFW_PRESS) {
|
if (state == GLFW_PRESS) {
|
||||||
if (PrevState == GLFW_RELEASE) {
|
if (PrevState == GLFW_RELEASE) {
|
||||||
@ -54,5 +139,28 @@ void HidGLFW::Update() {
|
|||||||
glfwGetCursorPos(Window, &x, &y);
|
glfwGetCursorPos(Window, &x, &y);
|
||||||
pMouse[1] = pMouse[0]; // Cycle pMouse pos
|
pMouse[1] = pMouse[0]; // Cycle pMouse pos
|
||||||
pMouse[0] = fvec2(x, y);
|
pMouse[0] = fvec2(x, y);
|
||||||
|
if (pInTextMode && (PD::OS::GetTime() - pLastUpdate) > 50) {
|
||||||
|
pLastUpdate = PD::OS::GetTime();
|
||||||
|
HandleTextOps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HidGLFW::GetInputStr(std::string& str) {
|
||||||
|
pText = &str;
|
||||||
|
glfwSetCharCallback(Window, TextCB);
|
||||||
|
pInTextMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HidGLFW::HandleTextOps() {
|
||||||
|
if (!pText) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*if (pTimedHeld(Kb_Backspace)) {
|
||||||
|
if (!pText->empty()) {
|
||||||
|
pText->pop_back();
|
||||||
|
}
|
||||||
|
} else if (pTimedHeld(Kb_Enter)) {
|
||||||
|
*pText += '\n';
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -37,7 +37,7 @@ void Init(void* data) {
|
|||||||
// Dekstop Init Stage
|
// Dekstop Init Stage
|
||||||
// First use default OS Driver
|
// First use default OS Driver
|
||||||
PD::OS::Init();
|
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)));
|
PD::Hid::Init(PD::HidGLFW::New(reinterpret_cast<GLFWwindow*>(data)));
|
||||||
}
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -37,13 +37,18 @@ function(pd_add_lib TARGET_NAME)
|
|||||||
${PD_INCLUDE_DIR}
|
${PD_INCLUDE_DIR}
|
||||||
${DEVKITPRO}/portlibs/3ds/include
|
${DEVKITPRO}/portlibs/3ds/include
|
||||||
)
|
)
|
||||||
target_compile_definitions(${TARGET_NAME} PUBLIC
|
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||||
-D_GNU_SOURCE=1
|
-D_GNU_SOURCE=1
|
||||||
-DPALLADIUM_VERSION="${PROJECT_VERSION}"
|
-DPALLADIUM_VERSION="${PROJECT_VERSION}"
|
||||||
-DPALLADIUM_GIT_COMMIT="${GIT_SHORT_HASH}"
|
-DPALLADIUM_GIT_COMMIT="${GIT_SHORT_HASH}"
|
||||||
-DPALLADIUM_GIT_BRANCH="${GIT_BRANCH}"
|
-DPALLADIUM_GIT_BRANCH="${GIT_BRANCH}"
|
||||||
-DBUILD_CTR=1
|
-DBUILD_CTR=1
|
||||||
)
|
)
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
||||||
|
target_compile_options(${TARGET_NAME} PRIVATE
|
||||||
|
-Wno-abi
|
||||||
|
)
|
||||||
|
endif()
|
||||||
### For the libs that depend on another
|
### For the libs that depend on another
|
||||||
if(ARG_DEPENDS)
|
if(ARG_DEPENDS)
|
||||||
target_link_libraries(${TARGET_NAME} PUBLIC ${ARG_DEPENDS})
|
target_link_libraries(${TARGET_NAME} PUBLIC ${ARG_DEPENDS})
|
||||||
|
@ -23,6 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -33,6 +34,7 @@ SOFTWARE.
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <numbers>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
55
include/pd/core/fquat.hpp
Normal file
55
include/pd/core/fquat.hpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This file is based on fvec4
|
||||||
|
|
||||||
|
#include <pd/core/common.hpp>
|
||||||
|
#include <pd/core/vec4.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
class fquat : public fvec4 {
|
||||||
|
constexpr fquat() : fvec4(0.f, 0.f, 0.f, 1.f) {}
|
||||||
|
constexpr fquat(float x, float y, float z, float w) : fvec4(x, y, z, w) {}
|
||||||
|
constexpr fquat(const fvec4& v) : fvec4(v) {}
|
||||||
|
|
||||||
|
static fquat Identity() { return fquat(0.f, 0.f, 0.f, 1.f); }
|
||||||
|
|
||||||
|
constexpr fquat Conjugate() const { return fquat(-x, -y, -z, w); }
|
||||||
|
fquat Inverse() const {
|
||||||
|
float len = SqLen();
|
||||||
|
if (len == 0.0f) {
|
||||||
|
return fquat();
|
||||||
|
}
|
||||||
|
return Conjugate() / len;
|
||||||
|
}
|
||||||
|
|
||||||
|
fquat operator*(const fquat& v) const {
|
||||||
|
return fquat(w * v.x + x * v.w + y * v.z - z * v.y,
|
||||||
|
w * v.y - x * v.z + y * v.w + z * v.x,
|
||||||
|
w * v.z + x * v.y - y * v.x + z * v.w,
|
||||||
|
w * v.w - x * v.x - y * v.y - z * v.z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace PD
|
@ -36,6 +36,12 @@ namespace IO {
|
|||||||
* @return 8Bit FileBuffer
|
* @return 8Bit FileBuffer
|
||||||
*/
|
*/
|
||||||
PD_CORE_API std::vector<u8> LoadFile2Mem(const std::string& path);
|
PD_CORE_API std::vector<u8> LoadFile2Mem(const std::string& path);
|
||||||
|
/**
|
||||||
|
* Load a File into a std::string
|
||||||
|
* @param path Path to the File
|
||||||
|
* @return std::string file content
|
||||||
|
*/
|
||||||
|
PD_CORE_API std::string LoadFile2Str(const std::string& path);
|
||||||
/**
|
/**
|
||||||
* Hash a 8Bit Memory Buffer
|
* Hash a 8Bit Memory Buffer
|
||||||
* @param data 8Bit input Buffer
|
* @param data 8Bit input Buffer
|
||||||
|
@ -25,17 +25,118 @@ SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pd/core/common.hpp>
|
#include <pd/core/common.hpp>
|
||||||
|
#include <pd/core/vec3.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
class PD_CORE_API Mat4 {
|
namespace Numbers {
|
||||||
public:
|
constexpr float Tau = std::numbers::pi * 2.f;
|
||||||
Mat4() { Zeros(); }
|
}
|
||||||
~Mat4() = default;
|
constexpr float Radians(float v) { return v * (Numbers::Tau / 360.0f); }
|
||||||
|
/**
|
||||||
|
* Minimal Mtx4 Lib that precomputes
|
||||||
|
* basic stuff stuff at compiletime
|
||||||
|
*
|
||||||
|
* This Lib includes Patches for work with Citro3D as well
|
||||||
|
*
|
||||||
|
* @note That this is not a full Matrix Library
|
||||||
|
*/
|
||||||
|
|
||||||
void Zeros();
|
struct PD_CORE_API Mat4 {
|
||||||
void Ortho(float left, float right, float bottom, float top, float near,
|
std::array<float, 16> m;
|
||||||
float far);
|
constexpr Mat4() : m{} {}
|
||||||
|
constexpr static Mat4 Diagonal(float x, float y, float z, float w) {
|
||||||
|
Mat4 ret;
|
||||||
|
ret(0, 0) = x;
|
||||||
|
ret(1, 1) = y;
|
||||||
|
ret(2, 2) = z;
|
||||||
|
ret(3, 3) = w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
constexpr static Mat4 Identity() { return Diagonal(1, 1, 1, 1); }
|
||||||
|
|
||||||
float m[16];
|
constexpr float* Ptr() { return m.data(); }
|
||||||
|
constexpr const float* Ptr() const { return m.data(); }
|
||||||
|
|
||||||
|
constexpr float& operator()(int row, int col) {
|
||||||
|
#ifdef __3DS__
|
||||||
|
// 3ds is full reverse order iirc
|
||||||
|
return m[row * 4 + (3 - col)];
|
||||||
|
#else
|
||||||
|
return m[col * 4 + row];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
constexpr float operator()(int row, int col) const {
|
||||||
|
#ifdef __3DS__
|
||||||
|
// 3ds is full reverse order iirc
|
||||||
|
return m[row * 4 + (3 - col)];
|
||||||
|
#else
|
||||||
|
return m[col * 4 + row];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Mat4 operator*(const Mat4& v) const {
|
||||||
|
Mat4 ret;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
float t = 0.f;
|
||||||
|
for (int k = 0; k < 4; k++) {
|
||||||
|
t += (*this)(i, k) * v(k, j);
|
||||||
|
}
|
||||||
|
ret(i, j) = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Mat4& operator*=(const Mat4& v) {
|
||||||
|
*this = *this * v;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static Mat4 Translate(float x, float y, float z) {
|
||||||
|
Mat4 ret = Identity();
|
||||||
|
ret(0, 3) = x;
|
||||||
|
ret(1, 3) = y;
|
||||||
|
ret(2, 3) = z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static Mat4 Scale(float x, float y, float z) {
|
||||||
|
Mat4 ret;
|
||||||
|
ret(0, 0) = x;
|
||||||
|
ret(1, 1) = y;
|
||||||
|
ret(2, 2) = z;
|
||||||
|
ret(3, 3) = 1.f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static Mat4 Ortho(float l, float r, float b, float t, float n,
|
||||||
|
float f) {
|
||||||
|
Mat4 ret;
|
||||||
|
#ifdef __3DS__ // Patch to rotate the Matrix correctly
|
||||||
|
ret(0, 1) = 2.f / (t - b);
|
||||||
|
ret(0, 3) = (b + t) / (b - t);
|
||||||
|
ret(1, 0) = 2.f / (l - r);
|
||||||
|
ret(1, 3) = (l + r) / (r - l);
|
||||||
|
ret(2, 2) = 1.f / (n - f);
|
||||||
|
ret(2, 3) = 0.5f * (n + f) / (n - f) - 0.5f;
|
||||||
|
#else
|
||||||
|
ret(0, 0) = 2.0f / (r - l);
|
||||||
|
ret(0, 3) = -(r + l) / (r - l);
|
||||||
|
ret(1, 1) = 2.0f / (t - b);
|
||||||
|
ret(1, 3) = -(t + b) / (t - b);
|
||||||
|
ret(2, 2) = -2.0f / (f - n);
|
||||||
|
ret(2, 3) = -(f + n) / (f - n);
|
||||||
|
#endif
|
||||||
|
ret(3, 3) = 1.f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Mat4 Rotate(fvec3 axis, float a);
|
||||||
|
static Mat4 RotateX(float a);
|
||||||
|
static Mat4 RotateY(float a);
|
||||||
|
static Mat4 RotateZ(float a);
|
||||||
|
static Mat4 Perspective(float fov, float aspect, float n, float f);
|
||||||
|
static Mat4 LookAt(const fvec3& pos, const fvec3& center, const fvec3& up);
|
||||||
};
|
};
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -30,4 +30,5 @@ SOFTWARE.
|
|||||||
#include <pd/core/sl/pair.hpp>
|
#include <pd/core/sl/pair.hpp>
|
||||||
#include <pd/core/sl/stack.hpp>
|
#include <pd/core/sl/stack.hpp>
|
||||||
#include <pd/core/sl/tools.hpp>
|
#include <pd/core/sl/tools.hpp>
|
||||||
|
#include <pd/core/sl/u128.hpp>
|
||||||
#include <pd/core/sl/vector.hpp>
|
#include <pd/core/sl/vector.hpp>
|
125
include/pd/core/sl/u128.hpp
Normal file
125
include/pd/core/sl/u128.hpp
Normal 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
|
@ -39,7 +39,7 @@ template <typename T, typename CharT>
|
|||||||
struct std::formatter<PD::vec2<T>, CharT> : std::formatter<T, CharT> {
|
struct std::formatter<PD::vec2<T>, CharT> : std::formatter<T, CharT> {
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(const PD::vec2<T>& v, FormatContext& ctx) const {
|
auto format(const PD::vec2<T>& v, FormatContext& ctx) const {
|
||||||
return std::format_to(ctx.out(), "({}, {})", v.x, v.y);
|
return std::format_to(ctx.out(), "{}, {}", v.x, v.y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ template <typename T, typename CharT>
|
|||||||
struct std::formatter<PD::vec3<T>, CharT> : std::formatter<T, CharT> {
|
struct std::formatter<PD::vec3<T>, CharT> : std::formatter<T, CharT> {
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(const PD::vec3<T>& v, FormatContext& ctx) const {
|
auto format(const PD::vec3<T>& v, FormatContext& ctx) const {
|
||||||
return std::format_to(ctx.out(), "({}, {}, {})", v.x, v.y, v.z);
|
return std::format_to(ctx.out(), "{}, {}, {}", v.x, v.y, v.z);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,6 +55,6 @@ template <typename T, typename CharT>
|
|||||||
struct std::formatter<PD::vec4<T>, CharT> : std::formatter<T, CharT> {
|
struct std::formatter<PD::vec4<T>, CharT> : std::formatter<T, CharT> {
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(const PD::vec4<T>& v, FormatContext& ctx) const {
|
auto format(const PD::vec4<T>& v, FormatContext& ctx) const {
|
||||||
return std::format_to(ctx.out(), "({}, {}, {}, {})", v.x, v.y, v.z, v.w);
|
return std::format_to(ctx.out(), "{}, {}, {}, {}", v.x, v.y, v.z, v.w);
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -23,7 +23,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This file is generated by lazyvec
|
// This file is generated by lazyvec 2.0.0
|
||||||
|
|
||||||
#include <pd/core/common.hpp>
|
#include <pd/core/common.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@ -33,20 +34,24 @@ class vec2 {
|
|||||||
T x;
|
T x;
|
||||||
T y;
|
T y;
|
||||||
|
|
||||||
vec2() : x(0), y(0) {}
|
// Constructors
|
||||||
|
|
||||||
|
constexpr vec2() : x(0), y(0) {}
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2(T1 v) {
|
constexpr vec2(T1 v) {
|
||||||
x = (T)v;
|
x = (T)v;
|
||||||
y = (T)v;
|
y = (T)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2(vec2<T1> v) {
|
constexpr vec2(const vec2<T1>& v) {
|
||||||
x = (T)v.x;
|
x = (T)v.x;
|
||||||
y = (T)v.y;
|
y = (T)v.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2(T x, T y) : x(x), y(y) {}
|
constexpr explicit vec2(T x, T y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator+=(T1 v) {
|
vec2<T>& operator+=(T1 v) {
|
||||||
@ -144,14 +149,42 @@ class vec2 {
|
|||||||
return vec2<T>(x / (T)v.x, y / (T)v.y);
|
return vec2<T>(x / (T)v.x, y / (T)v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 operator-() const { return vec2(-x, -y); }
|
// Generic Operations
|
||||||
|
|
||||||
bool operator==(const vec2& v) const { return x == v.x && y == v.y; }
|
vec2 operator-() const { return vec2(-x, -y); }
|
||||||
bool operator!=(const vec2& v) const { return !(*this == v); }
|
template <typename T1>
|
||||||
|
bool operator==(const vec2<T1>& v) const {
|
||||||
|
return x == (T)v.x && y == (T)v.y;
|
||||||
|
}
|
||||||
|
template <typename T1>
|
||||||
|
bool operator!=(const vec2<T1>& v) const {
|
||||||
|
return !(*this == v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
double Len() const { return std::sqrt(SqLen()); }
|
double Len() const { return std::sqrt(SqLen()); }
|
||||||
double SqLen() const { return x * x + y * y; }
|
double SqLen() const { return x * x + y * y; }
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
double Distance(const vec2<T1>& v) const {
|
||||||
|
return (*this - v).Len();
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2<T> Normalize() const {
|
||||||
|
double l = Len();
|
||||||
|
if (l == 0) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
return *this / (T)l;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
T Dot(const vec2<T1>& v) const {
|
||||||
|
return x * (T)v.x + y * (T)v.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap Functions
|
||||||
void SwapXY() {
|
void SwapXY() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = y;
|
x = y;
|
||||||
@ -159,6 +192,6 @@ class vec2 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
using fvec2 = vec2<float>;
|
using fvec2 = vec2<float>;
|
||||||
using dvec2 = vec2<double>;
|
|
||||||
using ivec2 = vec2<int>;
|
using ivec2 = vec2<int>;
|
||||||
|
using dvec2 = vec2<double>;
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
@ -23,8 +23,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This file is generated by lazyvec
|
// This file is generated by lazyvec 2.0.0
|
||||||
|
|
||||||
#include <pd/core/common.hpp>
|
#include <pd/core/common.hpp>
|
||||||
|
// Extended includes (rename if you use other filenames/paths)
|
||||||
|
#include <pd/core/vec2.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -34,22 +37,36 @@ class vec3 {
|
|||||||
T y;
|
T y;
|
||||||
T z;
|
T z;
|
||||||
|
|
||||||
vec3() : x(0), y(0), z(0) {}
|
// Constructors
|
||||||
|
|
||||||
|
constexpr vec3() : x(0), y(0), z(0) {}
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
explicit vec3(T1 v) {
|
constexpr vec3(T1 v) {
|
||||||
x = (T)v;
|
x = (T)v;
|
||||||
y = (T)v;
|
y = (T)v;
|
||||||
z = (T)v;
|
z = (T)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
explicit vec3(vec3<T1> v) {
|
constexpr vec3(const vec3<T1>& v) {
|
||||||
x = (T)v.x;
|
x = (T)v.x;
|
||||||
y = (T)v.y;
|
y = (T)v.y;
|
||||||
z = (T)v.z;
|
z = (T)v.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
constexpr explicit vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||||
|
|
||||||
|
// Extended Constructors
|
||||||
|
template <typename T1>
|
||||||
|
constexpr explicit vec3(const vec2<T1>& xy, T1 z) {
|
||||||
|
{
|
||||||
|
x = (T)xy.x;
|
||||||
|
y = (T)xy.y;
|
||||||
|
this->z = (T)z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator+=(T1 v) {
|
vec3<T>& operator+=(T1 v) {
|
||||||
@ -155,16 +172,47 @@ class vec3 {
|
|||||||
return vec3<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z);
|
return vec3<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 operator-() const { return vec3(-x, -y, -z); }
|
// Generic Operations
|
||||||
|
|
||||||
bool operator==(const vec3& v) const {
|
vec3 operator-() const { return vec3(-x, -y, -z); }
|
||||||
return x == v.x && y == v.y && z == v.z;
|
template <typename T1>
|
||||||
|
bool operator==(const vec3<T1>& v) const {
|
||||||
|
return x == (T)v.x && y == (T)v.y && z == (T)v.z;
|
||||||
}
|
}
|
||||||
bool operator!=(const vec3& v) const { return !(*this == v); }
|
template <typename T1>
|
||||||
|
bool operator!=(const vec3<T1>& v) const {
|
||||||
|
return !(*this == v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
double Len() const { return std::sqrt(SqLen()); }
|
double Len() const { return std::sqrt(SqLen()); }
|
||||||
double SqLen() const { return x * x + y * y + z * z; }
|
double SqLen() const { return x * x + y * y + z * z; }
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
double Distance(const vec3<T1>& v) const {
|
||||||
|
return (*this - v).Len();
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3<T> Normalize() const {
|
||||||
|
double l = Len();
|
||||||
|
if (l == 0) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
return *this / (T)l;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
T Dot(const vec3<T1>& v) const {
|
||||||
|
return x * (T)v.x + y * (T)v.y + z * (T)v.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
vec3<T> Cross(const vec3<T1>& v) const {
|
||||||
|
return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap Functions
|
||||||
void SwapXY() {
|
void SwapXY() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = y;
|
x = y;
|
||||||
@ -182,6 +230,6 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
using fvec3 = vec3<float>;
|
using fvec3 = vec3<float>;
|
||||||
using dvec3 = vec3<double>;
|
|
||||||
using ivec3 = vec3<int>;
|
using ivec3 = vec3<int>;
|
||||||
|
using dvec3 = vec3<double>;
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
@ -23,9 +23,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This file is generated by lazyvec
|
// This file is generated by lazyvec 2.0.0
|
||||||
|
|
||||||
#include <pd/core/common.hpp>
|
#include <pd/core/common.hpp>
|
||||||
#include <pd/core/vec2.hpp> // Extended
|
// Extended includes (rename if you use other filenames/paths)
|
||||||
|
#include <pd/core/vec2.hpp>
|
||||||
|
#include <pd/core/vec3.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -36,9 +39,11 @@ class vec4 {
|
|||||||
T z;
|
T z;
|
||||||
T w;
|
T w;
|
||||||
|
|
||||||
vec4() : x(0), y(0), z(0), w(0) {}
|
// Constructors
|
||||||
|
|
||||||
|
constexpr vec4() : x(0), y(0), z(0), w(0) {}
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
explicit vec4(T1 v) {
|
constexpr vec4(T1 v) {
|
||||||
x = (T)v;
|
x = (T)v;
|
||||||
y = (T)v;
|
y = (T)v;
|
||||||
z = (T)v;
|
z = (T)v;
|
||||||
@ -46,23 +51,37 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
explicit vec4(vec4<T1> v) {
|
constexpr vec4(const vec4<T1>& v) {
|
||||||
x = (T)v.x;
|
x = (T)v.x;
|
||||||
y = (T)v.y;
|
y = (T)v.y;
|
||||||
z = (T)v.z;
|
z = (T)v.z;
|
||||||
w = (T)v.w;
|
w = (T)v.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Extended Constructor */
|
constexpr explicit vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
|
||||||
|
|
||||||
|
// Extended Constructors
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
explicit vec4(vec2<T1> a, vec2<T1> b) {
|
constexpr explicit vec4(const vec2<T1>& xy, const vec2<T1>& zw) {
|
||||||
x = (T)a.x;
|
{
|
||||||
y = (T)a.y;
|
x = (T)xy.x;
|
||||||
z = (T)b.x;
|
y = (T)xy.y;
|
||||||
w = (T)b.y;
|
z = (T)zw.x;
|
||||||
|
w = (T)zw.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
|
template <typename T1>
|
||||||
|
constexpr explicit vec4(const vec3<T1>& xyz, T1 w) {
|
||||||
|
{
|
||||||
|
x = (T)xyz.x;
|
||||||
|
y = (T)xyz.y;
|
||||||
|
z = (T)xyz.z;
|
||||||
|
this->w = (T)w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator+=(T1 v) {
|
vec4<T>& operator+=(T1 v) {
|
||||||
@ -176,16 +195,42 @@ class vec4 {
|
|||||||
return vec4<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z, w / (T)v.w);
|
return vec4<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z, w / (T)v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 operator-() const { return vec4(-x, -y, -z, -w); }
|
// Generic Operations
|
||||||
|
|
||||||
bool operator==(const vec4& v) const {
|
vec4 operator-() const { return vec4(-x, -y, -z, -w); }
|
||||||
return x == v.x && y == v.y && z == v.z && w == v.w;
|
template <typename T1>
|
||||||
|
bool operator==(const vec4<T1>& v) const {
|
||||||
|
return x == (T)v.x && y == (T)v.y && z == (T)v.z && w == (T)v.w;
|
||||||
}
|
}
|
||||||
bool operator!=(const vec4& v) const { return !(*this == v); }
|
template <typename T1>
|
||||||
|
bool operator!=(const vec4<T1>& v) const {
|
||||||
|
return !(*this == v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
double Len() const { return std::sqrt(SqLen()); }
|
double Len() const { return std::sqrt(SqLen()); }
|
||||||
double SqLen() const { return x * x + y * y + z * z + w * w; }
|
double SqLen() const { return x * x + y * y + z * z + w * w; }
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
double Distance(const vec4<T1>& v) const {
|
||||||
|
return (*this - v).Len();
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4<T> Normalize() const {
|
||||||
|
double l = Len();
|
||||||
|
if (l == 0) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
return *this / (T)l;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
T Dot(const vec4<T1>& v) const {
|
||||||
|
return x * (T)v.x + y * (T)v.y + z * (T)v.z + w * (T)v.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap Functions
|
||||||
void SwapXY() {
|
void SwapXY() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = y;
|
x = y;
|
||||||
@ -218,6 +263,6 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
using fvec4 = vec4<float>;
|
using fvec4 = vec4<float>;
|
||||||
using dvec4 = vec4<double>;
|
|
||||||
using ivec4 = vec4<int>;
|
using ivec4 = vec4<int>;
|
||||||
|
using dvec4 = vec4<double>;
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
@ -34,7 +34,6 @@ enum LiBackendFlags_ {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
|
||||||
class GfxDriver {
|
class GfxDriver {
|
||||||
public:
|
public:
|
||||||
GfxDriver(const std::string& name = "NullGfx") : pName(name) {};
|
GfxDriver(const std::string& name = "NullGfx") : pName(name) {};
|
||||||
@ -48,25 +47,29 @@ class GfxDriver {
|
|||||||
virtual void Deinit() {}
|
virtual void Deinit() {}
|
||||||
virtual void NewFrame() {}
|
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) {}
|
||||||
|
|
||||||
virtual Texture::Ref LoadTex(
|
void SetViewPort(const ivec2& vp) { ViewPort = vp; }
|
||||||
|
|
||||||
|
virtual Li::Texture::Ref LoadTex(
|
||||||
const std::vector<u8>& pixels, int w, int h,
|
const std::vector<u8>& pixels, int w, int h,
|
||||||
Texture::Type type = Texture::Type::RGBA32,
|
Li::Texture::Type type = Li::Texture::Type::RGBA32,
|
||||||
Texture::Filter filter = Texture::Filter::LINEAR) {
|
Li::Texture::Filter filter = Li::Texture::Filter::LINEAR) {
|
||||||
// Texture loading not supported (when this func not get override)
|
// Texture loading not supported (when this func not get override)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Ref GetSolidTex() { return pSolid; }
|
Li::Texture::Ref GetSolidTex() { return pSolid; }
|
||||||
|
|
||||||
const std::string pName = "NullGfx";
|
const std::string pName = "NullGfx";
|
||||||
LiBackendFlags Flags = 0;
|
LiBackendFlags Flags = 0;
|
||||||
ivec2 ViewPort;
|
ivec2 ViewPort;
|
||||||
fvec4 ClearColor;
|
Mat4 Projection;
|
||||||
Texture::Ref pSolid;
|
Li::Texture::Ref pSolid;
|
||||||
|
size_t CurrentVertex = 0;
|
||||||
|
size_t CurrentIndex = 0;
|
||||||
|
|
||||||
/** Debug Variables */
|
/** Debug Variables */
|
||||||
|
|
||||||
@ -89,23 +92,23 @@ class Gfx {
|
|||||||
static void Deinit() { pGfx->Deinit(); }
|
static void Deinit() { pGfx->Deinit(); }
|
||||||
static void NewFrame() { pGfx->NewFrame(); }
|
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);
|
pGfx->RenderDrawData(Commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LiBackendFlags Flags() { return pGfx->Flags; }
|
static LiBackendFlags Flags() { return pGfx->Flags; }
|
||||||
static Texture::Ref LoadTex(
|
static Li::Texture::Ref LoadTex(
|
||||||
const std::vector<u8>& pixels, int w, int h,
|
const std::vector<u8>& pixels, int w, int h,
|
||||||
Texture::Type type = Texture::Type::RGBA32,
|
Li::Texture::Type type = Li::Texture::Type::RGBA32,
|
||||||
Texture::Filter filter = Texture::Filter::LINEAR) {
|
Li::Texture::Filter filter = Li::Texture::Filter::LINEAR) {
|
||||||
return pGfx->LoadTex(pixels, w, h, type, filter);
|
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;
|
static GfxDriver::Ref pGfx;
|
||||||
};
|
};
|
||||||
} // namespace Li
|
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -26,8 +26,72 @@ SOFTWARE.
|
|||||||
#include <pd/core/core.hpp>
|
#include <pd/core/core.hpp>
|
||||||
|
|
||||||
namespace PD {
|
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 {
|
class HidDriver {
|
||||||
public:
|
public:
|
||||||
|
enum Flags : u32 {
|
||||||
|
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] */
|
/** Key [Controller] */
|
||||||
enum Key : u32 {
|
enum Key : u32 {
|
||||||
No = 0, ///< No Key
|
No = 0, ///< No Key
|
||||||
@ -60,8 +124,11 @@ class HidDriver {
|
|||||||
Right = DRight | CPRight, ///< DPad or CPad Right
|
Right = DRight | CPRight, ///< DPad or CPad Right
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using KbKey = HidKb::KbKey;
|
||||||
|
|
||||||
/** Event */
|
/** Event */
|
||||||
enum Event {
|
enum Event {
|
||||||
|
Event_Null,
|
||||||
Event_Down, ///< Key Pressed
|
Event_Down, ///< Key Pressed
|
||||||
Event_Held, ///< Key Held
|
Event_Held, ///< Key Held
|
||||||
Event_Up, ///< Key released
|
Event_Up, ///< Key released
|
||||||
@ -90,6 +157,7 @@ class HidDriver {
|
|||||||
* @return if key(s) doing the requiested event
|
* @return if key(s) doing the requiested event
|
||||||
*/
|
*/
|
||||||
bool IsEvent(Event e, Key keys);
|
bool IsEvent(Event e, Key keys);
|
||||||
|
bool IsEvent(Event e, KbKey key);
|
||||||
/**
|
/**
|
||||||
* Check for Key Press Event
|
* Check for Key Press Event
|
||||||
* @param keys set of keys
|
* @param keys set of keys
|
||||||
@ -159,15 +227,23 @@ class HidDriver {
|
|||||||
/**
|
/**
|
||||||
* Template Update Function for a device specific driver
|
* Template Update Function for a device specific driver
|
||||||
*/
|
*/
|
||||||
virtual void Update() {}
|
virtual void Update();
|
||||||
|
/**
|
||||||
|
* Get Text from Keyboard
|
||||||
|
*/
|
||||||
|
virtual void GetInputStr(std::string& str) {}
|
||||||
|
|
||||||
/** Data Section */
|
/** Data Section */
|
||||||
|
|
||||||
/** Backend Identification Name */
|
/** Backend Identification Name */
|
||||||
const std::string pName;
|
const std::string pName;
|
||||||
|
|
||||||
|
/** Flags */
|
||||||
|
u32 Flags = 0;
|
||||||
|
|
||||||
/** Key Binds Map */
|
/** Key Binds Map */
|
||||||
std::unordered_map<u32, u32> pBinds;
|
std::unordered_map<u32, u32> pBinds;
|
||||||
|
std::unordered_map<u128, u128> pKbBinds;
|
||||||
/** Swap Tabe Function */
|
/** Swap Tabe Function */
|
||||||
void SwapTab();
|
void SwapTab();
|
||||||
/** Using 2 Positions for Current and Last */
|
/** Using 2 Positions for Current and Last */
|
||||||
@ -176,6 +252,8 @@ class HidDriver {
|
|||||||
bool pLocked = false;
|
bool pLocked = false;
|
||||||
/** Key Event Table Setup */
|
/** Key Event Table Setup */
|
||||||
std::unordered_map<Event, u32> KeyEvents[2];
|
std::unordered_map<Event, u32> KeyEvents[2];
|
||||||
|
/** Keyboard Key Event Table Setup */
|
||||||
|
std::unordered_map<Event, u128> KbKeyEvents[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Static Hid Controller */
|
/** Static Hid Controller */
|
||||||
@ -186,6 +264,7 @@ class Hid {
|
|||||||
|
|
||||||
/** Referenec to Drivers enums */
|
/** Referenec to Drivers enums */
|
||||||
using Key = HidDriver::Key;
|
using Key = HidDriver::Key;
|
||||||
|
using KbKey = HidKb::KbKey;
|
||||||
using Event = HidDriver::Event;
|
using Event = HidDriver::Event;
|
||||||
|
|
||||||
static void Init(HidDriver::Ref v = nullptr) {
|
static void Init(HidDriver::Ref v = nullptr) {
|
||||||
@ -197,6 +276,7 @@ class Hid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool IsEvent(Event e, Key keys) { return pHid->IsEvent(e, keys); }
|
static bool IsEvent(Event e, Key keys) { return pHid->IsEvent(e, keys); }
|
||||||
|
static bool IsEvent(Event e, KbKey key) { return pHid->IsEvent(e, key); }
|
||||||
static bool IsDown(Key keys) { return pHid->IsDown(keys); }
|
static bool IsDown(Key keys) { return pHid->IsDown(keys); }
|
||||||
static bool IsUp(Key keys) { return pHid->IsUp(keys); }
|
static bool IsUp(Key keys) { return pHid->IsUp(keys); }
|
||||||
static bool IsHeld(Key keys) { return pHid->IsHeld(keys); }
|
static bool IsHeld(Key keys) { return pHid->IsHeld(keys); }
|
||||||
@ -208,6 +288,8 @@ class Hid {
|
|||||||
static void Unlock() { pHid->Unlock(); }
|
static void Unlock() { pHid->Unlock(); }
|
||||||
static bool Locked() { return pHid->Locked(); }
|
static bool Locked() { return pHid->Locked(); }
|
||||||
static void Update() { pHid->Update(); }
|
static void Update() { pHid->Update(); }
|
||||||
|
static u32 GetFlags() { return pHid->Flags; }
|
||||||
|
static void GetStrInput(std::string& str) { pHid->GetInputStr(str); }
|
||||||
|
|
||||||
static HidDriver::Ref pHid;
|
static HidDriver::Ref pHid;
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,8 @@ class PD_IMAGE_API Image {
|
|||||||
RGB, // bpp == 3
|
RGB, // bpp == 3
|
||||||
RGB565, // bpp == 2 (not supported in laoding)
|
RGB565, // bpp == 2 (not supported in laoding)
|
||||||
BGR, // bpp == 3
|
BGR, // bpp == 3
|
||||||
ABGR // bpp == 4
|
ABGR, // bpp == 4
|
||||||
|
BGRA, // bpp == 4
|
||||||
};
|
};
|
||||||
Image() = default;
|
Image() = default;
|
||||||
Image(const std::string& path) { this->Load(path); }
|
Image(const std::string& path) { this->Load(path); }
|
||||||
@ -58,6 +59,9 @@ class PD_IMAGE_API Image {
|
|||||||
int Height() const { return pHeight; }
|
int Height() const { return pHeight; }
|
||||||
Format Fmt() const { return pFmt; }
|
Format Fmt() const { return pFmt; }
|
||||||
|
|
||||||
|
void FlipVertical();
|
||||||
|
void FlipHorizontal();
|
||||||
|
|
||||||
u8& operator[](int idx) { return pBuffer[idx]; }
|
u8& operator[](int idx) { return pBuffer[idx]; }
|
||||||
u8 operator[](int idx) const { return pBuffer[idx]; }
|
u8 operator[](int idx) const { return pBuffer[idx]; }
|
||||||
|
|
||||||
|
@ -61,9 +61,17 @@ class PD_LITHIUM_API DrawList {
|
|||||||
|
|
||||||
PD_SHARED(DrawList);
|
PD_SHARED(DrawList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append an input drawlist on top of this one
|
||||||
|
* This Function will clear the Input list to make sure
|
||||||
|
* THat the moved memory blocks don't get used
|
||||||
|
* @param list DrawList to move into current
|
||||||
|
*/
|
||||||
|
void Merge(DrawList::Ref list);
|
||||||
|
|
||||||
Command::Ref PreGenerateCmd();
|
Command::Ref PreGenerateCmd();
|
||||||
void AddCommand(Command::Ref v) { pDrawList.push_back(std::move(v)); }
|
void AddCommand(Command::Ref v);
|
||||||
void Clear() { pDrawList.clear(); }
|
void Clear();
|
||||||
|
|
||||||
void SetFont(Font::Ref font) { pCurrentFont = font; }
|
void SetFont(Font::Ref font) { pCurrentFont = font; }
|
||||||
void SetFontScale(float scale) { pFontScale = scale; }
|
void SetFontScale(float scale) { pFontScale = scale; }
|
||||||
@ -186,6 +194,8 @@ class PD_LITHIUM_API DrawList {
|
|||||||
Texture::Ref CurrentTex;
|
Texture::Ref CurrentTex;
|
||||||
std::vector<Command::Ref> pDrawList;
|
std::vector<Command::Ref> pDrawList;
|
||||||
PD::Vec<fvec2> pPath;
|
PD::Vec<fvec2> pPath;
|
||||||
|
u32 pNumIndices = 0;
|
||||||
|
u32 pNumVertices = 0;
|
||||||
};
|
};
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
@ -67,6 +67,18 @@ class PD_LITHIUM_API Font {
|
|||||||
* @param px_height Pixelheight of the codepoints (limit by 64)
|
* @param px_height Pixelheight of the codepoints (limit by 64)
|
||||||
*/
|
*/
|
||||||
void LoadTTF(const std::string& path, int px_height = 32);
|
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
|
* Getter for Codepoint reference
|
||||||
* @return codepoint dataholder reference
|
* @return codepoint dataholder reference
|
||||||
@ -83,6 +95,12 @@ class PD_LITHIUM_API Font {
|
|||||||
void CmdTextEx(std::vector<Command::Ref>& cmds, const fvec2& pos, u32 color,
|
void CmdTextEx(std::vector<Command::Ref>& cmds, const fvec2& pos, u32 color,
|
||||||
float scale, const std::string& text, LiTextFlags flags = 0,
|
float scale, const std::string& text, LiTextFlags flags = 0,
|
||||||
const fvec2& box = 0);
|
const fvec2& box = 0);
|
||||||
|
/**
|
||||||
|
* Utility function to create a font atlas
|
||||||
|
* During TTF loading (Internal and should not be called)
|
||||||
|
*/
|
||||||
|
void pMakeAtlas(bool final, std::vector<u8>& font_tex, int texszs,
|
||||||
|
PD::Li::Texture::Ref tex);
|
||||||
|
|
||||||
/** Data Section */
|
/** Data Section */
|
||||||
int PixelHeight;
|
int PixelHeight;
|
||||||
|
41
include/pd/lithium/fonts.hpp
Normal file
41
include/pd/lithium/fonts.hpp
Normal 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
|
@ -85,7 +85,7 @@ class Rect {
|
|||||||
* Get the bottom-right corner position.
|
* Get the bottom-right corner position.
|
||||||
* @return Bottom-right position as vec2.
|
* @return Bottom-right position as vec2.
|
||||||
*/
|
*/
|
||||||
fvec2 BotRight() const { return fvec2(Bot.z, Bot.y); }
|
fvec2 BotRight() const { return fvec2(Bot.z, Bot.w); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the top-left corner position.
|
* Set the top-left corner position.
|
||||||
|
@ -63,6 +63,11 @@ class PD_UI7_API Container {
|
|||||||
// this->screen = io->Ren->CurrentScreen();
|
// this->screen = io->Ren->CurrentScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetClipRect(fvec4 clip) {
|
||||||
|
pClipRect = clip;
|
||||||
|
pCLipRectUsed = true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Setter for Position */
|
/** Setter for Position */
|
||||||
void SetPos(const fvec2& pos) { this->pos = pos; }
|
void SetPos(const fvec2& pos) { this->pos = pos; }
|
||||||
/** Setter for Size */
|
/** Setter for Size */
|
||||||
@ -161,6 +166,10 @@ class PD_UI7_API Container {
|
|||||||
bool pPressed = false;
|
bool pPressed = false;
|
||||||
/** Was Pressed Twice */
|
/** Was Pressed Twice */
|
||||||
bool pPressedTwice = false;
|
bool pPressedTwice = false;
|
||||||
|
/** ClipRect */
|
||||||
|
fvec4 pClipRect;
|
||||||
|
/** Clip Rect used */
|
||||||
|
bool pCLipRectUsed = false;
|
||||||
};
|
};
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
@ -52,6 +52,10 @@ class PD_UI7_API DynObj : public Container {
|
|||||||
|
|
||||||
PD_SHARED(DynObj);
|
PD_SHARED(DynObj);
|
||||||
|
|
||||||
|
void AddInputHandler(std::function<void(UI7::IO::Ref, Container*)> inp) {
|
||||||
|
pInp = inp;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return true if butten is pressed*/
|
/** Return true if butten is pressed*/
|
||||||
bool IsPressed() { return pressed; }
|
bool IsPressed() { return pressed; }
|
||||||
/**
|
/**
|
||||||
@ -72,6 +76,7 @@ class PD_UI7_API DynObj : public Container {
|
|||||||
UI7Color color = UI7Color_Button; ///< current button color
|
UI7Color color = UI7Color_Button; ///< current button color
|
||||||
bool pressed = false; ///< ispressed value
|
bool pressed = false; ///< ispressed value
|
||||||
std::function<void(UI7::IO::Ref, Li::DrawList::Ref, Container*)> pRenFun;
|
std::function<void(UI7::IO::Ref, Li::DrawList::Ref, Container*)> pRenFun;
|
||||||
|
std::function<void(UI7::IO::Ref, Container*)> pInp;
|
||||||
};
|
};
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -31,8 +31,6 @@ using UI7Align = unsigned int;
|
|||||||
using UI7IOFlags = unsigned int;
|
using UI7IOFlags = unsigned int;
|
||||||
/** 32Bit Value for Layout Flags */
|
/** 32Bit Value for Layout Flags */
|
||||||
using UI7LayoutFlags = unsigned int;
|
using UI7LayoutFlags = unsigned int;
|
||||||
/** 32Bit value for DrawFlags */
|
|
||||||
using UI7DrawFlags = unsigned int;
|
|
||||||
|
|
||||||
/** Menu Flags */
|
/** Menu Flags */
|
||||||
enum UI7MenuFlags_ {
|
enum UI7MenuFlags_ {
|
||||||
@ -48,6 +46,9 @@ enum UI7MenuFlags_ {
|
|||||||
UI7MenuFlags_NoResize = 1 << 8, ///< Disable Menu Resize
|
UI7MenuFlags_NoResize = 1 << 8, ///< Disable Menu Resize
|
||||||
UI7MenuFlags_NoClose = 1 << 9, ///< Disable Close Button
|
UI7MenuFlags_NoClose = 1 << 9, ///< Disable Close Button
|
||||||
UI7MenuFlags_NoScrollbar = 1 << 10, ///< Hide the Scrollbar
|
UI7MenuFlags_NoScrollbar = 1 << 10, ///< Hide the Scrollbar
|
||||||
|
// POC
|
||||||
|
UI7MenuFlags_Maximize = 1 << 11, ///< Add a Maximize Button
|
||||||
|
UI7MenuFlags_Minimize = 1 << 12, ///< Add a Minimize Button
|
||||||
// Enable Horizontal and Vertical Scrolling
|
// Enable Horizontal and Vertical Scrolling
|
||||||
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
|
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
|
||||||
};
|
};
|
||||||
@ -58,12 +59,6 @@ enum UI7LayoutFlags_ {
|
|||||||
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
|
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UI7DrawFlags_ {
|
|
||||||
UI7DrawFlags_None = 0,
|
|
||||||
UI7DrawFlags_Close = 1 << 0, ///< Close a PolyLine
|
|
||||||
UI7DrawFlags_AALines = 1 << 1, ///< Anti aliased Lines
|
|
||||||
};
|
|
||||||
|
|
||||||
/** UI7 Context Flags */
|
/** UI7 Context Flags */
|
||||||
enum UI7IOFlags_ {
|
enum UI7IOFlags_ {
|
||||||
UI7IOFlags_None = 0, ///< No Additional Config available
|
UI7IOFlags_None = 0, ///< No Additional Config available
|
||||||
@ -91,6 +86,11 @@ enum UI7LytAdd_ {
|
|||||||
UI7LytAdd_Front = 1 << 2, ///< Add in front of the list
|
UI7LytAdd_Front = 1 << 2, ///< Add in front of the list
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Todo: Look at this
|
||||||
|
* Maybe proof of concept ???
|
||||||
|
* Didnt remember that this exists
|
||||||
|
*/
|
||||||
enum UI7ContainerFlags_ {
|
enum UI7ContainerFlags_ {
|
||||||
UI7ContainerFlags_None = 0,
|
UI7ContainerFlags_None = 0,
|
||||||
UI7ContainerFlags_EnableInternalInput = 1 << 0,
|
UI7ContainerFlags_EnableInternalInput = 1 << 0,
|
||||||
|
@ -58,7 +58,9 @@ class InputHandler {
|
|||||||
// Get a Short define for touch pos
|
// Get a Short define for touch pos
|
||||||
fvec2 p = Hid::MousePos();
|
fvec2 p = Hid::MousePos();
|
||||||
// Check if Drag starts in the area position
|
// 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
|
// Set ID and iniatial Positions
|
||||||
DraggedObject = id;
|
DraggedObject = id;
|
||||||
DragSourcePos = p;
|
DragSourcePos = p;
|
||||||
@ -69,11 +71,16 @@ class InputHandler {
|
|||||||
DragTime->Reset();
|
DragTime->Reset();
|
||||||
DragTime->Rseume();
|
DragTime->Rseume();
|
||||||
return false; // To make sure the Object is "Dragged"
|
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
|
// Update DragLast and DragPoisition
|
||||||
DragLastPosition = DragPosition;
|
DragLastPosition = DragPosition;
|
||||||
DragPosition = p;
|
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
|
// Released... Everything gets reset
|
||||||
DraggedObject = 0;
|
DraggedObject = 0;
|
||||||
DragPosition = 0;
|
DragPosition = 0;
|
||||||
|
@ -40,10 +40,11 @@ class PD_UI7_API IO {
|
|||||||
Theme = UI7::Theme::New();
|
Theme = UI7::Theme::New();
|
||||||
Back = Li::DrawList::New();
|
Back = Li::DrawList::New();
|
||||||
Front = Li::DrawList::New();
|
Front = Li::DrawList::New();
|
||||||
|
FDL = Li::DrawList::New();
|
||||||
DeltaStats = TimeStats::New(60);
|
DeltaStats = TimeStats::New(60);
|
||||||
/** Probably not the best solution i guess */
|
/** Probably not the best solution i guess */
|
||||||
CurrentViewPort.z = PD::Li::Gfx::pGfx->ViewPort.x;
|
CurrentViewPort.z = PD::Gfx::pGfx->ViewPort.x;
|
||||||
CurrentViewPort.w = PD::Li::Gfx::pGfx->ViewPort.y;
|
CurrentViewPort.w = PD::Gfx::pGfx->ViewPort.y;
|
||||||
}
|
}
|
||||||
~IO() {}
|
~IO() {}
|
||||||
|
|
||||||
@ -54,6 +55,12 @@ class PD_UI7_API IO {
|
|||||||
*/
|
*/
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final Draw List for PD::Li::Gfx::RednerDrawData
|
||||||
|
*
|
||||||
|
* Possible thanks to the DrawList::Merge Feature
|
||||||
|
*/
|
||||||
|
Li::DrawList::Ref FDL = nullptr;
|
||||||
ivec4 CurrentViewPort = ivec4(0, 0, 0, 0);
|
ivec4 CurrentViewPort = ivec4(0, 0, 0, 0);
|
||||||
std::unordered_map<u32, ViewPort::Ref> ViewPorts;
|
std::unordered_map<u32, ViewPort::Ref> ViewPorts;
|
||||||
float Framerate = 0.f;
|
float Framerate = 0.f;
|
||||||
@ -94,6 +101,13 @@ class PD_UI7_API IO {
|
|||||||
ViewPorts[id] = ViewPort::New(id, size);
|
ViewPorts[id] = ViewPort::New(id, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewPort::Ref GetViewPort(const ID& id) {
|
||||||
|
if (!ViewPorts.count(id)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return ViewPorts[id];
|
||||||
|
}
|
||||||
|
|
||||||
UI7::InputHandler::Ref InputHandler;
|
UI7::InputHandler::Ref InputHandler;
|
||||||
};
|
};
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
|
@ -39,11 +39,13 @@ class PD_UI7_API Layout {
|
|||||||
this->IO = io;
|
this->IO = io;
|
||||||
DrawList = Li::DrawList::New();
|
DrawList = Li::DrawList::New();
|
||||||
DrawList->SetFont(IO->Font);
|
DrawList->SetFont(IO->Font);
|
||||||
|
DrawList->SetFontScale(io->FontScale);
|
||||||
Scrolling[0] = false;
|
Scrolling[0] = false;
|
||||||
Scrolling[1] = false;
|
Scrolling[1] = false;
|
||||||
CursorInit();
|
CursorInit();
|
||||||
Pos = fvec2(0, 0);
|
Pos = fvec2(io->CurrentViewPort.x, io->CurrentViewPort.y);
|
||||||
Size = fvec2(io->CurrentViewPort.z, io->CurrentViewPort.w);
|
Size = fvec2(io->CurrentViewPort.z - io->CurrentViewPort.x,
|
||||||
|
io->CurrentViewPort.w - io->CurrentViewPort.y);
|
||||||
WorkRect = fvec4(IO->MenuPadding, Size - (fvec2(2) * IO->MenuPadding));
|
WorkRect = fvec4(IO->MenuPadding, Size - (fvec2(2) * IO->MenuPadding));
|
||||||
}
|
}
|
||||||
~Layout() = default;
|
~Layout() = default;
|
||||||
@ -126,7 +128,8 @@ class PD_UI7_API Layout {
|
|||||||
fvec2 MaxPosition;
|
fvec2 MaxPosition;
|
||||||
fvec4 WorkRect;
|
fvec4 WorkRect;
|
||||||
|
|
||||||
// Scrolling
|
// Scrolling (Only theoretical)
|
||||||
|
// Rendering must be done by the Objective that uses the Lyt
|
||||||
fvec2 ScrollOffset;
|
fvec2 ScrollOffset;
|
||||||
bool Scrolling[2];
|
bool Scrolling[2];
|
||||||
|
|
||||||
|
@ -24,12 +24,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pd/ui7/container/dragdata.hpp"
|
|
||||||
#include <pd/core/core.hpp>
|
#include <pd/core/core.hpp>
|
||||||
#include <pd/ui7/io.hpp>
|
#include <pd/ui7/io.hpp>
|
||||||
#include <pd/ui7/layout.hpp>
|
#include <pd/ui7/layout.hpp>
|
||||||
#include <pd/ui7/pd_p_api.hpp>
|
#include <pd/ui7/pd_p_api.hpp>
|
||||||
|
|
||||||
|
#include "pd/ui7/container/dragdata.hpp"
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace UI7 {
|
namespace UI7 {
|
||||||
class PD_UI7_API Menu {
|
class PD_UI7_API Menu {
|
||||||
@ -87,9 +88,11 @@ public:
|
|||||||
}
|
}
|
||||||
pLayout->AddObject(r);
|
pLayout->AddObject(r);
|
||||||
}
|
}
|
||||||
void Sameline() { pLayout->SameLine(); }
|
void SameLine() { pLayout->SameLine(); }
|
||||||
void Separator();
|
void Separator();
|
||||||
void SeparatorText(const std::string &label);
|
void SeparatorText(const std::string &label);
|
||||||
|
bool BeginTreeNode(const ID &id);
|
||||||
|
void EndTreeNode();
|
||||||
|
|
||||||
void HandleFocus();
|
void HandleFocus();
|
||||||
void HandleScrolling();
|
void HandleScrolling();
|
||||||
@ -106,6 +109,7 @@ public:
|
|||||||
ID pID;
|
ID pID;
|
||||||
bool *pIsShown = nullptr;
|
bool *pIsShown = nullptr;
|
||||||
bool pIsOpen = true;
|
bool pIsOpen = true;
|
||||||
|
std::unordered_map<u32, bool> pTreeNodes;
|
||||||
|
|
||||||
float TitleBarHeight = 0.f;
|
float TitleBarHeight = 0.f;
|
||||||
};
|
};
|
||||||
|
@ -24,19 +24,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pd/ui7/flags.hpp"
|
|
||||||
#include <pd/core/core.hpp>
|
#include <pd/core/core.hpp>
|
||||||
#include <pd/ui7/io.hpp>
|
#include <pd/ui7/io.hpp>
|
||||||
#include <pd/ui7/menu.hpp>
|
#include <pd/ui7/menu.hpp>
|
||||||
#include <pd/ui7/pd_p_api.hpp>
|
#include <pd/ui7/pd_p_api.hpp>
|
||||||
|
|
||||||
|
#include "pd/ui7/flags.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare UI7 Version
|
* Declare UI7 Version
|
||||||
* Format: 00 00 00 00
|
* Format: 00 00 00 00
|
||||||
* Major Minor Patch Build
|
* Major Minor Patch Build
|
||||||
* 0x01010000 -> 1.1.0-0
|
* 0x01010000 -> 1.1.0-0
|
||||||
*/
|
*/
|
||||||
#define UI7_VERSION 0x00050000
|
#define UI7_VERSION 0x00050100
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace UI7 {
|
namespace UI7 {
|
||||||
@ -57,8 +58,13 @@ public:
|
|||||||
void AddViewPort(const ID &id, const ivec4 &vp);
|
void AddViewPort(const ID &id, const ivec4 &vp);
|
||||||
void UseViewPort(const ID &id);
|
void UseViewPort(const ID &id);
|
||||||
void Update();
|
void Update();
|
||||||
bool BeginMenu(const ID &id, UI7MenuFlags flags, bool *pShow = nullptr);
|
bool BeginMenu(const ID &id, UI7MenuFlags flags = 0, bool *pShow = nullptr);
|
||||||
void EndMenu();
|
void EndMenu();
|
||||||
|
void AboutMenu(bool *show = nullptr);
|
||||||
|
void MetricsMenu(bool *show = nullptr);
|
||||||
|
void StyleEditor(bool *show = nullptr);
|
||||||
|
|
||||||
|
Li::DrawList::Ref GetDrawData() { return pIO->FDL; }
|
||||||
|
|
||||||
Menu::Ref pGetOrCreateMenu(const ID &id) {
|
Menu::Ref pGetOrCreateMenu(const ID &id) {
|
||||||
auto menu = pMenus.find(id);
|
auto menu = pMenus.find(id);
|
||||||
@ -73,6 +79,7 @@ public:
|
|||||||
/** Current Menu */
|
/** Current Menu */
|
||||||
Menu::Ref pCurrent = nullptr;
|
Menu::Ref pCurrent = nullptr;
|
||||||
std::vector<u32> pCurrentMenus;
|
std::vector<u32> pCurrentMenus;
|
||||||
|
std::vector<u32> pDFO; /** Debug Final Order */
|
||||||
std::unordered_map<u32, Menu::Ref> pMenus;
|
std::unordered_map<u32, Menu::Ref> pMenus;
|
||||||
};
|
};
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
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
|
set(SRC
|
||||||
source/bit_util.cpp
|
source/bit_util.cpp
|
||||||
|
@ -39,6 +39,20 @@ PD_CORE_API std::vector<u8> LoadFile2Mem(const std::string& path) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_CORE_API std::string LoadFile2Str(const std::string& path) {
|
||||||
|
std::ifstream iff(path, std::ios::binary);
|
||||||
|
if (!iff) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::string ret;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(iff, line)) {
|
||||||
|
ret += line;
|
||||||
|
}
|
||||||
|
iff.close();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
PD_CORE_API u32 HashMemory(const std::vector<u8>& data) {
|
PD_CORE_API u32 HashMemory(const std::vector<u8>& data) {
|
||||||
u32 hash = 4477;
|
u32 hash = 4477;
|
||||||
for (auto& it : data) {
|
for (auto& it : data) {
|
||||||
|
@ -25,32 +25,98 @@ SOFTWARE.
|
|||||||
#include <pd/core/mat.hpp>
|
#include <pd/core/mat.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
PD_CORE_API void Mat4::Zeros() {
|
PD_CORE_API Mat4 Mat4::RotateX(float a) {
|
||||||
for (int i = 0; i < 16; i++) {
|
float c = std::cos(a);
|
||||||
m[i] = 0.0f;
|
float s = std::sin(a);
|
||||||
}
|
Mat4 ret = Identity();
|
||||||
|
ret(1, 1) = c;
|
||||||
|
ret(1, 2) = -s;
|
||||||
|
ret(2, 1) = s;
|
||||||
|
ret(2, 2) = c;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_CORE_API void Mat4::Ortho(float left, float right, float bottom, float top,
|
PD_CORE_API Mat4 Mat4::RotateY(float a) {
|
||||||
float near, float far) {
|
float c = std::cos(a);
|
||||||
m[0] = 2.0f / (right - left);
|
float s = std::sin(a);
|
||||||
m[1] = 0.0f;
|
Mat4 ret = Identity();
|
||||||
m[2] = 0.0f;
|
ret(0, 0) = c;
|
||||||
m[3] = -(right + left) / (right - left);
|
ret(0, 2) = s;
|
||||||
|
ret(2, 0) = -s;
|
||||||
|
ret(2, 2) = c;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
m[4] = 0.0f;
|
PD_CORE_API Mat4 Mat4::RotateZ(float a) {
|
||||||
m[5] = 2.0f / (top - bottom);
|
float c = std::cos(a);
|
||||||
m[6] = 0.0f;
|
float s = std::sin(a);
|
||||||
m[7] = -(top + bottom) / (top - bottom);
|
Mat4 ret = Identity();
|
||||||
|
ret(0, 0) = c;
|
||||||
|
ret(0, 1) = -s;
|
||||||
|
ret(1, 0) = s;
|
||||||
|
ret(1, 1) = c;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
m[8] = 0.0f;
|
PD_CORE_API Mat4 Mat4::Rotate(fvec3 axis, float a) {
|
||||||
m[9] = 0.0f;
|
float s = std::sin(a);
|
||||||
m[10] = -2.0f / (far - near);
|
float c = std::cos(a);
|
||||||
m[11] = -(far + near) / (far - near);
|
float t = 1.f - c;
|
||||||
|
axis = axis.Normalize();
|
||||||
|
float x = axis.x;
|
||||||
|
float y = axis.y;
|
||||||
|
float z = axis.z;
|
||||||
|
Mat4 ret = Identity();
|
||||||
|
ret(0, 0) = t * x * x + c;
|
||||||
|
ret(0, 1) = t * x * y - z * s;
|
||||||
|
ret(0, 2) = t * x * z + y * s;
|
||||||
|
|
||||||
m[12] = 0.0f;
|
ret(1, 0) = t * x * y + z * s;
|
||||||
m[13] = 0.0f;
|
ret(1, 1) = t * y * y + c;
|
||||||
m[14] = 0.0f;
|
ret(1, 2) = t * y * z - x * s;
|
||||||
m[15] = 1.0f;
|
|
||||||
|
ret(2, 0) = t * x * z - y * s;
|
||||||
|
ret(2, 1) = t * y * z + x * s;
|
||||||
|
ret(2, 2) = t * z * z + c;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_CORE_API Mat4 Mat4::Perspective(float fov, float aspect, float n, float f) {
|
||||||
|
float _fov = std::tan(fov / 2.f);
|
||||||
|
Mat4 ret;
|
||||||
|
ret(0, 0) = 1.f / (aspect * _fov);
|
||||||
|
ret(1, 1) = 1.f / _fov;
|
||||||
|
#ifdef __3DS__
|
||||||
|
ret(2, 3) = f * n / (n - f);
|
||||||
|
ret(2, 2) = -(-1.f) * n / (n - f);
|
||||||
|
#else
|
||||||
|
ret(2, 2) = -(f + n) / (f - n);
|
||||||
|
ret(2, 3) = -(2.f * f * n) / (f - n);
|
||||||
|
#endif
|
||||||
|
ret(3, 2) = -1.f;
|
||||||
|
ret(3, 3) = 0.0f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_CORE_API Mat4 Mat4::LookAt(const fvec3& pos, const fvec3& center,
|
||||||
|
const fvec3& up) {
|
||||||
|
auto f = fvec3(center - pos).Normalize();
|
||||||
|
auto s = f.Cross(up).Normalize();
|
||||||
|
auto u = s.Cross(f);
|
||||||
|
|
||||||
|
Mat4 ret = Identity();
|
||||||
|
ret(0, 0) = s.x;
|
||||||
|
ret(0, 1) = s.y;
|
||||||
|
ret(0, 2) = s.z;
|
||||||
|
ret(1, 0) = u.x;
|
||||||
|
ret(1, 1) = u.y;
|
||||||
|
ret(1, 2) = u.z;
|
||||||
|
ret(2, 0) = -f.x;
|
||||||
|
ret(2, 1) = -f.y;
|
||||||
|
ret(2, 2) = -f.z;
|
||||||
|
ret(0, 3) = -s.Dot(pos);
|
||||||
|
ret(1, 3) = -u.Dot(pos);
|
||||||
|
ret(2, 3) = f.Dot(pos);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
## The Core Core Library
|
## The Core Core Library
|
||||||
project(pd-drivers LANGUAGES CXX VERSION 0.5.0)
|
project(pd-drivers LANGUAGES CXX VERSION 0.5.1)
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
source/hid.cpp
|
source/hid.cpp
|
||||||
|
@ -26,7 +26,6 @@ SOFTWARE.
|
|||||||
#include <pd/drivers/pd_p_api.hpp>
|
#include <pd/drivers/pd_p_api.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
|
||||||
PD_DEF_EXP(GfxDriver::Ref, Gfx::pGfx);
|
PD_DEF_EXP(GfxDriver::Ref, Gfx::pGfx);
|
||||||
|
|
||||||
void Gfx::Init(GfxDriver::Ref d) {
|
void Gfx::Init(GfxDriver::Ref d) {
|
||||||
@ -42,5 +41,4 @@ void GfxDriver::PostInit() {
|
|||||||
std::vector<PD::u8> white(16 * 16 * 4, 0xff);
|
std::vector<PD::u8> white(16 * 16 * 4, 0xff);
|
||||||
pSolid = this->LoadTex(white, 16, 16);
|
pSolid = this->LoadTex(white, 16, 16);
|
||||||
}
|
}
|
||||||
} // namespace Li
|
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -5,6 +5,9 @@ namespace PD {
|
|||||||
PD_DEF_EXP(HidDriver::Ref, Hid::pHid);
|
PD_DEF_EXP(HidDriver::Ref, Hid::pHid);
|
||||||
|
|
||||||
bool HidDriver::IsEvent(Event e, Key keys) { return KeyEvents[0][e] & keys; }
|
bool HidDriver::IsEvent(Event e, Key keys) { return KeyEvents[0][e] & keys; }
|
||||||
|
bool HidDriver::IsEvent(Event e, KbKey keys) {
|
||||||
|
return KbKeyEvents[0][e].Has(keys);
|
||||||
|
}
|
||||||
|
|
||||||
void HidDriver::SwapTab() {
|
void HidDriver::SwapTab() {
|
||||||
auto tkd = KeyEvents[1][Event_Down];
|
auto tkd = KeyEvents[1][Event_Down];
|
||||||
@ -17,4 +20,20 @@ void HidDriver::SwapTab() {
|
|||||||
KeyEvents[0][Event_Held] = tkh;
|
KeyEvents[0][Event_Held] = tkh;
|
||||||
KeyEvents[0][Event_Up] = tku;
|
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
|
} // namespace PD
|
@ -77,6 +77,46 @@ PD_IMAGE_API void Image::Copy(const std::vector<u8>& buf, int w, int h,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_IMAGE_API void Image::FlipHorizontal() {
|
||||||
|
/**
|
||||||
|
* Dont know if i am brain dead but i think this code
|
||||||
|
* should Horizpntal flip an image
|
||||||
|
* Probably this needs some optimisation like not always calling
|
||||||
|
* Fmt2Bpp and use `* 0.5` instead of `/ 2` i guess
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < pWidth / 2; i++) {
|
||||||
|
for (int j = 0; j < pHeight; j++) {
|
||||||
|
int src = (j * pWidth + i) * Fmt2Bpp(pFmt);
|
||||||
|
int dst = (j * pWidth + (pWidth - 1 - i)) * Fmt2Bpp(pFmt);
|
||||||
|
for (int k = 0; k < Fmt2Bpp(pFmt); k++) {
|
||||||
|
PD::u8 tmp = pBuffer[dst + k];
|
||||||
|
pBuffer[dst + k] = pBuffer[src + k];
|
||||||
|
pBuffer[src + k] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_IMAGE_API void Image::FlipVertical() {
|
||||||
|
/**
|
||||||
|
* Dont know if i am brain dead but i think this code
|
||||||
|
* should Vertical flip an image
|
||||||
|
* Probably this needs some optimisation like not always calling
|
||||||
|
* Fmt2Bpp and use `* 0.5` instead of `/ 2` i guess
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < pWidth; i++) {
|
||||||
|
for (int j = 0; j < pHeight / 2; j++) {
|
||||||
|
int src = (j * pWidth + i) * Fmt2Bpp(pFmt);
|
||||||
|
int dst = ((pHeight - 1 - j) * pWidth + i) * Fmt2Bpp(pFmt);
|
||||||
|
for (int k = 0; k < Fmt2Bpp(pFmt); k++) {
|
||||||
|
PD::u8 tmp = pBuffer[dst + k];
|
||||||
|
pBuffer[dst + k] = pBuffer[src + k];
|
||||||
|
pBuffer[src + k] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PD_IMAGE_API void Image::Convert(Image::Ref img, Image::Format dst) {
|
PD_IMAGE_API void Image::Convert(Image::Ref img, Image::Format dst) {
|
||||||
if (img->pFmt == dst) {
|
if (img->pFmt == dst) {
|
||||||
return;
|
return;
|
||||||
@ -93,6 +133,12 @@ PD_IMAGE_API void Image::Convert(Image::Ref img, Image::Format dst) {
|
|||||||
img->pBuffer.resize(img->pWidth * img->pHeight * 3);
|
img->pBuffer.resize(img->pWidth * img->pHeight * 3);
|
||||||
ImgConvert::RGB32toRGBA24(img->pBuffer, cpy, img->pWidth, img->pHeight);
|
ImgConvert::RGB32toRGBA24(img->pBuffer, cpy, img->pWidth, img->pHeight);
|
||||||
img->pFmt = RGB;
|
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) {
|
} else if (img->pFmt == Image::RGBA && dst == Image::RGB565) {
|
||||||
Convert(img, Image::RGB);
|
Convert(img, Image::RGB);
|
||||||
Convert(img, Image::RGB565);
|
Convert(img, Image::RGB565);
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
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
|
set(SRC
|
||||||
source/drawlist.cpp
|
source/drawlist.cpp
|
||||||
source/font.cpp
|
source/font.cpp
|
||||||
|
source/fonts.cpp
|
||||||
source/renderer.cpp
|
source/renderer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,4 +17,10 @@ else()
|
|||||||
pd_add_lib(pd-lithium SRC_FILES ${SRC})
|
pd_add_lib(pd-lithium SRC_FILES ${SRC})
|
||||||
endif()
|
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)
|
target_link_libraries(pd-lithium PUBLIC pd-core)
|
||||||
|
@ -33,13 +33,35 @@ namespace PD {
|
|||||||
namespace Li {
|
namespace Li {
|
||||||
PD_LITHIUM_API void DrawList::DrawSolid() { CurrentTex = Gfx::GetSolidTex(); }
|
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 */
|
||||||
|
list->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
PD_LITHIUM_API Command::Ref DrawList::PreGenerateCmd() {
|
PD_LITHIUM_API Command::Ref DrawList::PreGenerateCmd() {
|
||||||
Command::Ref cmd = Command::New();
|
Command::Ref cmd = Command::New();
|
||||||
cmd->Layer = Layer;
|
cmd->Layer = Layer;
|
||||||
cmd->Index = pDrawList.size();
|
cmd->Index = pDrawList.size();
|
||||||
cmd->Tex = CurrentTex;
|
cmd->Tex = CurrentTex;
|
||||||
pClipCmd(cmd.get());
|
pClipCmd(cmd.get());
|
||||||
return std::move(cmd);
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_LITHIUM_API void DrawList::pClipCmd(Command *cmd) {
|
PD_LITHIUM_API void DrawList::pClipCmd(Command *cmd) {
|
||||||
|
@ -32,80 +32,123 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include <pd/lithium/renderer.hpp>
|
#include <pd/lithium/renderer.hpp>
|
||||||
|
|
||||||
|
#ifdef PD_LI_INCLUDE_FONTS
|
||||||
|
#include <pd/lithium/fonts.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
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) {
|
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);
|
TT::Scope st("LI_LoadTTF_" + path);
|
||||||
PixelHeight = height; // Set internel pixel height
|
auto font = PD::IO::LoadFile2Mem(path);
|
||||||
// Use NextPow2 to be able to use sizes between for example 16 and 32
|
LoadTTF(font, height);
|
||||||
// before it only was possible to use 8, 16, 32, 64 as size
|
}
|
||||||
int texszs = BitUtil::GetPow2(height * 16);
|
|
||||||
// Load stbtt
|
PD_LITHIUM_API void Font::pMakeAtlas(bool final, std::vector<u8> &font_tex,
|
||||||
|
int texszs, PD::Li::Texture::Ref tex) {
|
||||||
|
auto t =
|
||||||
|
Gfx::LoadTex(font_tex, texszs, texszs, Texture::RGBA32, Texture::LINEAR);
|
||||||
|
tex->CopyFrom(t);
|
||||||
|
Textures.push_back(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_LITHIUM_API void Font::LoadTTF(const std::vector<u8> &data, int height) {
|
||||||
|
/**
|
||||||
|
* Some additional Info:
|
||||||
|
* Removed the stbtt get bitmapbox as we dont need to place
|
||||||
|
* the glyps nicely in the tex. next step would be using the free
|
||||||
|
* space on the y axis to get mor glyphs inside
|
||||||
|
*/
|
||||||
|
PixelHeight = height;
|
||||||
|
int texszs = PD::BitUtil::GetPow2(height * 16);
|
||||||
|
if (texszs > 1024) {
|
||||||
|
texszs = 1024; // Max size
|
||||||
|
}
|
||||||
|
|
||||||
stbtt_fontinfo inf;
|
stbtt_fontinfo inf;
|
||||||
std::ifstream loader(path, std::ios::binary);
|
if (!stbtt_InitFont(&inf, data.data(), 0)) {
|
||||||
if (!loader.is_open()) return;
|
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);
|
|
||||||
// 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
|
|
||||||
// clang-format on
|
|
||||||
float scale = stbtt_ScaleForPixelHeight(&inf, PixelHeight);
|
float scale = stbtt_ScaleForPixelHeight(&inf, PixelHeight);
|
||||||
|
|
||||||
int ascent, descent, lineGap;
|
int ascent, descent, lineGap;
|
||||||
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
||||||
int baseline = static_cast<int>(ascent * scale);
|
int baseline = static_cast<int>(ascent * scale);
|
||||||
|
|
||||||
std::map<u32, int> buf_cache; // Cache to not render same codepoint tex twice
|
// Cache to not render same codepoint tex twice
|
||||||
|
std::map<u32, int> buf_cache;
|
||||||
|
|
||||||
/// Load Codepoints
|
std::vector<u8> font_tex(texszs * texszs * 4, 0);
|
||||||
auto tex = Texture::New();
|
auto tex = Texture::New();
|
||||||
fvec2 off;
|
fvec2 off;
|
||||||
for (u32 ii = 0x0000; ii < 0xFFFF; ii++) {
|
|
||||||
int i = stbtt_FindGlyphIndex(&inf, ii);
|
|
||||||
if (i == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (stbtt_IsGlyphEmpty(&inf, i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Codepoint c;
|
bool empty = true;
|
||||||
|
|
||||||
|
for (u32 ii = 0x0000; ii <= 0xFFFF; ii++) {
|
||||||
|
int gi = stbtt_FindGlyphIndex(&inf, ii);
|
||||||
|
if (gi == 0) continue;
|
||||||
|
if (stbtt_IsGlyphEmpty(&inf, gi)) continue;
|
||||||
|
|
||||||
int w = 0, h = 0, xo = 0, yo = 0;
|
int w = 0, h = 0, xo = 0, yo = 0;
|
||||||
unsigned char *bitmap =
|
unsigned char *bitmap =
|
||||||
stbtt_GetCodepointBitmap(&inf, scale, scale, i, &w, &h, &xo, &yo);
|
stbtt_GetCodepointBitmap(&inf, scale, scale, ii, &w, &h, &xo, &yo);
|
||||||
int x0, y0, x1, y1;
|
if (!bitmap || w <= 0 || h <= 0) {
|
||||||
stbtt_GetCodepointBitmapBox(&inf, i, scale, scale, &x0, &y0, &x1, &y1);
|
if (bitmap) free(bitmap);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if Codepoint exists as hash and if it is use its already written
|
|
||||||
// data
|
|
||||||
u32 hashed_map = IO::HashMemory(std::vector<u8>(bitmap, bitmap + (w * h)));
|
u32 hashed_map = IO::HashMemory(std::vector<u8>(bitmap, bitmap + (w * h)));
|
||||||
if (buf_cache.find(hashed_map) != buf_cache.end()) {
|
if (buf_cache.find(hashed_map) != buf_cache.end()) {
|
||||||
c = GetCodepoint(buf_cache[hashed_map]);
|
Codepoint c = GetCodepoint(buf_cache[hashed_map]);
|
||||||
c.pCodepoint = i;
|
c.pCodepoint = ii;
|
||||||
CodeMap[i] = c;
|
CodeMap[ii] = c;
|
||||||
free(bitmap);
|
free(bitmap);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
buf_cache[hashed_map] = i;
|
buf_cache[hashed_map] = ii;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next row
|
||||||
if (off.x + w > texszs) {
|
if (off.x + w > texszs) {
|
||||||
off.y += PixelHeight;
|
off.y += PixelHeight;
|
||||||
off.x = 0;
|
off.x = 0.0f;
|
||||||
|
}
|
||||||
|
// Bake cause we go out of the tex
|
||||||
|
if (off.y + PixelHeight > texszs) {
|
||||||
|
pMakeAtlas(false, font_tex, texszs, tex);
|
||||||
|
tex = Texture::New();
|
||||||
|
off = 0;
|
||||||
|
std::fill(font_tex.begin(), font_tex.end(), 0);
|
||||||
|
empty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set UV Data
|
// UVs & Codepoint
|
||||||
|
Codepoint c;
|
||||||
fvec4 uvs;
|
fvec4 uvs;
|
||||||
uvs.x = static_cast<float>(off.x) / texszs;
|
// cast the ints to floats and not the floats...
|
||||||
uvs.y = static_cast<float>(off.y) / texszs;
|
// dont know where my mind was when creating the code
|
||||||
uvs.z = static_cast<float>((off.x + w) / texszs);
|
uvs.x = off.x / static_cast<float>(texszs);
|
||||||
uvs.w = static_cast<float>((off.y + h) / texszs);
|
uvs.y = off.y / static_cast<float>(texszs);
|
||||||
|
uvs.z = (off.x + w) / static_cast<float>(texszs);
|
||||||
|
uvs.w = (off.y + h) / static_cast<float>(texszs);
|
||||||
|
// Flip if needed
|
||||||
if (Gfx::Flags() & LiBackendFlags_FlipUV_Y) {
|
if (Gfx::Flags() & LiBackendFlags_FlipUV_Y) {
|
||||||
uvs.y = 1.f - uvs.y;
|
uvs.y = 1.f - uvs.y;
|
||||||
uvs.w = 1.f - uvs.w;
|
uvs.w = 1.f - uvs.w;
|
||||||
@ -114,11 +157,13 @@ PD_LITHIUM_API void Font::LoadTTF(const std::string &path, int height) {
|
|||||||
c.Tex = tex;
|
c.Tex = tex;
|
||||||
c.Size = fvec2(w, h);
|
c.Size = fvec2(w, h);
|
||||||
c.Offset = baseline + yo;
|
c.Offset = baseline + yo;
|
||||||
|
c.pCodepoint = ii;
|
||||||
|
|
||||||
// Render glyph
|
|
||||||
for (int y = 0; y < h; ++y) {
|
for (int y = 0; y < h; ++y) {
|
||||||
for (int x = 0; x < w; ++x) {
|
for (int x = 0; x < w; ++x) {
|
||||||
int map_pos = (((off.y + y) * texszs + (off.x + x))) * 4;
|
int map_pos = ((static_cast<int>(off.y) + y) * texszs +
|
||||||
|
(static_cast<int>(off.x) + x)) *
|
||||||
|
4;
|
||||||
font_tex[map_pos + 0] = 255;
|
font_tex[map_pos + 0] = 255;
|
||||||
font_tex[map_pos + 1] = 255;
|
font_tex[map_pos + 1] = 255;
|
||||||
font_tex[map_pos + 2] = 255;
|
font_tex[map_pos + 2] = 255;
|
||||||
@ -126,27 +171,18 @@ PD_LITHIUM_API void Font::LoadTTF(const std::string &path, int height) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
empty = false;
|
||||||
|
CodeMap[ii] = c;
|
||||||
free(bitmap);
|
free(bitmap);
|
||||||
CodeMap[i] = c;
|
|
||||||
|
|
||||||
// Small Patch to avoid some possible artifacts
|
// offset by 1 (prevents visual glitches i had)
|
||||||
off.x += w + 1;
|
off.x += w + 1;
|
||||||
if (off.x + w > texszs) {
|
|
||||||
off.y += PixelHeight;
|
|
||||||
if (off.y + PixelHeight > texszs) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
off.x = 0;
|
|
||||||
|
if (!empty) {
|
||||||
|
pMakeAtlas(true, font_tex, texszs, tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Load the Texture and append to list
|
|
||||||
{
|
|
||||||
auto t = Gfx::LoadTex(font_tex, texszs, texszs, Texture::RGBA32,
|
|
||||||
Texture::LINEAR);
|
|
||||||
tex->CopyFrom(t);
|
|
||||||
}
|
|
||||||
Textures.push_back(tex);
|
|
||||||
}
|
|
||||||
|
|
||||||
PD_LITHIUM_API Font::Codepoint &Font::GetCodepoint(u32 cp) {
|
PD_LITHIUM_API Font::Codepoint &Font::GetCodepoint(u32 cp) {
|
||||||
// Check if codepoijt exist or return a static invalid one
|
// Check if codepoijt exist or return a static invalid one
|
||||||
@ -170,7 +206,7 @@ PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) {
|
|||||||
float lh = (float)PixelHeight * cfs;
|
float lh = (float)PixelHeight * cfs;
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
for (auto &it : wtext) {
|
for (auto &it : wtext) {
|
||||||
if (it == '\0') {
|
if (it == L'\0') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
@ -179,16 +215,16 @@ PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (it) {
|
switch (it) {
|
||||||
case '\n':
|
case L'\n':
|
||||||
res.y += lh;
|
res.y += lh;
|
||||||
res.x = std::max(res.x, x);
|
res.x = std::max(res.x, x);
|
||||||
x = 0.f;
|
x = 0.f;
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case L'\t':
|
||||||
x += 16 * cfs;
|
x += 16 * cfs;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case L' ':
|
||||||
x += 2 * cfs;
|
x += 16 * cfs;
|
||||||
// Fall trough here to get the same result as in
|
// Fall trough here to get the same result as in
|
||||||
// TextCommand if/else Section
|
// TextCommand if/else Section
|
||||||
default:
|
default:
|
||||||
@ -242,7 +278,8 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
|
|||||||
cmd->Tex = Tex;
|
cmd->Tex = Tex;
|
||||||
for (auto &jt : wline) {
|
for (auto &jt : wline) {
|
||||||
auto cp = GetCodepoint(jt);
|
auto cp = GetCodepoint(jt);
|
||||||
if ((cp.pInvalid && jt != '\n' && jt != '\t') && jt != '\r') {
|
if ((cp.pInvalid && jt != L' ' && jt != L'\n' && jt != L'\t') &&
|
||||||
|
jt != L'\r') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Tex != cp.Tex) {
|
if (Tex != cp.Tex) {
|
||||||
@ -251,14 +288,14 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
|
|||||||
Tex = cp.Tex;
|
Tex = cp.Tex;
|
||||||
cmd->Tex = Tex;
|
cmd->Tex = Tex;
|
||||||
}
|
}
|
||||||
if (jt == '\t') {
|
if (jt == L'\t') {
|
||||||
off.x += 16 * cfs;
|
off.x += 16 * cfs;
|
||||||
} else {
|
} else {
|
||||||
if (jt != ' ') {
|
if (jt != L' ') {
|
||||||
if (flags & LiTextFlags_Shaddow) {
|
if (flags & LiTextFlags_Shaddow) {
|
||||||
// Draw
|
// Draw
|
||||||
Rect rec = Renderer::PrimRect(
|
Rect rec = Renderer::PrimRect(
|
||||||
rpos + vec2(off.x + 1, off.x + (cp.Offset * cfs)) + 1,
|
rpos + vec2(off.x + 1, off.y + (cp.Offset * cfs)) + 1,
|
||||||
cp.Size * cfs, 0.f);
|
cp.Size * cfs, 0.f);
|
||||||
Renderer::CmdQuad(cmd.get(), rec, cp.SimpleUV, 0xff111111);
|
Renderer::CmdQuad(cmd.get(), rec, cp.SimpleUV, 0xff111111);
|
||||||
}
|
}
|
||||||
@ -266,10 +303,10 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
|
|||||||
Rect rec = Renderer::PrimRect(
|
Rect rec = Renderer::PrimRect(
|
||||||
rpos + off + fvec2(0, (cp.Offset * cfs)), cp.Size * cfs, 0.f);
|
rpos + off + fvec2(0, (cp.Offset * cfs)), cp.Size * cfs, 0.f);
|
||||||
Renderer::CmdQuad(cmd.get(), rec, cp.SimpleUV, color);
|
Renderer::CmdQuad(cmd.get(), rec, cp.SimpleUV, color);
|
||||||
} else {
|
|
||||||
off.x += 2 * cfs;
|
|
||||||
}
|
|
||||||
off.x += cp.Size.x * cfs + 2 * cfs;
|
off.x += cp.Size.x * cfs + 2 * cfs;
|
||||||
|
} else {
|
||||||
|
off.x += 16 * cfs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmds.push_back(std::move(cmd));
|
cmds.push_back(std::move(cmd));
|
||||||
|
48
pd/lithium/source/fonts.cpp
Normal file
48
pd/lithium/source/fonts.cpp
Normal 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
|
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
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
|
set(SRC
|
||||||
source/theme.cpp
|
source/theme.cpp
|
||||||
@ -25,4 +25,4 @@ else()
|
|||||||
pd_add_lib(pd-ui7 SRC_FILES ${SRC})
|
pd_add_lib(pd-ui7 SRC_FILES ${SRC})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(pd-ui7 PUBLIC pd-core)
|
target_link_libraries(pd-ui7 PUBLIC pd-lithium pd-core)
|
@ -27,7 +27,13 @@ SOFTWARE.
|
|||||||
namespace PD {
|
namespace PD {
|
||||||
namespace UI7 {
|
namespace UI7 {
|
||||||
PD_UI7_API void DynObj::Draw() { pRenFun(io, list, this); }
|
PD_UI7_API void DynObj::Draw() { pRenFun(io, list, this); }
|
||||||
PD_UI7_API void DynObj::HandleInput() {}
|
|
||||||
|
PD_UI7_API void DynObj::HandleInput() {
|
||||||
|
if (pInp) {
|
||||||
|
pInp(io, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PD_UI7_API void DynObj::Update() {}
|
PD_UI7_API void DynObj::Update() {}
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -28,7 +28,13 @@ namespace UI7 {
|
|||||||
PD_UI7_API void Label::Draw() {
|
PD_UI7_API void Label::Draw() {
|
||||||
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
// io->Ren->OnScreen(screen);
|
// io->Ren->OnScreen(screen);
|
||||||
|
if (pCLipRectUsed) {
|
||||||
|
list->PushClipRect(pClipRect);
|
||||||
|
}
|
||||||
list->DrawText(FinalPos(), label, io->Theme->Get(UI7Color_Text));
|
list->DrawText(FinalPos(), label, io->Theme->Get(UI7Color_Text));
|
||||||
|
if (pCLipRectUsed) {
|
||||||
|
list->PopClipRect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -26,6 +26,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
PD_UI7_API void UI7::IO::Update() {
|
PD_UI7_API void UI7::IO::Update() {
|
||||||
|
/** Todo: find out if we even still use the Drawlist regestry */
|
||||||
u64 current = OS::GetNanoTime();
|
u64 current = OS::GetNanoTime();
|
||||||
Delta = static_cast<float>(current - LastTime) / 1000000.f;
|
Delta = static_cast<float>(current - LastTime) / 1000000.f;
|
||||||
LastTime = current;
|
LastTime = current;
|
||||||
@ -37,5 +38,7 @@ PD_UI7_API void UI7::IO::Update() {
|
|||||||
DrawListRegestry.PushFront(
|
DrawListRegestry.PushFront(
|
||||||
Pair<UI7::ID, Li::DrawList::Ref>("CtxBackList", Back));
|
Pair<UI7::ID, Li::DrawList::Ref>("CtxBackList", Back));
|
||||||
// RegisterDrawList("CtxBackList", Back);
|
// RegisterDrawList("CtxBackList", Back);
|
||||||
|
NumIndices = FDL->pNumIndices;
|
||||||
|
NumVertices = FDL->pNumVertices;
|
||||||
}
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
@ -37,6 +37,7 @@ Menu::Menu(const ID &id, IO::Ref io) : pIO(io), pID(id) {
|
|||||||
PD_UI7_API void Menu::Label(const std::string &label) {
|
PD_UI7_API void Menu::Label(const std::string &label) {
|
||||||
// Layout API
|
// Layout API
|
||||||
auto r = Label::New(label, pIO);
|
auto r = Label::New(label, pIO);
|
||||||
|
r->SetClipRect(fvec4(pLayout->GetPosition(), pLayout->GetSize()));
|
||||||
pLayout->AddObject(r);
|
pLayout->AddObject(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +119,8 @@ PD_UI7_API void Menu::HandleFocus() {
|
|||||||
if (!pIsOpen) {
|
if (!pIsOpen) {
|
||||||
newarea = fvec4(pLayout->Pos, fvec2(pLayout->Size.x, TitleBarHeight));
|
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(), newarea) &&
|
||||||
!Li::Renderer::InBox(Hid::MousePos(),
|
!Li::Renderer::InBox(Hid::MousePos(),
|
||||||
pIO->InputHandler->FocusedMenuRect)) {
|
pIO->InputHandler->FocusedMenuRect)) {
|
||||||
@ -128,7 +130,10 @@ PD_UI7_API void Menu::HandleFocus() {
|
|||||||
pIO->InputHandler->FocusedMenuRect = newarea;
|
pIO->InputHandler->FocusedMenuRect = newarea;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Todo: (func name is self describing) */
|
||||||
PD_UI7_API void Menu::HandleScrolling() {}
|
PD_UI7_API void Menu::HandleScrolling() {}
|
||||||
|
|
||||||
PD_UI7_API void Menu::HandleTitlebarActions() {
|
PD_UI7_API void Menu::HandleTitlebarActions() {
|
||||||
// Collapse
|
// Collapse
|
||||||
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||||
@ -157,6 +162,21 @@ PD_UI7_API void Menu::HandleTitlebarActions() {
|
|||||||
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Resize logic
|
||||||
|
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||||
|
vec2 cpos = pLayout->Pos + pLayout->Size - fvec2(20);
|
||||||
|
|
||||||
|
// clr_close_btn = UI7Color_FrameBackground;
|
||||||
|
if (pIO->InputHandler->DragObject(UI7::ID(pID.GetName() + "rszs"),
|
||||||
|
fvec4(cpos, fvec2(20)))) {
|
||||||
|
fvec2 szs = pLayout->Size + (pIO->InputHandler->DragPosition -
|
||||||
|
pIO->InputHandler->DragLastPosition);
|
||||||
|
if (szs.x < 30) szs.x = 30;
|
||||||
|
if (szs.y < 30) szs.y = 30;
|
||||||
|
pLayout->Size = szs;
|
||||||
|
// clr_close_btn = UI7Color_FrameBackgroundHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Menu Movement
|
// Menu Movement
|
||||||
if (!(Flags & UI7MenuFlags_NoMove)) {
|
if (!(Flags & UI7MenuFlags_NoMove)) {
|
||||||
if (pIO->InputHandler->DragObject(
|
if (pIO->InputHandler->DragObject(
|
||||||
@ -167,13 +187,35 @@ PD_UI7_API void Menu::HandleTitlebarActions() {
|
|||||||
}
|
}
|
||||||
pLayout->Pos = pLayout->Pos + (pIO->InputHandler->DragPosition -
|
pLayout->Pos = pLayout->Pos + (pIO->InputHandler->DragPosition -
|
||||||
pIO->InputHandler->DragLastPosition);
|
pIO->InputHandler->DragLastPosition);
|
||||||
// Have no ViewPort Yet :(
|
// Keep Window In Viewport
|
||||||
// pLayout->Pos = std::clamp(pLayout->Pos, fvec2(10), fvec2(1270, 710));
|
// 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, pIO->CurrentViewPort.y,
|
||||||
|
pIO->CurrentViewPort.w - 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PD_UI7_API void Menu::DrawBaseLayout() {
|
PD_UI7_API void Menu::DrawBaseLayout() {
|
||||||
if (pIsOpen) {
|
if (pIsOpen) {
|
||||||
|
/** Resize Sym (Render on Top of Everything) */
|
||||||
|
if (!(Flags & UI7MenuFlags_NoResize)) {
|
||||||
|
Container::Ref r = DynObj::New(
|
||||||
|
[](IO::Ref io, Li::DrawList::Ref l, UI7::Container *self) {
|
||||||
|
l->Layer = 1;
|
||||||
|
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
|
||||||
|
l->PathAdd(self->FinalPos() + self->GetSize());
|
||||||
|
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
|
||||||
|
l->PathFill(io->Theme->Get(UI7Color_Button));
|
||||||
|
});
|
||||||
|
r->SetSize(
|
||||||
|
fvec2(pLayout->GetSize().x, pLayout->GetSize().y - TitleBarHeight));
|
||||||
|
r->SetPos(fvec2(0, TitleBarHeight));
|
||||||
|
pLayout->AddObjectEx(r,
|
||||||
|
UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Background */
|
||||||
Container::Ref r = DynObj::New([](IO::Ref io, Li::DrawList::Ref l,
|
Container::Ref r = DynObj::New([](IO::Ref io, Li::DrawList::Ref l,
|
||||||
UI7::Container *self) {
|
UI7::Container *self) {
|
||||||
l->Layer = 0;
|
l->Layer = 0;
|
||||||
@ -254,6 +296,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_UI7_API void Menu::Update() {
|
PD_UI7_API void Menu::Update() {
|
||||||
HandleFocus();
|
HandleFocus();
|
||||||
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||||
@ -262,5 +305,62 @@ PD_UI7_API void Menu::Update() {
|
|||||||
DrawBaseLayout();
|
DrawBaseLayout();
|
||||||
pLayout->Update();
|
pLayout->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_UI7_API bool Menu::BeginTreeNode(const ID &id) {
|
||||||
|
// As of some notes this should work:
|
||||||
|
auto n = pTreeNodes.find(id);
|
||||||
|
if (n == pTreeNodes.end()) {
|
||||||
|
pTreeNodes[id] = false;
|
||||||
|
n = pTreeNodes.find(id);
|
||||||
|
}
|
||||||
|
fvec2 pos = pLayout->Cursor;
|
||||||
|
fvec2 tdim = pIO->Font->GetTextBounds(id.GetName(), pIO->FontScale);
|
||||||
|
fvec2 szs = tdim + fvec2(pIO->ItemSpace.x + 10, 0);
|
||||||
|
|
||||||
|
if (n->second) {
|
||||||
|
pLayout->InitialCursorOffset += 10.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object
|
||||||
|
auto r =
|
||||||
|
DynObj::New([=, this](IO::Ref io, Li::DrawList::Ref l, Container *self) {
|
||||||
|
fvec2 ts = self->FinalPos() + fvec2(0, 7);
|
||||||
|
fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)};
|
||||||
|
if (n->second) {
|
||||||
|
float t = pl[0].y;
|
||||||
|
pl[0].y = pl[1].x;
|
||||||
|
pl[1].x = t;
|
||||||
|
}
|
||||||
|
l->DrawTriangleFilled(ts, ts + pl[0], ts + pl[1],
|
||||||
|
io->Theme->Get(UI7Color_FrameBackground));
|
||||||
|
|
||||||
|
l->DrawText(self->FinalPos() + fvec2(10 + io->ItemSpace.x, 0),
|
||||||
|
id.GetName(), io->Theme->Get(UI7Color_Text));
|
||||||
|
});
|
||||||
|
/** Yes this new function handler was created for tree nodes */
|
||||||
|
r->AddInputHandler([=, this](IO::Ref io, Container *self) {
|
||||||
|
if (io->InputHandler->DragObject(
|
||||||
|
ID(pID.GetName() + id.GetName()),
|
||||||
|
fvec4(self->FinalPos(), self->GetSize()))) {
|
||||||
|
if (io->InputHandler->DragReleased) {
|
||||||
|
n->second = !n->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
r->SetPos(pos);
|
||||||
|
r->SetSize(szs);
|
||||||
|
/** Use Add Object as it is faster */
|
||||||
|
pLayout->AddObject(r);
|
||||||
|
|
||||||
|
return n->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_UI7_API void UI7::Menu::EndTreeNode() {
|
||||||
|
pLayout->InitialCursorOffset.x -= 10.f;
|
||||||
|
pLayout->Cursor.x -= 10.f;
|
||||||
|
if (pLayout->InitialCursorOffset.x < 0.f) {
|
||||||
|
pLayout->InitialCursorOffset.x = 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
@ -21,9 +21,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <pd/ui7/ui7.hpp>
|
||||||
|
|
||||||
#include "pd/ui7/flags.hpp"
|
#include "pd/ui7/flags.hpp"
|
||||||
#include "pd/ui7/pd_p_api.hpp"
|
#include "pd/ui7/pd_p_api.hpp"
|
||||||
#include <pd/ui7/ui7.hpp>
|
|
||||||
|
#define UI7DHX32(x) std::format("{}: {:#08x}", #x, x)
|
||||||
|
#define UI7DTF(x) PD::Strings::FormatNanos(x)
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace UI7 {
|
namespace UI7 {
|
||||||
@ -32,8 +36,7 @@ PD_UI7_API std::string GetVersion(bool show_build) {
|
|||||||
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
|
s << ((UI7_VERSION >> 24) & 0xFF) << ".";
|
||||||
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
|
s << ((UI7_VERSION >> 16) & 0xFF) << ".";
|
||||||
s << ((UI7_VERSION >> 8) & 0xFF);
|
s << ((UI7_VERSION >> 8) & 0xFF);
|
||||||
if (show_build)
|
if (show_build) s << "-" << ((UI7_VERSION) & 0xFF);
|
||||||
s << "-" << ((UI7_VERSION) & 0xFF);
|
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,11 +66,289 @@ PD_UI7_API bool Context::BeginMenu(const ID &id, UI7MenuFlags flags,
|
|||||||
}
|
}
|
||||||
pCurrent = pGetOrCreateMenu(id);
|
pCurrent = pGetOrCreateMenu(id);
|
||||||
this->pCurrent->pIsShown = pShow;
|
this->pCurrent->pIsShown = pShow;
|
||||||
this->pIO->InputHandler->CurrentMenu = id;
|
if (pCurrent->pIsShown != nullptr) {
|
||||||
|
if (!*pCurrent->pIsShown) {
|
||||||
|
pCurrent = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Probably we dont even need Input Handling in this stage */
|
||||||
|
// this->pIO->InputHandler->CurrentMenu = id;
|
||||||
|
pCurrentMenus.push_back(id);
|
||||||
|
pCurrent->Flags = flags;
|
||||||
|
if (!pCurrent->pIsOpen) {
|
||||||
|
pCurrent = nullptr;
|
||||||
|
}
|
||||||
return pCurrent != nullptr;
|
return pCurrent != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_UI7_API void Context::Update() { pIO->Update(); }
|
PD_UI7_API void Context::EndMenu() {
|
||||||
|
/**
|
||||||
|
* Currently it would be a better wy to handle menus as follows
|
||||||
|
*
|
||||||
|
* The folowing context will generate a new menu as normally but instead
|
||||||
|
* of true or false we have m is false (nullptr) or true (some ptr returned)
|
||||||
|
* and after that it should simply out of scope
|
||||||
|
* (This would probably require some wrapper class to find out if m goes
|
||||||
|
* out of scope)
|
||||||
|
* ```cpp
|
||||||
|
* if(auto m = ui7->BeginMenu("Test")) {
|
||||||
|
* m->Label("Show some Text");
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
if (!pCurrent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pCurrent = nullptr;
|
||||||
|
// pIO->InputHandler->CurrentMenu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_UI7_API void Context::Update() {
|
||||||
|
/**
|
||||||
|
* Cause Commenting each line looks carbage...
|
||||||
|
* This function simply clears the FinalDrawList, Searches for Menu ID's in
|
||||||
|
* The sorted menu List from last frame to insert them as same order into
|
||||||
|
* the final list. After that it adds new menus to the begin to 'add' new
|
||||||
|
* menus on top. As final step the focused menu gets add to begin
|
||||||
|
* Then the menus update their Input and DraeList Generation in List Order
|
||||||
|
* and the DrawLists get Merged into the FDL in reverse Order. At end the List
|
||||||
|
* gets cleanup and io gets updated
|
||||||
|
*
|
||||||
|
* Very simple ...
|
||||||
|
*/
|
||||||
|
pIO->FDL->Clear();
|
||||||
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(),
|
||||||
|
pIO->InputHandler->FocusedMenu) == pCurrentMenus.end()) {
|
||||||
|
pIO->InputHandler->FocusedMenu = 0;
|
||||||
|
pIO->InputHandler->FocusedMenuRect = fvec4(0);
|
||||||
|
}
|
||||||
|
std::vector<u32> FinalList;
|
||||||
|
for (auto it : pDFO) {
|
||||||
|
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), it) !=
|
||||||
|
pCurrentMenus.end() &&
|
||||||
|
it != pIO->InputHandler->FocusedMenu) {
|
||||||
|
FinalList.push_back(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto it : pCurrentMenus) {
|
||||||
|
if (std::find(FinalList.begin(), FinalList.end(), it) == FinalList.end() &&
|
||||||
|
it != pIO->InputHandler->FocusedMenu) {
|
||||||
|
FinalList.push_back(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pMenus.count(pIO->InputHandler->FocusedMenu)) {
|
||||||
|
FinalList.insert(FinalList.begin(), pIO->InputHandler->FocusedMenu);
|
||||||
|
}
|
||||||
|
pDFO = FinalList;
|
||||||
|
for (auto &it : FinalList) {
|
||||||
|
this->pIO->InputHandler->CurrentMenu = it;
|
||||||
|
pMenus[it]->Update(); /** Render */
|
||||||
|
this->pIO->InputHandler->CurrentMenu = 0;
|
||||||
|
}
|
||||||
|
for (int i = (int)FinalList.size() - 1; i >= 0; i--) {
|
||||||
|
pIO->FDL->Merge(pMenus[FinalList[i]]->pLayout->GetDrawList());
|
||||||
|
}
|
||||||
|
pCurrentMenus.clear();
|
||||||
|
pIO->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_UI7_API void Context::AboutMenu(bool *show) {
|
||||||
|
if (BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) {
|
||||||
|
auto m = pCurrent;
|
||||||
|
m->Label("Palladium UI7 " + GetVersion());
|
||||||
|
m->Separator();
|
||||||
|
m->Label("(c) 2023-2025 René Amthor");
|
||||||
|
m->Label("UI7 is licensed under the MIT License.");
|
||||||
|
m->Label("See LICENSE for more information.");
|
||||||
|
static bool show_build;
|
||||||
|
m->Checkbox("Show Build Info", show_build);
|
||||||
|
if (show_build) {
|
||||||
|
m->SeparatorText("Build Info");
|
||||||
|
m->Label("Full Version -> " + GetVersion(true));
|
||||||
|
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 -> " +
|
||||||
|
Strings::GetCompilerVersion()); // + LibInfo::CompiledWith());
|
||||||
|
}
|
||||||
|
EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_UI7_API void Context::MetricsMenu(bool *show) {
|
||||||
|
if (BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling, show)) {
|
||||||
|
auto m = pCurrent;
|
||||||
|
m->Label("Palladium - UI7 " + GetVersion());
|
||||||
|
m->Separator();
|
||||||
|
m->Label(
|
||||||
|
std::format("Average {:.3f} ms/f ({:.1f} FPS)",
|
||||||
|
((float)pIO->DeltaStats->GetAverage() / 1000.f),
|
||||||
|
1000.f / ((float)pIO->DeltaStats->GetAverage() / 1000.f)));
|
||||||
|
m->Label(std::format("NumVertices: {}", pIO->NumVertices));
|
||||||
|
m->Label(std::format("NumIndices: {} -> {} Tris", pIO->NumIndices,
|
||||||
|
pIO->NumIndices / 3));
|
||||||
|
m->Label("Menus: " + std::to_string(pMenus.size()));
|
||||||
|
/** Section TimeTrace */
|
||||||
|
m->SeparatorText("TimeTrace");
|
||||||
|
if (m->BeginTreeNode("Traces (" + std::to_string(OS::GetTraceMap().size()) +
|
||||||
|
")")) {
|
||||||
|
for (auto &it : OS::GetTraceMap()) {
|
||||||
|
if (m->BeginTreeNode(it.second->GetID())) {
|
||||||
|
m->Label("Diff: " + UI7DTF(it.second->GetLastDiff()));
|
||||||
|
m->Label("Protocol Len: " +
|
||||||
|
std::to_string(it.second->GetProtocol()->GetLen()));
|
||||||
|
m->Label("Average: " +
|
||||||
|
UI7DTF(it.second->GetProtocol()->GetAverage()));
|
||||||
|
m->Label("Min: " + UI7DTF(it.second->GetProtocol()->GetMin()));
|
||||||
|
m->Label("Max: " + UI7DTF(it.second->GetProtocol()->GetMax()));
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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()) + ")")) {
|
||||||
|
for (auto &it : pMenus) {
|
||||||
|
if (m->BeginTreeNode(it.second->pID.GetName())) {
|
||||||
|
m->Label("Name: " + it.second->pID.GetName());
|
||||||
|
m->Label(std::format("Pos: {}", it.second->pLayout->GetPosition()));
|
||||||
|
m->Label(std::format("Size: {}", it.second->pLayout->GetSize()));
|
||||||
|
m->Label(std::format("WorkRect: {}", it.second->pLayout->WorkRect));
|
||||||
|
m->Label(std::format("Cursor: {}", it.second->pLayout->Cursor));
|
||||||
|
if (m->BeginTreeNode(
|
||||||
|
"ID Objects (" +
|
||||||
|
std::to_string(it.second->pLayout->IDObjects.size()) + ")")) {
|
||||||
|
for (auto &jt : it.second->pLayout->IDObjects) {
|
||||||
|
m->Label(std::format("{:08X}", jt->GetID()));
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
if (m->BeginTreeNode("Active Menus (" +
|
||||||
|
std::to_string(pCurrentMenus.size()) + ")")) {
|
||||||
|
for (auto &it : pCurrentMenus) {
|
||||||
|
if (m->BeginTreeNode(pMenus[it]->pID.GetName())) {
|
||||||
|
m->Label("Name: " + pMenus[it]->pID.GetName());
|
||||||
|
m->Label(std::format("Pos: {}", pMenus[it]->pLayout->GetPosition()));
|
||||||
|
m->Label(std::format("Size: {}", pMenus[it]->pLayout->GetSize()));
|
||||||
|
m->Label(std::format("WorkRect: {}", pMenus[it]->pLayout->WorkRect));
|
||||||
|
m->Label(std::format("Cursor: {}", pMenus[it]->pLayout->Cursor));
|
||||||
|
if (m->BeginTreeNode(
|
||||||
|
"ID Objects (" +
|
||||||
|
std::to_string(pMenus[it]->pLayout->IDObjects.size()) +
|
||||||
|
")")) {
|
||||||
|
for (auto &jt : pMenus[it]->pLayout->IDObjects) {
|
||||||
|
m->Label(std::format("{:08X}", jt->GetID()));
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
// Well this are Li Drawlists now and they do not count their stats (yet)
|
||||||
|
/*if (m->BeginTreeNode("DrawLists (" +
|
||||||
|
std::to_string(pIO->DrawListRegestry.Size()) + ")")) {
|
||||||
|
for (auto &it : pIO->DrawListRegestry) {
|
||||||
|
if (m->BeginTreeNode(it.First.GetName())) {
|
||||||
|
m->Label("Vertices: " + std::to_string(it.Second->NumVertices));
|
||||||
|
m->Label("Indices: " + std::to_string(it.Second->NumIndices));
|
||||||
|
m->Label("Base Layer: " + std::to_string(it.Second->Base));
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}*/
|
||||||
|
m->Label("io->Time: " + Strings::FormatMillis(pIO->Time->Get()));
|
||||||
|
m->Label(std::format("Delta: {:.3f}", pIO->Delta));
|
||||||
|
m->Label(std::format("Framerate: {:.2f}", pIO->Framerate));
|
||||||
|
m->Label(
|
||||||
|
std::format("Focused Menu: {:08X}", pIO->InputHandler->FocusedMenu));
|
||||||
|
m->Label(std::format("Dragged Object: {:08X}",
|
||||||
|
pIO->InputHandler->DraggedObject));
|
||||||
|
m->Label(std::format("DragTime: {:.2f}s",
|
||||||
|
pIO->InputHandler->DragTime->GetSeconds()));
|
||||||
|
m->Label(std::format("DragDestination: [{}]",
|
||||||
|
pIO->InputHandler->DragDestination));
|
||||||
|
m->Label(std::format("DragSource: [{}]", pIO->InputHandler->DragSourcePos));
|
||||||
|
m->Label(std::format("DragPos: [{}]", pIO->InputHandler->DragPosition));
|
||||||
|
m->Label(
|
||||||
|
std::format("DragLastPos: [{}]", pIO->InputHandler->DragLastPosition));
|
||||||
|
EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_UI7_API void UI7::Context::StyleEditor(bool *show) {
|
||||||
|
if (this->BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) {
|
||||||
|
auto m = pCurrent;
|
||||||
|
|
||||||
|
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
|
||||||
|
m->Separator();
|
||||||
|
m->DragData("MenuPadding", (float *)&pIO->MenuPadding, 2, 0.f, 100.f);
|
||||||
|
m->DragData("FramePadding", (float *)&pIO->FramePadding, 2, 0.f, 100.f);
|
||||||
|
m->DragData("ItemSpace", (float *)&pIO->ItemSpace, 2, 0.f, 100.f);
|
||||||
|
m->DragData("MinSliderSize", (float *)&pIO->MinSliderDragSize, 2, 1.f,
|
||||||
|
100.f);
|
||||||
|
m->DragData("OverScroll Modifier", &pIO->OverScrollMod, 1, 0.01f,
|
||||||
|
std::numeric_limits<float>::max(), 0.01f, 2);
|
||||||
|
m->Checkbox("Menu Border", pIO->ShowMenuBorder);
|
||||||
|
m->Checkbox("Frame Border", pIO->ShowFrameBorder);
|
||||||
|
m->SeparatorText("Theme");
|
||||||
|
if (m->Button("Dark")) {
|
||||||
|
UI7::Theme::Default(*pIO->Theme.get());
|
||||||
|
}
|
||||||
|
m->SameLine();
|
||||||
|
if (m->Button("Flashbang")) {
|
||||||
|
UI7::Theme::Flashbang(*pIO->Theme.get());
|
||||||
|
}
|
||||||
|
/// Small trick to print without prefix
|
||||||
|
#define ts(x) m->ColorEdit(std::string(#x).substr(9), &pIO->Theme->GetRef(x));
|
||||||
|
#define ts2(x) \
|
||||||
|
m->DragData(std::string(#x).substr(9), (u8 *)&pIO->Theme->GetRef(x), 4, \
|
||||||
|
(u8)0, (u8)255);
|
||||||
|
ts2(UI7Color_Background);
|
||||||
|
ts2(UI7Color_Border);
|
||||||
|
ts2(UI7Color_Button);
|
||||||
|
ts2(UI7Color_ButtonDead);
|
||||||
|
ts2(UI7Color_ButtonActive);
|
||||||
|
ts2(UI7Color_ButtonHovered);
|
||||||
|
ts2(UI7Color_Text);
|
||||||
|
ts2(UI7Color_TextDead);
|
||||||
|
ts2(UI7Color_Header);
|
||||||
|
ts2(UI7Color_HeaderDead);
|
||||||
|
ts2(UI7Color_Selector);
|
||||||
|
ts2(UI7Color_Checkmark);
|
||||||
|
ts2(UI7Color_FrameBackground);
|
||||||
|
ts2(UI7Color_FrameBackgroundHovered);
|
||||||
|
ts2(UI7Color_Progressbar);
|
||||||
|
ts2(UI7Color_ListEven);
|
||||||
|
ts2(UI7Color_ListOdd);
|
||||||
|
this->EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace UI7
|
} // namespace UI7
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
@ -17,6 +17,8 @@ void RoundedRect(PD::Li::DrawList::Ref l, PD::fvec2 p, PD::fvec2 s, PD::u32 clr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int v = 20;
|
int v = 20;
|
||||||
|
int TheScale = 1;
|
||||||
|
bool AboutOderSo = true;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
void *PD_INIT_DATA = nullptr;
|
void *PD_INIT_DATA = nullptr;
|
||||||
@ -55,7 +57,7 @@ int main() {
|
|||||||
#endif
|
#endif
|
||||||
List->SetFont(font);
|
List->SetFont(font);
|
||||||
PD::Image::Convert(img, img->RGBA);
|
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();
|
auto ui7 = PD::UI7::Context::New();
|
||||||
@ -63,16 +65,13 @@ int main() {
|
|||||||
ui7->AddViewPort(VpTop, PD::ivec4(0, 0, 400, 240));
|
ui7->AddViewPort(VpTop, PD::ivec4(0, 0, 400, 240));
|
||||||
ui7->UseViewPort(VpTop);
|
ui7->UseViewPort(VpTop);
|
||||||
ui7->pIO->Font = font;
|
ui7->pIO->Font = font;
|
||||||
PD::UI7::Menu::Ref menu = PD::UI7::Menu::New("Test", ui7->pIO);
|
|
||||||
bool open_haxx = true;
|
|
||||||
menu->pIsShown = &open_haxx;
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/** MainLoop */
|
/** MainLoop */
|
||||||
#ifndef __3DS__
|
#ifndef __3DS__
|
||||||
font->DefaultPixelHeight = 32;
|
font->DefaultPixelHeight = 32;
|
||||||
while (!glfwWindowShouldClose(win)) {
|
while (!glfwWindowShouldClose(win)) {
|
||||||
#else
|
#else
|
||||||
PD::Li::Gfx::pGfx->ViewPort = PD::ivec2(400, 240);
|
PD::Gfx::pGfx->ViewPort = PD::ivec2(400, 240);
|
||||||
while (aptMainLoop()) {
|
while (aptMainLoop()) {
|
||||||
#endif
|
#endif
|
||||||
PD::Hid::Update();
|
PD::Hid::Update();
|
||||||
@ -80,7 +79,11 @@ int main() {
|
|||||||
/** Auto ViewPort Resize */
|
/** Auto ViewPort Resize */
|
||||||
int wx, wy;
|
int wx, wy;
|
||||||
glfwGetWindowSize(win, &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
|
#endif
|
||||||
/** Rendering some stuff */
|
/** Rendering some stuff */
|
||||||
List->DrawSolid();
|
List->DrawSolid();
|
||||||
@ -90,7 +93,10 @@ int main() {
|
|||||||
RoundedRect(List, PD::fvec2(200, 50), 100, 0xffffffff,
|
RoundedRect(List, PD::fvec2(200, 50), 100, 0xffffffff,
|
||||||
((1 + std::sin(PD::OS::GetTime() / 1000.f)) * 0.5f) * 100.f);
|
((1 + std::sin(PD::OS::GetTime() / 1000.f)) * 0.5f) * 100.f);
|
||||||
List->DrawText(PD::fvec2(50, 190), "OK", 0xffffffff);
|
List->DrawText(PD::fvec2(50, 190), "OK", 0xffffffff);
|
||||||
List->DrawLine(PD::fvec2(0), PD::fvec2(1000, 600), 0xffffffff);
|
// List->DrawLine(PD::fvec2(0), PD::fvec2(1000, 600), 0xffffffff);
|
||||||
|
List->PathAdd(500);
|
||||||
|
List->PathAdd(550);
|
||||||
|
List->PathStroke(0xff00ffff, TheScale);
|
||||||
// List->DrawRectFilled(PD::fvec2(10, 10), PD::fvec2(1260, 700),
|
// List->DrawRectFilled(PD::fvec2(10, 10), PD::fvec2(1260, 700),
|
||||||
// 0xffffffff);
|
// 0xffffffff);
|
||||||
/** Draw text */
|
/** Draw text */
|
||||||
@ -103,10 +109,12 @@ int main() {
|
|||||||
PD::Hid::MousePos()) +
|
PD::Hid::MousePos()) +
|
||||||
"\nUI7 Version: " + PD::UI7::GetVersion(),
|
"\nUI7 Version: " + PD::UI7::GetVersion(),
|
||||||
0xff000000);
|
0xff000000);
|
||||||
ui7->pIO->InputHandler->CurrentMenu = menu->pID;
|
if (ui7->BeginMenu("Test")) {
|
||||||
if (menu->pIsOpen) {
|
auto menu = ui7->pCurrent;
|
||||||
menu->Label("Hello");
|
menu->Label("Hello");
|
||||||
menu->Label("World!");
|
menu->Label("World!");
|
||||||
|
menu->Checkbox("About Menu", AboutOderSo);
|
||||||
|
menu->DragData("Line", &TheScale);
|
||||||
if (menu->Button("Test")) {
|
if (menu->Button("Test")) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -117,9 +125,49 @@ int main() {
|
|||||||
menu->Label(
|
menu->Label(
|
||||||
std::format("Left: {}", PD::Hid::IsHeld(PD::Hid::Key::Touch)));
|
std::format("Left: {}", PD::Hid::IsHeld(PD::Hid::Key::Touch)));
|
||||||
menu->DragData("Value", &v, 1);
|
menu->DragData("Value", &v, 1);
|
||||||
|
ui7->EndMenu();
|
||||||
}
|
}
|
||||||
menu->Update();
|
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::Gfx::pGfx->VertexCounter));
|
||||||
|
menu->Label(std::format("Indices: {}", PD::Gfx::pGfx->IndexCounter));
|
||||||
|
ui7->EndMenu();
|
||||||
|
}
|
||||||
|
if (ui7->BeginMenu("#Debug (UI7)")) {
|
||||||
|
auto menu = ui7->pCurrent;
|
||||||
|
menu->Label(std::format("Framerate: {:.1f} [{:.2f}]", ui7->pIO->Framerate,
|
||||||
|
ui7->pIO->Delta));
|
||||||
|
menu->SeparatorText("Input");
|
||||||
|
menu->Label(std::format("FocusedMenu: #{:08X}",
|
||||||
|
ui7->pIO->InputHandler->FocusedMenu));
|
||||||
|
menu->Label(std::format("FocusedMenuRect: {}",
|
||||||
|
ui7->pIO->InputHandler->FocusedMenuRect));
|
||||||
|
menu->SeparatorText("Menu Order");
|
||||||
|
for (auto &it : ui7->pDFO) {
|
||||||
|
menu->Label(std::format("{}", ui7->pMenus[it]->pID.GetName()));
|
||||||
|
}
|
||||||
|
ui7->EndMenu();
|
||||||
|
}
|
||||||
|
if (ui7->BeginMenu("NoDebug")) {
|
||||||
|
auto m = ui7->pCurrent;
|
||||||
|
if (m->BeginTreeNode("Test")) {
|
||||||
|
m->Label("Hello World!");
|
||||||
|
if (m->BeginTreeNode("AnotherNode")) {
|
||||||
|
m->Label("Another Label!");
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
m->EndTreeNode();
|
||||||
|
}
|
||||||
|
m->Label("Yes another Label!");
|
||||||
|
ui7->EndMenu();
|
||||||
|
}
|
||||||
|
ui7->AboutMenu(&AboutOderSo);
|
||||||
|
ui7->MetricsMenu();
|
||||||
|
ui7->StyleEditor();
|
||||||
|
PD::TT::Beg("ui7->Update");
|
||||||
ui7->Update();
|
ui7->Update();
|
||||||
|
PD::TT::End("ui7->Update");
|
||||||
/** Render DrawData */
|
/** Render DrawData */
|
||||||
#ifdef __3DS__
|
#ifdef __3DS__
|
||||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||||
@ -127,12 +175,11 @@ int main() {
|
|||||||
C3D_RenderTargetClear(Top, C3D_CLEAR_ALL, 0x00000000, 0);
|
C3D_RenderTargetClear(Top, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||||
#endif
|
#endif
|
||||||
PD::TT::Beg("REN");
|
PD::TT::Beg("REN");
|
||||||
PD::Li::Gfx::NewFrame();
|
PD::Gfx::NewFrame();
|
||||||
PD::Li::Gfx::RenderDrawData(List->pDrawList);
|
PD::Gfx::RenderDrawData(List->pDrawList);
|
||||||
PD::Li::Gfx::RenderDrawData(menu->pLayout->GetDrawList()->pDrawList);
|
PD::Gfx::RenderDrawData(ui7->GetDrawData()->pDrawList);
|
||||||
/** Clear The List */
|
/** Clear The List */
|
||||||
List->Clear();
|
List->Clear();
|
||||||
menu->pLayout->GetDrawList()->pDrawList.clear();
|
|
||||||
PD::TT::End("REN");
|
PD::TT::End("REN");
|
||||||
#ifndef __3DS__
|
#ifndef __3DS__
|
||||||
/** Do OS Specifc Stuff (swapp buffers / window buttan events) */
|
/** Do OS Specifc Stuff (swapp buffers / window buttan events) */
|
||||||
|
@ -3,3 +3,4 @@ cmake_minimum_required(VERSION 3.22)
|
|||||||
add_subdirectory(lazyvec)
|
add_subdirectory(lazyvec)
|
||||||
add_subdirectory(ppam)
|
add_subdirectory(ppam)
|
||||||
add_subdirectory(pdlm)
|
add_subdirectory(pdlm)
|
||||||
|
add_subdirectory(pdfm)
|
@ -1,7 +1,18 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
project(lazyvec LANGUAGES CXX VERSION 1.0.0)
|
project(lazyvec LANGUAGES CXX VERSION 2.0.0)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED true)
|
||||||
|
|
||||||
add_executable(lazyvec
|
add_executable(lazyvec
|
||||||
source/main.cpp
|
source/main.cpp
|
||||||
|
|
||||||
|
source/lazyconstructors.cpp
|
||||||
|
source/lazyfuncs.cpp
|
||||||
|
source/lazyops.cpp
|
||||||
|
source/lazyoperation.cpp
|
||||||
|
source/lazytemplate.cpp
|
||||||
|
source/lazyswap.cpp
|
||||||
)
|
)
|
||||||
|
target_include_directories(lazyvec PUBLIC include)
|
||||||
|
19
tools/lazyvec/include/lazyvec.hpp
Normal file
19
tools/lazyvec/include/lazyvec.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/** Header for all source file functions */
|
||||||
|
|
||||||
|
#include <format> // yes this tool requires at least c++ 20
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace LVec {
|
||||||
|
const std::vector<std::string> elems = {"x", "y", "z", "w"};
|
||||||
|
std::string GenerateHeader(int n);
|
||||||
|
std::string MakeOperationFor(char op, int n);
|
||||||
|
std::string GenericOperations(int n);
|
||||||
|
std::string MakeFunctions(int n);
|
||||||
|
std::string MakeSwap(int n);
|
||||||
|
std::string MakeConstructors(int n);
|
||||||
|
} // namespace LVec
|
75
tools/lazyvec/source/lazyconstructors.cpp
Normal file
75
tools/lazyvec/source/lazyconstructors.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <lazyvec.hpp>
|
||||||
|
|
||||||
|
constexpr std::string_view _construct = R"text(
|
||||||
|
constexpr vec{0}() : {1} {{}}
|
||||||
|
template <typename T1>
|
||||||
|
constexpr vec{0}(T1 v) {{
|
||||||
|
{2}
|
||||||
|
}}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
constexpr vec{0}(const vec{0}<T1>& v) {{
|
||||||
|
{3}
|
||||||
|
}}
|
||||||
|
|
||||||
|
constexpr explicit vec{0}({4}) : {5} {{}}{6}
|
||||||
|
)text";
|
||||||
|
|
||||||
|
constexpr std::string_view _extended3 = R"(
|
||||||
|
|
||||||
|
// Extended Constructors
|
||||||
|
template <typename T1>
|
||||||
|
constexpr explicit vec3(const vec2<T1>& xy, T1 z) {{
|
||||||
|
x = (T)xy.x;
|
||||||
|
y = (T)xy.y;
|
||||||
|
this->z = (T)z;
|
||||||
|
}}
|
||||||
|
)";
|
||||||
|
|
||||||
|
constexpr std::string_view _extended4 = R"(
|
||||||
|
|
||||||
|
// Extended Constructors
|
||||||
|
template <typename T1>
|
||||||
|
constexpr explicit vec4(const vec2<T1>& xy, const vec2<T1>& zw) {{
|
||||||
|
x = (T)xy.x;
|
||||||
|
y = (T)xy.y;
|
||||||
|
z = (T)zw.x;
|
||||||
|
w = (T)zw.y;
|
||||||
|
}}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
constexpr explicit vec4(const vec3<T1>& xyz, T1 w) {{
|
||||||
|
x = (T)xyz.x;
|
||||||
|
y = (T)xyz.y;
|
||||||
|
z = (T)xyz.z;
|
||||||
|
this->w = (T)w;
|
||||||
|
}}
|
||||||
|
)";
|
||||||
|
|
||||||
|
namespace LVec {
|
||||||
|
std::string MakeConstructors(int n) {
|
||||||
|
std::stringstream s1, s2, s3, s4, s5;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
s1 << elems[i] << "(0)";
|
||||||
|
s2 << " " << elems[i] << " = (T)v;";
|
||||||
|
s3 << " " << elems[i] << " = (T)v." << elems[i] << ";";
|
||||||
|
s4 << "T " << elems[i];
|
||||||
|
s5 << elems[i] << "(" << elems[i] << ")";
|
||||||
|
if (i != n - 1) {
|
||||||
|
s1 << ", ";
|
||||||
|
s2 << std::endl;
|
||||||
|
s3 << std::endl;
|
||||||
|
s4 << ", ";
|
||||||
|
s5 << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string extended;
|
||||||
|
if (n == 3) {
|
||||||
|
extended = _extended3;
|
||||||
|
} else if (n == 4) {
|
||||||
|
extended = _extended4;
|
||||||
|
}
|
||||||
|
return std::format(_construct, n, s1.str(), s2.str(), s3.str(), s4.str(),
|
||||||
|
s5.str(), extended);
|
||||||
|
}
|
||||||
|
} // namespace LVec
|
50
tools/lazyvec/source/lazyfuncs.cpp
Normal file
50
tools/lazyvec/source/lazyfuncs.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <lazyvec.hpp>
|
||||||
|
|
||||||
|
constexpr std::string_view _funcs = R"text(
|
||||||
|
double Len() const {{ return std::sqrt(SqLen()); }}
|
||||||
|
double SqLen() const {{ return {1}; }}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
double Distance(const vec{0}<T1>& v) const {{
|
||||||
|
return (*this - v).Len();
|
||||||
|
}}
|
||||||
|
|
||||||
|
vec{0}<T> Normalize() const {{
|
||||||
|
double l = Len();
|
||||||
|
if(l == 0) {{
|
||||||
|
return *this;
|
||||||
|
}}
|
||||||
|
return *this / (T)l;
|
||||||
|
}}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
T Dot(const vec{0}<T1>&v) const {{
|
||||||
|
return {2};
|
||||||
|
}}
|
||||||
|
)text";
|
||||||
|
|
||||||
|
constexpr std::string_view _cross = R"text(
|
||||||
|
template <typename T1>
|
||||||
|
vec3<T> Cross(const vec3<T1>& v) const {
|
||||||
|
return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||||||
|
}
|
||||||
|
)text";
|
||||||
|
|
||||||
|
namespace LVec {
|
||||||
|
std::string MakeFunctions(int n) {
|
||||||
|
std::stringstream s1, s2;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
s1 << elems[i] << " * " << elems[i];
|
||||||
|
s2 << elems[i] << " * (T)v." << elems[i];
|
||||||
|
if (i != n - 1) {
|
||||||
|
s1 << " + ";
|
||||||
|
s2 << " + ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string ret = std::format(_funcs, n, s1.str(), s2.str());
|
||||||
|
if (n == 3) {
|
||||||
|
ret += _cross;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} // namespace LVec
|
47
tools/lazyvec/source/lazyoperation.cpp
Normal file
47
tools/lazyvec/source/lazyoperation.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include <lazyvec.hpp>
|
||||||
|
|
||||||
|
constexpr std::string_view _op_template = R"text(
|
||||||
|
template <typename T1>
|
||||||
|
vec{0}<T>& operator{1}=(T1 v) {{
|
||||||
|
{2}
|
||||||
|
return *this;
|
||||||
|
}}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
vec{0}<T>& operator{1}=(const vec{0}<T1>& v) {{
|
||||||
|
{3}
|
||||||
|
return *this;
|
||||||
|
}}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
vec{0}<T> operator{1}(T1 v) const {{
|
||||||
|
return vec{0}<T>({4});
|
||||||
|
}}
|
||||||
|
|
||||||
|
template <typename T1>
|
||||||
|
vec{0}<T> operator{1}(const vec{0}<T1>& v) const {{
|
||||||
|
return vec{0}<T>({5});
|
||||||
|
}}
|
||||||
|
)text";
|
||||||
|
|
||||||
|
namespace LVec {
|
||||||
|
std::string MakeOperationFor(char op, int n) {
|
||||||
|
const std::string& toff = " ";
|
||||||
|
// Create for streams for the operations functions
|
||||||
|
std::stringstream s1, s2, s3, s4;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
s1 << toff << elems[i] << " " << op << "= (T)v;";
|
||||||
|
s2 << toff << elems[i] << " " << op << "= (T)v." << elems[i] << ";";
|
||||||
|
s3 << elems[i] << " " << op << " (T)v";
|
||||||
|
s4 << elems[i] << " " << op << " (T)v." << elems[i];
|
||||||
|
if (i != n - 1) {
|
||||||
|
s1 << std::endl;
|
||||||
|
s2 << std::endl;
|
||||||
|
s3 << ", ";
|
||||||
|
s4 << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::format(_op_template, n, op, s1.str(), s2.str(), s3.str(),
|
||||||
|
s4.str());
|
||||||
|
}
|
||||||
|
} // namespace LVec
|
30
tools/lazyvec/source/lazyops.cpp
Normal file
30
tools/lazyvec/source/lazyops.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include <lazyvec.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diffrence between lazyoperation.cpp and lazyops.cpp ?
|
||||||
|
* One is for Operators with an input sym like +, -, * or /
|
||||||
|
* the other (this) is for generic operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
constexpr std::string_view _generic_ops = R"text(
|
||||||
|
vec{0} operator-() const {{ return vec{0}({1}); }}
|
||||||
|
template <typename T1>
|
||||||
|
bool operator==(const vec{0}<T1>& v) const {{ return {2}; }}
|
||||||
|
template <typename T1>
|
||||||
|
bool operator!=(const vec{0}<T1>& v) const {{ return !(*this == v); }}
|
||||||
|
)text";
|
||||||
|
|
||||||
|
namespace LVec {
|
||||||
|
std::string GenericOperations(int n) {
|
||||||
|
std::stringstream s1, s2;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
s1 << "-" << elems[i];
|
||||||
|
s2 << elems[i] << " == (T)v." << elems[i];
|
||||||
|
if (i != n - 1) {
|
||||||
|
s1 << ", ";
|
||||||
|
s2 << " && ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::format(_generic_ops, n, s1.str(), s2.str());
|
||||||
|
}
|
||||||
|
} // namespace LVec
|
25
tools/lazyvec/source/lazyswap.cpp
Normal file
25
tools/lazyvec/source/lazyswap.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <lazyvec.hpp>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
namespace LVec {
|
||||||
|
std::string MakeSwap(int n) {
|
||||||
|
std::stringstream s;
|
||||||
|
std::unordered_set<std::string> done;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
std::string a = elems[i];
|
||||||
|
std::string b = elems[j];
|
||||||
|
/** Make sure we generate nothing twice */
|
||||||
|
if (a == b || done.count(b + a)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s << " void Swap" << (char)toupper(a[0]) << (char)toupper(b[0])
|
||||||
|
<< "() {\n";
|
||||||
|
s << " T t = " << a << ";\n " << a << " = " << b << ";\n";
|
||||||
|
s << " " << b << " = t;\n }\n";
|
||||||
|
done.insert(a + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
} // namespace LVec
|
77
tools/lazyvec/source/lazytemplate.cpp
Normal file
77
tools/lazyvec/source/lazytemplate.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include <lazyvec.hpp>
|
||||||
|
|
||||||
|
constexpr std::string_view _template = R"text(#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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This file is generated by lazyvec 2.0.0
|
||||||
|
|
||||||
|
#include <pd/core/common.hpp>
|
||||||
|
{7}
|
||||||
|
|
||||||
|
namespace PD {{
|
||||||
|
template <typename T>
|
||||||
|
class vec{0} {{
|
||||||
|
public:
|
||||||
|
{1}
|
||||||
|
// Constructors
|
||||||
|
{2}
|
||||||
|
// Operations
|
||||||
|
{3}
|
||||||
|
// Generic Operations
|
||||||
|
{4}
|
||||||
|
// Functions
|
||||||
|
{5}
|
||||||
|
// Swap Functions
|
||||||
|
{6}
|
||||||
|
}};
|
||||||
|
using fvec{0} = vec{0}<float>;
|
||||||
|
using ivec{0} = vec{0}<int>;
|
||||||
|
using dvec{0} = vec{0}<double>;
|
||||||
|
}} // namespace PD
|
||||||
|
)text";
|
||||||
|
|
||||||
|
namespace LVec {
|
||||||
|
std::string GenerateHeader(int n) {
|
||||||
|
std::stringstream ops, data, extended;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
data << "T " << elems[i] << ";" << std::endl;
|
||||||
|
}
|
||||||
|
ops << MakeOperationFor('+', n);
|
||||||
|
ops << MakeOperationFor('-', n);
|
||||||
|
ops << MakeOperationFor('*', n);
|
||||||
|
ops << MakeOperationFor('/', n);
|
||||||
|
if (n > 2) {
|
||||||
|
extended << "// Extended includes (rename if you use other filenames/paths)"
|
||||||
|
<< std::endl;
|
||||||
|
extended << "#include <vec2.hpp>" << std::endl;
|
||||||
|
if (n == 4) {
|
||||||
|
extended << "#include <vec3.hpp>" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::format(_template, n, data.str(), MakeConstructors(n), ops.str(),
|
||||||
|
GenericOperations(n), MakeFunctions(n), MakeSwap(n),
|
||||||
|
extended.str());
|
||||||
|
}
|
||||||
|
} // namespace LVec
|
@ -21,194 +21,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
const char* license_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.
|
|
||||||
*/
|
|
||||||
)";
|
|
||||||
|
|
||||||
const std::vector<std::string> elems = {"x", "y", "z", "w"};
|
|
||||||
|
|
||||||
void MakeOperationFor(std::fstream& off, char op, int n) {
|
|
||||||
off << " template <typename T1>\n";
|
|
||||||
off << " vec" << n << "<T>& operator" << op << "=(T1 v) {\n";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << " " << elems[i] << " " << op << "= (T)v;\n";
|
|
||||||
}
|
|
||||||
off << " return *this;\n";
|
|
||||||
off << " }\n\n";
|
|
||||||
|
|
||||||
off << " template <typename T1>\n";
|
|
||||||
off << " vec" << n << "<T>& operator" << op << "=(const vec" << n
|
|
||||||
<< "<T1>& v) {\n";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << " " << elems[i] << " " << op << "= (T)v." << elems[i] << ";\n";
|
|
||||||
}
|
|
||||||
off << " return *this;\n";
|
|
||||||
off << " }\n\n";
|
|
||||||
|
|
||||||
off << " template <typename T1>\n";
|
|
||||||
off << " vec" << n << "<T> operator" << op << "(T1 v) const {\n";
|
|
||||||
off << " return vec" << n << "<T>(";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (i > 0) off << ", ";
|
|
||||||
off << elems[i] << " " << op << " (T)v";
|
|
||||||
}
|
|
||||||
off << ");\n }\n\n";
|
|
||||||
|
|
||||||
off << " template <typename T1>\n";
|
|
||||||
off << " vec" << n << "<T> operator" << op << "(const vec" << n
|
|
||||||
<< "<T1>& v) const {\n";
|
|
||||||
off << " return vec" << n << "<T>(";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (i > 0) off << ", ";
|
|
||||||
off << elems[i] << " " << op << " (T)v." << elems[i];
|
|
||||||
}
|
|
||||||
off << ");\n }\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void SwapHaxx(std::fstream& off, int n) {
|
|
||||||
std::unordered_set<std::string> done;
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
for (int j = 0; j < n; j++) {
|
|
||||||
std::string a = elems[i];
|
|
||||||
std::string b = elems[j];
|
|
||||||
/** Make sure we generate nothing twice */
|
|
||||||
if (a == b || done.count(b + a)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
off << " void Swap" << (char)toupper(a[0]) << (char)toupper(b[0])
|
|
||||||
<< "() {\n";
|
|
||||||
off << " T t = " << a << ";\n " << a << " = " << b << ";\n";
|
|
||||||
off << " " << b << " = t;\n }\n";
|
|
||||||
done.insert(a + b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateVec(int n) {
|
|
||||||
if (n < 2 || n > 4) {
|
|
||||||
std::cout << "Only 2 to 4 supported.\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::fstream off("vec" + std::to_string(n) + ".hpp", std::ios::out);
|
|
||||||
|
|
||||||
off << "#pragma once\n" << std::endl;
|
|
||||||
off << license_text << std::endl;
|
|
||||||
off << "// This file is generated by lazyvec\n#include "
|
|
||||||
"<pd/core/common.hpp>\n\n";
|
|
||||||
off << "namespace PD {" << std::endl;
|
|
||||||
off << "template <typename T>\nclass vec" << n << " {\npublic:\n";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << " T " << elems[i] << ";\n";
|
|
||||||
}
|
|
||||||
off << "\n";
|
|
||||||
off << " vec" << n << "(): ";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
off << ", ";
|
|
||||||
}
|
|
||||||
off << elems[i] << "(0)";
|
|
||||||
}
|
|
||||||
off << " {}" << std::endl;
|
|
||||||
// Magic Construtor (support for anytype vec)
|
|
||||||
off << " template <typename T1>\n";
|
|
||||||
off << " explicit vec" << n << "(T1 v) {\n";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << " " << elems[i] << " = (T)v;\n";
|
|
||||||
}
|
|
||||||
off << " }\n\n";
|
|
||||||
|
|
||||||
// Magic Constructor 2
|
|
||||||
off << " template <typename T1>\n";
|
|
||||||
off << " explicit vec" << n << "(vec" << n << "<T1> v) {\n";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << " " << elems[i] << " = (T)v. " << elems[i] << ";\n";
|
|
||||||
}
|
|
||||||
off << " }\n\n";
|
|
||||||
|
|
||||||
off << " vec" << n << "(";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (i > 0) off << ", ";
|
|
||||||
off << "T " << elems[i];
|
|
||||||
}
|
|
||||||
off << ") : ";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (i > 0) off << ", ";
|
|
||||||
off << elems[i] << "(" << elems[i] << ")";
|
|
||||||
}
|
|
||||||
off << " {}\n\n";
|
|
||||||
|
|
||||||
MakeOperationFor(off, '+', n);
|
|
||||||
MakeOperationFor(off, '-', n);
|
|
||||||
MakeOperationFor(off, '*', n);
|
|
||||||
MakeOperationFor(off, '/', n);
|
|
||||||
|
|
||||||
off << " vec" << n << " operator-() const {return vec" << n << "(";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << "-" << elems[i];
|
|
||||||
if (i != n - 1) {
|
|
||||||
off << ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
off << ");}\n\n";
|
|
||||||
|
|
||||||
off << " bool operator==(const vec" << n << "& v) const { return ";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << elems[i] << " == v." << elems[i];
|
|
||||||
if (i != n - 1) {
|
|
||||||
off << " && ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
off << ";}\n";
|
|
||||||
off << " bool operator!=(const vec" << n
|
|
||||||
<< "&v) const { return !(*this == v); }\n\n";
|
|
||||||
|
|
||||||
off << " double Len() const {return std::sqrt(SqLen()); }\n";
|
|
||||||
off << " double SqLen() const { return ";
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
off << elems[i] << " * " << elems[i];
|
|
||||||
if (i != n - 1) {
|
|
||||||
off << " + ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
off << "; }\n\n";
|
|
||||||
|
|
||||||
SwapHaxx(off, n);
|
|
||||||
|
|
||||||
off << "};\n";
|
|
||||||
off << "using fvec" << n << " = vec" << n << "<float>;\n";
|
|
||||||
off << "using dvec" << n << " = vec" << n << "<double>;\n";
|
|
||||||
off << "using ivec" << n << " = vec" << n << "<int>;\n";
|
|
||||||
off << "}\n";
|
|
||||||
off.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Yet another Stupid Code generation tool
|
* Yet another Stupid Code generation tool
|
||||||
* Why ?
|
* Why ?
|
||||||
@ -216,11 +28,21 @@ void GenerateVec(int n) {
|
|||||||
* manually writeup vec2 to vec4
|
* manually writeup vec2 to vec4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <lazyvec.hpp>
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
std::cout << argv[0] << " <num (2 to 4)>" << std::endl;
|
std::cout << argv[0] << " <num (2 to 4)>" << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
GenerateVec(std::stoi(argv[1]));
|
int l = std::stoi(argv[1]);
|
||||||
|
if (l < 2 || l > 4) {
|
||||||
|
std::cout << argv[0] << " <num (2 to 4)>" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
std::ofstream f("vec" + std::to_string(l) + ".hpp");
|
||||||
|
f << LVec::GenerateHeader(l);
|
||||||
|
f.close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
11
tools/pdfm/CMakeLists.txt
Normal file
11
tools/pdfm/CMakeLists.txt
Normal 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
167
tools/pdfm/source/main.cpp
Normal 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;
|
||||||
|
}
|
@ -28,7 +28,9 @@ SOFTWARE.
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
const char* license_text = R"(/*
|
constexpr std::string_view ppa_text = R"(#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
MIT License
|
MIT License
|
||||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||||
|
|
||||||
@ -50,35 +52,34 @@ 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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
)";
|
|
||||||
|
|
||||||
constexpr std::string_view ppa_text =
|
/** Generated with ppam */
|
||||||
"#pragma once\n\n{0}\n"
|
|
||||||
"/** Generated with ppam */\n\n"
|
#ifdef _WIN32 // Windows (MSVC Tested)
|
||||||
"#ifdef _WIN32 // Windows (MSVC Tested)\n"
|
#ifdef {0}_BUILD_SHARED
|
||||||
"#ifdef {1}_BUILD_SHARED\n"
|
#define {0}_API __declspec(dllexport)
|
||||||
"#define {1}_API __declspec(dllexport)\n"
|
#else
|
||||||
"#else\n"
|
#define {0}_API __declspec(dllimport)
|
||||||
"#define {1}_API __declspec(dllimport)\n"
|
#endif
|
||||||
"#endif\n"
|
#elif defined(__APPLE__) // macOS (untested yet)
|
||||||
"#elif defined(__APPLE__) // macOS (untested yet)\n"
|
#ifdef {0}_BUILD_SHARED
|
||||||
"#ifdef {1}_BUILD_SHARED\n"
|
#define {0}_API __attribute__((visibility("default")))
|
||||||
"#define {1}_API __attribute__((visibility(\"default\")))\n"
|
#else
|
||||||
"#else\n"
|
#define {0}_API
|
||||||
"#define {1}_API\n"
|
#endif
|
||||||
"#endif\n"
|
#elif defined(__linux__) // Linux (untested yet)
|
||||||
"#elif defined(__linux__) // Linux (untested yet)\n"
|
#ifdef {0}_BUILD_SHARED
|
||||||
"#ifdef {1}_BUILD_SHARED\n"
|
#define {0}_API __attribute__((visibility("default")))
|
||||||
"#define {1}_API __attribute__((visibility(\"default\")))\n"
|
#else
|
||||||
"#else\n"
|
#define {0}_API
|
||||||
"#define {1}_API\n"
|
#endif
|
||||||
"#endif\n"
|
#elif defined(__3DS__) // 3ds Specific
|
||||||
"#elif defined(__3DS__) // 3ds Specific\n"
|
// Only Static supported
|
||||||
"// Only Static supported\n"
|
#define {0}_API
|
||||||
"#define {1}_API\n"
|
#else
|
||||||
"#else\n"
|
#define {0}_API
|
||||||
"#define {1}_API\n"
|
#endif
|
||||||
"#endif\n";
|
)";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tool to generate the `pd_p_api.hpp` (Palladium Platform Api)
|
* Tool to generate the `pd_p_api.hpp` (Palladium Platform Api)
|
||||||
@ -91,7 +92,7 @@ int main(int argc, char* argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
std::fstream off("pd_p_api.hpp", std::ios::out);
|
std::fstream off("pd_p_api.hpp", std::ios::out);
|
||||||
off << std::format(ppa_text, license_text, argv[1]);
|
off << std::format(ppa_text, argv[1]);
|
||||||
off.close();
|
off.close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Reference in New Issue
Block a user