2 Commits

Author SHA1 Message Date
6c38aa6f21 Adding and fixing stuff
- Fix HexChar2Int
- Remove some devisions in tween engine
- Add PathAdd function for x, y seperated instead of fvec2
- Readd text wrapping (rd7-palladium maybe)
2025-12-15 22:16:19 +01:00
f19c947fc3 Road to 0.6.0
- readd the c++ linear allocator for 3ds
- start switching from PD::Vec to std::vector
- Add Color::Hex as constexpr for compiletime color converts
- Add FNV Hasing functions
- Make UI7 ids be able to be generated at compile time
- Added a Throw Function (for whatever)
- Added HexCHar2Int (replaces the lookup table)
- Made u128 fully constexpr
2025-12-10 19:02:54 +01:00
27 changed files with 316 additions and 135 deletions

View File

@@ -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.1) project(palladium LANGUAGES C CXX VERSION 0.6.0)
# 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)

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2024 - 2025 tobid7 Copyright (c) 2024 - 2025 René Amthor tobid7
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
project(pd-3ds LANGUAGES CXX VERSION 0.5.0) project(pd-3ds LANGUAGES CXX VERSION 0.6.0)
set(SRC set(SRC
source/bknd-gfx.cpp source/bknd-gfx.cpp

View File

@@ -27,19 +27,10 @@ SOFTWARE.
#include <3ds.h> #include <3ds.h>
#include <citro3d.h> #include <citro3d.h>
#include <pd-3ds/linearAllocator.hpp>
#include <pd/lithium/lithium.hpp> #include <pd/lithium/lithium.hpp>
namespace PD { namespace PD {
template <typename T>
class LinearAlloc : public Allocator<T> {
public:
LinearAlloc() = default;
~LinearAlloc() = default;
/** Never forget the sizeof(T) again (most painful bug i created) */
T* Allocate(size_t n) override { return (T*)linearAlloc(n * sizeof(T)); }
void Deallocate(T* ptr) { linearFree(ptr); }
};
class GfxC3D : public GfxDriver { class GfxC3D : public GfxDriver {
public: public:
GfxC3D() : GfxDriver("Citro3D") {} GfxC3D() : GfxDriver("Citro3D") {}
@@ -59,8 +50,8 @@ 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<Li::Vertex, LinearAlloc<Li::Vertex>> VertexBuffer; std::vector<Li::Vertex, LinearAllocator<Li::Vertex>> VertexBuffer;
Vec<u16, LinearAlloc<u16>> IndexBuffer; std::vector<u16, LinearAllocator<u16>> IndexBuffer;
int pLocProjection = 0; int pLocProjection = 0;
DVLB_s* ShaderCode; DVLB_s* ShaderCode;
shaderProgram_s Shader; shaderProgram_s Shader;

View File

@@ -0,0 +1,49 @@
#pragma once
#include <3ds.h>
#include <pd/core/common.hpp>
// Custom C++ Allocator class to interface with libctru linear heap memory
// based on this guide:
// https://johnfarrier.com/custom-allocators-in-c-high-performance-memory-management/
namespace PD {
template <typename T>
class LinearAllocator {
public:
using value_type = T;
LinearAllocator() noexcept = default;
template <typename U>
constexpr LinearAllocator(const LinearAllocator<U>&) noexcept {}
T* allocate(std::size_t n) {
if (n > max_size()) {
throw std::runtime_error("[PD] LinearAllocator: Bad alloc!");
}
return static_cast<T*>(linearAlloc(n * sizeof(T)));
}
void deallocate(T* p, std::size_t) noexcept { linearFree(p); }
template <class U, class... Args>
void construct(U* p, Args&&... args) {
::new ((void*)p) U(std::forward<Args>(args)...);
}
template <class U>
void destroy(U* p) {
p->~U();
}
friend bool operator==(const LinearAllocator, const LinearAllocator) {
return true;
}
friend bool operator!=(const LinearAllocator, const LinearAllocator) {
return false;
}
// Use linearSpace free as max_size to not allocate out of bounds
// or to b eable to see a crash report screen.
size_t max_size() const noexcept { return linearSpaceFree(); }
};
} // namespace PD

View File

@@ -93,8 +93,8 @@ int GetBPP(Li::Texture::Type type) {
} }
void GfxC3D::Init() { void GfxC3D::Init() {
VertexBuffer.Resize(4 * 8192); VertexBuffer.resize(4 * 8192);
IndexBuffer.Resize(6 * 8192); IndexBuffer.resize(6 * 8192);
Flags |= LiBackendFlags_FlipUV_Y; Flags |= LiBackendFlags_FlipUV_Y;
@@ -179,10 +179,10 @@ 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(Li::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);
} }
C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL);
} }

View File

@@ -24,6 +24,7 @@ SOFTWARE.
*/ */
#include <pd/core/common.hpp> #include <pd/core/common.hpp>
#include <pd/core/strings.hpp>
namespace PD { namespace PD {
class PD_CORE_API Color { class PD_CORE_API Color {
@@ -65,17 +66,34 @@ class PD_CORE_API Color {
b(static_cast<u8>(255.f * b)), b(static_cast<u8>(255.f * b)),
a(static_cast<u8>(255.f * a)) {} a(static_cast<u8>(255.f * a)) {}
/** /**
* Constructor for Hex Input * Constructor for Hex Input (is abel to run at compile time xD)
* @param hex Hex String in `#ffffff` or `#ffffffff` format * @param hex Hex String in `#ffffff` or `#ffffffff` format
*/ */
Color(const std::string& hex) { Hex(hex); } constexpr Color(const std::string_view& hex) { Hex(hex); }
/** /**
* Create Color Object by Hex String * Create Color Object by Hex String (at compile time btw)
* @param hex Hex String in `#ffffff` or `#ffffffff` format * @param hex Hex String in `#ffffff` or `#ffffffff` format
* @return Color class itself * @return Color class itself
*/ */
Color& Hex(const std::string& hex); constexpr Color& Hex(const std::string_view& hex) {
if (!(hex.length() == 7 || hex.length() == 9)) {
throw "[PD] Color: hex string is not rgb or rgba!";
}
r = PD::Strings::HexChar2Int(hex[1]) * 16 +
PD::Strings::HexChar2Int(hex[2]);
g = PD::Strings::HexChar2Int(hex[3]) * 16 +
PD::Strings::HexChar2Int(hex[4]);
b = PD::Strings::HexChar2Int(hex[5]) * 16 +
PD::Strings::HexChar2Int(hex[6]);
if (hex.length() == 9) {
a = PD::Strings::HexChar2Int(hex[7]) * 16 +
PD::Strings::HexChar2Int(hex[8]);
} else {
a = 255;
}
return *this;
}
/** /**
* Convert this Color Object to Hex string * Convert this Color Object to Hex string
* @param rgba [default false] sets if 8 or 6 digit color should be returned * @param rgba [default false] sets if 8 or 6 digit color should be returned
@@ -89,7 +107,7 @@ class PD_CORE_API Color {
* @param p Amount (supports -1.0 to 1.0 for use of sine) * @param p Amount (supports -1.0 to 1.0 for use of sine)
* @return Class Reference * @return Class Reference
*/ */
Color& Fade(const Color& color, float p) { constexpr Color& Fade(const Color& color, float p) {
a = static_cast<u8>((color.a - a) * ((p + 1.f) / 2)); a = static_cast<u8>((color.a - a) * ((p + 1.f) / 2));
b = static_cast<u8>((color.b - b) * ((p + 1.f) / 2)); b = static_cast<u8>((color.b - b) * ((p + 1.f) / 2));
g = static_cast<u8>((color.g - g) * ((p + 1.f) / 2)); g = static_cast<u8>((color.g - g) * ((p + 1.f) / 2));
@@ -101,12 +119,12 @@ class PD_CORE_API Color {
* Get 32Bit Color Value * Get 32Bit Color Value
* @return 32Bit Color Value (ABGR iirc) * @return 32Bit Color Value (ABGR iirc)
*/ */
u32 Get() const { return (a << 24) | (b << 16) | (g << 8) | r; } constexpr u32 Get() const { return (a << 24) | (b << 16) | (g << 8) | r; }
/** /**
* Get The Luminance of the Color * Get The Luminance of the Color
* @return luminance (from 0.0 to 1.0) * @return luminance (from 0.0 to 1.0)
*/ */
float Luminance() const { constexpr float Luminance() const {
// For Reference https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness // For Reference https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
return (0.3 * (r / 255.f) + 0.59 * (g / 255.f) + 0.11 * (b / 255.f)); return (0.3 * (r / 255.f) + 0.59 * (g / 255.f) + 0.11 * (b / 255.f));
} }
@@ -114,13 +132,13 @@ class PD_CORE_API Color {
* Check if the Color is Light or Dark * Check if the Color is Light or Dark
* @return true if light * @return true if light
*/ */
bool IsLight() const { return (Luminance() >= 0.5); } constexpr bool IsLight() const { return (Luminance() >= 0.5); }
/** /**
* Operator to cast Color to 32Bit Value * Operator to cast Color to 32Bit Value
* @return 32Bit Color Value * @return 32Bit Color Value
*/ */
operator u32() const { return Get(); } constexpr operator u32() const { return Get(); }
/** Public Access Data section */ /** Public Access Data section */
u8 r; u8 r;

View File

@@ -62,6 +62,9 @@ SOFTWARE.
#define PD_BIT(x) (1 << x) #define PD_BIT(x) (1 << x)
namespace PD { namespace PD {
[[noreturn]] inline void Throw(const std::string& str) {
throw std::runtime_error("[PD] " + str);
}
/** Types */ /** Types */
using u8 = unsigned char; using u8 = unsigned char;
using u16 = unsigned short; using u16 = unsigned short;

View File

@@ -25,6 +25,7 @@ SOFTWARE.
#include <pd/core/bit_util.hpp> #include <pd/core/bit_util.hpp>
#include <pd/core/color.hpp> #include <pd/core/color.hpp>
#include <pd/core/fnv.hpp>
#include <pd/core/io.hpp> #include <pd/core/io.hpp>
#include <pd/core/mat.hpp> #include <pd/core/mat.hpp>
#include <pd/core/sl/sl.hpp> #include <pd/core/sl/sl.hpp>

53
include/pd/core/fnv.hpp Normal file
View File

@@ -0,0 +1,53 @@
#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.
*/
#include <pd/core/common.hpp>
namespace PD {
/**
* FNV-1a 32Bit hasing function
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
*/
constexpr u32 FNV1A32(std::string_view str) {
u32 ret = 0x811c9dc5; // Offset basis
for (auto& it : str) {
ret ^= it;
ret *= 0x01000193; // Prime
}
return ret;
}
/**
* FNV-1a 64Bit hasing function
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
*/
constexpr u64 FNV1A64(std::string_view str) {
u64 ret = 0xcbf29ce484222325; // Offset basis
for (auto& it : str) {
ret ^= it;
ret *= 0x00000100000001b3; // Prime
}
return ret;
}
} // namespace PD

View File

@@ -28,18 +28,18 @@ class u128 {
return u128(); return u128();
} }
u128 operator+(const u128& v) const { constexpr u128 operator+(const u128& v) const {
u128 ret; u128 ret;
ret.pLow = pLow + v.pLow; ret.pLow = pLow + v.pLow;
ret.pHigh = pHigh + v.pHigh + (ret.pLow < pLow); ret.pHigh = pHigh + v.pHigh + (ret.pLow < pLow);
return ret; return ret;
} }
u128 operator&(const u128& v) const { constexpr u128 operator&(const u128& v) const {
return u128(pLow & v.pLow, pHigh & v.pHigh); return u128(pLow & v.pLow, pHigh & v.pHigh);
} }
u128 operator<<(u32 s) const { constexpr u128 operator<<(u32 s) const {
if (s == 0) { if (s == 0) {
return *this; return *this;
} }
@@ -52,7 +52,7 @@ class u128 {
return u128(pLow << s, (pHigh << s) | (pLow >> (64 - s))); return u128(pLow << s, (pHigh << s) | (pLow >> (64 - s)));
} }
u128 operator>>(u32 s) const { constexpr u128 operator>>(u32 s) const {
if (s == 0) { if (s == 0) {
return *this; return *this;
} }
@@ -65,23 +65,23 @@ class u128 {
return u128((pLow >> s) | (pHigh << (64 - s)), pHigh >> s); return u128((pLow >> s) | (pHigh << (64 - s)), pHigh >> s);
} }
u128& operator|=(const u128& v) { constexpr u128& operator|=(const u128& v) {
pLow |= v.pLow; pLow |= v.pLow;
pHigh |= v.pHigh; pHigh |= v.pHigh;
return *this; return *this;
} }
u128 operator|(const u128& v) const { constexpr u128 operator|(const u128& v) const {
return u128(pLow | v.pLow, pHigh | v.pHigh); return u128(pLow | v.pLow, pHigh | v.pHigh);
} }
u128& operator&=(const u128& v) { constexpr u128& operator&=(const u128& v) {
pLow &= v.pLow; pLow &= v.pLow;
pHigh &= v.pHigh; pHigh &= v.pHigh;
return *this; return *this;
} }
u128 operator~() const { return u128(~pLow, ~pHigh); } constexpr u128 operator~() const { return u128(~pLow, ~pHigh); }
/** /**
* Old why to make if checks possible * Old why to make if checks possible
@@ -92,7 +92,7 @@ class u128 {
// return pLow & v.pLow || pHigh & v.pHigh; // return pLow & v.pLow || pHigh & v.pHigh;
// } // }
bool operator==(const u128& v) const { constexpr bool operator==(const u128& v) const {
return pLow == v.pLow && pHigh == v.pHigh; return pLow == v.pLow && pHigh == v.pHigh;
} }
@@ -100,12 +100,14 @@ class u128 {
* Use explicit here to make sure it is only for checking and not for * Use explicit here to make sure it is only for checking and not for
* some error leading implicit bool assignments... * some error leading implicit bool assignments...
*/ */
explicit operator bool() const { return pLow != 0 || pHigh != 0; } constexpr explicit operator bool() const { return pLow != 0 || pHigh != 0; }
/** Deprecated way to handle `flag & SomeFlag` */ /** Deprecated way to handle `flag & SomeFlag` */
bool Has(const u128& v) const { return pLow & v.pLow || pHigh & v.pHigh; } constexpr bool Has(const u128& v) const {
return pLow & v.pLow || pHigh & v.pHigh;
}
bool operator!=(const u128& v) const { return !(*this == v); } constexpr bool operator!=(const u128& v) const { return !(*this == v); }
}; };
} // namespace PD } // namespace PD

View File

@@ -30,6 +30,13 @@ namespace PD {
* Set of String Utillity Functions * Set of String Utillity Functions
*/ */
namespace Strings { namespace Strings {
constexpr int HexChar2Int(char c) {
/** Imagine man hat ne lookup table dafür verwendet :/ */
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return 10 + (c - 'a');
if (c >= 'A' && c <= 'F') return 10 + (c - 'A');
return -1; // Error
}
/** /**
* Check if a String ends with a specific extension * Check if a String ends with a specific extension
* @param str Input string * @param str Input string

View File

@@ -55,7 +55,8 @@ class TimeStats {
* @return Average * @return Average
*/ */
u64 GetAverage() { u64 GetAverage() {
if (!num_val) return 0.f; if (!num_val)
return 0.f;
u64 res = 0; u64 res = 0;
for (int i = 0; i < num_val; i++) { for (int i = 0; i < num_val; i++) {
res += val[smart_idx(i)]; res += val[smart_idx(i)];
@@ -68,7 +69,8 @@ class TimeStats {
* @return Minimum value * @return Minimum value
*/ */
u64 GetMin() { u64 GetMin() {
if (!num_val) return 0.f; if (!num_val)
return 0.f;
u64 res = std::numeric_limits<u64>::max(); u64 res = std::numeric_limits<u64>::max();
for (int i = 0; i < num_val; i++) { for (int i = 0; i < num_val; i++) {
res = std::min(val[smart_idx(i)], res); res = std::min(val[smart_idx(i)], res);
@@ -81,7 +83,8 @@ class TimeStats {
* @return Max Value * @return Max Value
*/ */
u64 GetMax() { u64 GetMax() {
if (!num_val) return 0.f; if (!num_val)
return 0.f;
u64 res = 0; u64 res = 0;
for (int i = 0; i < num_val; i++) { for (int i = 0; i < num_val; i++) {
res = std::max(val[smart_idx(i)], res); res = std::max(val[smart_idx(i)], res);

View File

@@ -60,7 +60,7 @@ class Tween {
* @param delta deltatime * @param delta deltatime
*/ */
void Update(float delta) { void Update(float delta) {
time += delta / 1000.f; time += delta * 0.001f;
if (time > tend) { if (time > tend) {
finished = true; finished = true;
time = tend; time = tend;
@@ -162,10 +162,10 @@ class Tween {
return -(end - start) * t * (t - 2) + start; return -(end - start) * t * (t - 2) + start;
break; break;
case EaseInOutQuad: case EaseInOutQuad:
t = time / (tend / 2); t = time / (tend * 0.5f);
if (t < 1) return (end - start) / 2 * t * t + start; if (t < 1) return (end - start) * 0.5f * t * t + start;
t--; t--;
return -(end - start) / 2 * (t * (t - 2) - 1) + start; return -(end - start) * 0.5f * (t * (t - 2) - 1) + start;
break; break;
case EaseInCubic: case EaseInCubic:
t = time / tend; t = time / tend;
@@ -177,20 +177,20 @@ class Tween {
return (end - start) * (t * t * t + 1) + start; return (end - start) * (t * t * t + 1) + start;
break; break;
// case EaseInOutCubic: // case EaseInOutCubic:
// t = time / (tend / 2); // t = time / (tend *0.5f);
// if (t < 1) return (end - start) / 2 * t * t * t + start; // if (t < 1) return (end - start) *0.5f * t * t * t + start;
// t--; // t--;
// return (end - start) / 2 * (t * t * t * 2) + start; // return (end - start) *0.5f * (t * t * t * 2) + start;
// break; // break;
case EaseInSine: case EaseInSine:
return -(end - start) * cos(time / tend * (M_PI / 2)) + (end - start) + return -(end - start) * cos(time / tend * (M_PI * 0.5f)) +
start; (end - start) + start;
break; break;
case EaseOutSine: case EaseOutSine:
return (end - start) * sin(time / tend * (M_PI / 2)) + start; return (end - start) * sin(time / tend * (M_PI * 0.5f)) + start;
break; break;
case EaseInOutSine: case EaseInOutSine:
return -(end - start) / 2 * (cos(M_PI * time / tend) - 1) + start; return -(end - start) * 0.5f * (cos(M_PI * time / tend) - 1) + start;
break; break;
default: // Linear default: // Linear

View File

@@ -0,0 +1,45 @@
#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.
*/
#include <pd/core/core.hpp>
namespace PD {
class Snd {
public:
Snd(const std::string& name = "NullSnd") : pName(name) {};
~Snd() = default;
PD_SHARED(Snd);
virtual void Init() {}
virtual void Deinit() {}
virtual bool Done(int buf_idx) {}
virtual void Update(int buf_idx, void* data) {}
virtual bool IsChannelPlaying(int chn) {}
virtual bool IsChannelPaused(int chn) {}
const std::string pName = "NullSnd";
};
} // namespace PD

View File

@@ -97,7 +97,7 @@ class PD_LITHIUM_API DrawList {
* Extended Draw Text Function * Extended Draw Text Function
*/ */
void DrawTextEx(const fvec2& p, const std::string& text, u32 color, void DrawTextEx(const fvec2& p, const std::string& text, u32 color,
LiTextFlags flags, fvec2 box = fvec2(0.f)); LiTextFlags flags, const fvec2& box = fvec2(0.f));
void DrawLine(const fvec2& a, const fvec2& b, u32 color, int t = 1); void DrawLine(const fvec2& a, const fvec2& b, u32 color, int t = 1);
/** /**
* Take list of points and display it as a line on screen * Take list of points and display it as a line on screen
@@ -138,6 +138,14 @@ class PD_LITHIUM_API DrawList {
* @param v Position to add * @param v Position to add
*/ */
void PathAdd(const fvec2& v) { pPath.Add(v); } void PathAdd(const fvec2& v) { pPath.Add(v); }
/**
* Add a Point to the Path
* @note Keep in mind that this function is used for
* setting the starting point
* @param x X Position to add
* @param y Y Position to add
*/
void PathAdd(float x, float y) { pPath.Add(fvec2(x, y)); }
/** /**
* Path Stroke Create Line from point to point * Path Stroke Create Line from point to point
* @note For Primitives like Rect or Triangle mak sure to use * @note For Primitives like Rect or Triangle mak sure to use

View File

@@ -101,6 +101,8 @@ class PD_LITHIUM_API Font {
*/ */
void pMakeAtlas(bool final, std::vector<u8>& font_tex, int texszs, void pMakeAtlas(bool final, std::vector<u8>& font_tex, int texszs,
PD::Li::Texture::Ref tex); PD::Li::Texture::Ref tex);
std::string pWrapText(const std::string& txt, float scale,
const PD::fvec2& max, PD::fvec2& dim);
/** Data Section */ /** Data Section */
int PixelHeight; int PixelHeight;

View File

@@ -45,8 +45,8 @@ class ID {
* used when directly placing a string istead of using ID("") * used when directly placing a string istead of using ID("")
* @param text Input String * @param text Input String
*/ */
ID(const char* text) { constexpr ID(const char* text) {
pID = PD::Strings::FastHash(text); pID = PD::FNV1A32(text);
pName = text; pName = text;
} }
/** /**
@@ -56,16 +56,17 @@ class ID {
~ID() = default; ~ID() = default;
/** Get The ID Initial Name */ /** Get The ID Initial Name */
const std::string& GetName() const { return pName; } constexpr const std::string_view& GetNameView() const { return pName; }
const std::string GetName() const { return std::string(pName); }
/** Getter for the raw 32bit int id */ /** Getter for the raw 32bit int id */
const u32& RawID() const { return pID; } constexpr const u32& RawID() const { return pID; }
/** Return the ID when casting to u32 */ /** Return the ID when casting to u32 */
operator u32() const { return pID; } constexpr operator u32() const { return pID; }
u32 pID; ///< Hash of the name u32 pID; ///< Hash of the name
std::string pName; ///< Name std::string_view pName; ///< Name
}; };
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD

View File

@@ -52,7 +52,7 @@ class PD_UI7_API Layout {
PD_SHARED(Layout); PD_SHARED(Layout);
const std::string& GetName() const { return ID.GetName(); } const std::string GetName() const { return ID.GetName(); }
const UI7::ID& GetID() const { return this->ID; } const UI7::ID& GetID() const { return this->ID; }
const fvec2& GetPosition() const { return Pos; } const fvec2& GetPosition() const { return Pos; }

View File

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

View File

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

View File

@@ -25,39 +25,6 @@ SOFTWARE.
#include <pd/core/color.hpp> #include <pd/core/color.hpp>
namespace PD { namespace PD {
// The Solution of the biggest performance issue
// A Simple Lookup table
static const std::map<char, int> HEX_DEC = {
{'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5},
{'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'a', 10}, {'b', 11},
{'c', 12}, {'d', 13}, {'e', 14}, {'f', 15}, {'A', 10}, {'B', 11},
{'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}};
PD_CORE_API Color& Color::Hex(const std::string& hex) {
#ifdef PD_NO_SAFE_CODE
/// Safetey check (not required if you programm well xd)
if (hex.length() != 7 || hex.length() != 9 || hex.length() != 6 ||
hex.length() != 8 || std::find_if(hex.begin(), hex.end(), [](char c) {
return !std::isxdigit(c);
}) != hex.end()) {
return *this;
}
#endif
int offset = ((hex.length() == 7 || hex.length() == 9) ? 1 : 0);
r = HEX_DEC.at(hex[offset]) * 16 + HEX_DEC.at(hex[offset + 1]);
offset += 2;
g = HEX_DEC.at(hex[offset]) * 16 + HEX_DEC.at(hex[offset + 1]);
offset += 2;
b = HEX_DEC.at(hex[offset]) * 16 + HEX_DEC.at(hex[offset + 1]);
offset += 2;
if (hex.length() == 9) {
a = HEX_DEC.at(hex[offset]) * 16 + HEX_DEC.at(hex[offset + 1]);
} else {
a = 255;
}
return *this;
}
PD_CORE_API std::string Color::Hex(bool rgba) const { PD_CORE_API std::string Color::Hex(bool rgba) const {
/** Need to int cast (so it is used as num and not char...) */ /** Need to int cast (so it is used as num and not char...) */
std::stringstream s; std::stringstream s;

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
project(pd-lithium LANGUAGES CXX VERSION 0.5.1) project(pd-lithium LANGUAGES CXX VERSION 0.6.0)
option(PD_LI_INCLUDE_FONTS "Include Fonts" OFF) option(PD_LI_INCLUDE_FONTS "Include Fonts" OFF)

View File

@@ -37,6 +37,8 @@ PD_LITHIUM_API void DrawList::Clear() {
pNumIndices = 0; pNumIndices = 0;
pNumVertices = 0; pNumVertices = 0;
pDrawList.clear(); pDrawList.clear();
pPath.Clear();
pClipRects.Clear();
} }
PD_LITHIUM_API void DrawList::AddCommand(Command::Ref v) { PD_LITHIUM_API void DrawList::AddCommand(Command::Ref v) {
@@ -279,7 +281,7 @@ PD_LITHIUM_API void DrawList::DrawText(const fvec2 &pos,
PD_LITHIUM_API void DrawList::DrawTextEx(const fvec2 &p, PD_LITHIUM_API void DrawList::DrawTextEx(const fvec2 &p,
const std::string &text, u32 color, const std::string &text, u32 color,
LiTextFlags flags, fvec2 box) { LiTextFlags flags, const fvec2 &box) {
if (!pCurrentFont) { if (!pCurrentFont) {
return; return;
} }

View File

@@ -250,6 +250,10 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
fvec2 td; fvec2 td;
fvec2 rpos = pos; fvec2 rpos = pos;
fvec2 rbox = box; fvec2 rbox = box;
std::string txt = text;
if (flags & LiTextFlags_Wrap) {
txt = pWrapText(txt, scale, box, td);
}
if (flags & (LiTextFlags_AlignMid | LiTextFlags_AlignRight)) { if (flags & (LiTextFlags_AlignMid | LiTextFlags_AlignRight)) {
td = GetTextBounds(text, scale); td = GetTextBounds(text, scale);
} }
@@ -261,7 +265,7 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
} }
std::vector<std::string> lines; std::vector<std::string> lines;
std::istringstream iss(text); std::istringstream iss(txt);
std::string tmp; std::string tmp;
while (std::getline(iss, tmp)) { while (std::getline(iss, tmp)) {
lines.push_back(tmp); lines.push_back(tmp);
@@ -315,5 +319,30 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
} }
} }
PD_LITHIUM_API std::string Font::pWrapText(const std::string &txt, float scale,
const PD::fvec2 &max,
PD::fvec2 &dim) {
std::string ret;
std::string line;
int lx = 0;
std::stringstream s(txt);
std::string tmp;
// Simply go over every word
while (s >> tmp) {
auto d = GetTextBounds(tmp, scale);
if (lx + d.x <= max.x) {
line += tmp + ' ';
lx += d.x;
} else {
ret += line + '\n';
line = tmp + ' ';
lx = GetTextBounds(line, scale).x;
}
}
ret += line;
dim = GetTextBounds(ret, scale);
return ret;
}
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD

View File

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

View File

@@ -141,7 +141,7 @@ PD_UI7_API void Menu::HandleScrolling() {
pLayout->ScrollStart = pLayout->ScrollOffset; pLayout->ScrollStart = pLayout->ScrollOffset;
} }
if (pIO->InputHandler->DragObject( if (pIO->InputHandler->DragObject(
"sbg" + pID.pName, "sbg" + pID.GetName(),
fvec4(pLayout->Pos, fvec2(0.f)) + pLayout->WorkRect)) { fvec4(pLayout->Pos, fvec2(0.f)) + pLayout->WorkRect)) {
if (pIO->InputHandler->DragReleasedAW) { if (pIO->InputHandler->DragReleasedAW) {
} else { } else {