Compare commits
2 Commits
devel050
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
|
6c38aa6f21
|
|||
|
f19c947fc3
|
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# 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
|
||||
set(PD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
source/bknd-gfx.cpp
|
||||
|
||||
@@ -27,19 +27,10 @@ SOFTWARE.
|
||||
#include <3ds.h>
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <pd-3ds/linearAllocator.hpp>
|
||||
#include <pd/lithium/lithium.hpp>
|
||||
|
||||
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 {
|
||||
public:
|
||||
GfxC3D() : GfxDriver("Citro3D") {}
|
||||
@@ -59,8 +50,8 @@ class GfxC3D : public GfxDriver {
|
||||
PD::Li::Texture::Filter filter =
|
||||
PD::Li::Texture::Filter::LINEAR) override;
|
||||
|
||||
Vec<Li::Vertex, LinearAlloc<Li::Vertex>> VertexBuffer;
|
||||
Vec<u16, LinearAlloc<u16>> IndexBuffer;
|
||||
std::vector<Li::Vertex, LinearAllocator<Li::Vertex>> VertexBuffer;
|
||||
std::vector<u16, LinearAllocator<u16>> IndexBuffer;
|
||||
int pLocProjection = 0;
|
||||
DVLB_s* ShaderCode;
|
||||
shaderProgram_s Shader;
|
||||
|
||||
49
backends/3ds/include/pd-3ds/linearAllocator.hpp
Normal file
49
backends/3ds/include/pd-3ds/linearAllocator.hpp
Normal 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
|
||||
@@ -93,8 +93,8 @@ int GetBPP(Li::Texture::Type type) {
|
||||
}
|
||||
|
||||
void GfxC3D::Init() {
|
||||
VertexBuffer.Resize(4 * 8192);
|
||||
IndexBuffer.Resize(6 * 8192);
|
||||
VertexBuffer.resize(4 * 8192);
|
||||
IndexBuffer.resize(6 * 8192);
|
||||
|
||||
Flags |= LiBackendFlags_FlipUV_Y;
|
||||
|
||||
@@ -179,10 +179,10 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
||||
BindTex(Tex->Address);
|
||||
auto bufInfo = C3D_GetBufInfo();
|
||||
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_UNSIGNED_SHORT, IndexBuffer.Data() + StartIndex);
|
||||
C3D_UNSIGNED_SHORT, IndexBuffer.data() + StartIndex);
|
||||
}
|
||||
C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <pd/core/common.hpp>
|
||||
#include <pd/core/strings.hpp>
|
||||
|
||||
namespace PD {
|
||||
class PD_CORE_API Color {
|
||||
@@ -65,17 +66,34 @@ class PD_CORE_API Color {
|
||||
b(static_cast<u8>(255.f * b)),
|
||||
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
|
||||
*/
|
||||
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
|
||||
* @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
|
||||
* @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)
|
||||
* @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));
|
||||
b = static_cast<u8>((color.b - b) * ((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
|
||||
* @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
|
||||
* @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
|
||||
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
|
||||
* @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
|
||||
* @return 32Bit Color Value
|
||||
*/
|
||||
operator u32() const { return Get(); }
|
||||
constexpr operator u32() const { return Get(); }
|
||||
|
||||
/** Public Access Data section */
|
||||
u8 r;
|
||||
|
||||
@@ -62,6 +62,9 @@ SOFTWARE.
|
||||
#define PD_BIT(x) (1 << x)
|
||||
|
||||
namespace PD {
|
||||
[[noreturn]] inline void Throw(const std::string& str) {
|
||||
throw std::runtime_error("[PD] " + str);
|
||||
}
|
||||
/** Types */
|
||||
using u8 = unsigned char;
|
||||
using u16 = unsigned short;
|
||||
|
||||
@@ -25,6 +25,7 @@ SOFTWARE.
|
||||
|
||||
#include <pd/core/bit_util.hpp>
|
||||
#include <pd/core/color.hpp>
|
||||
#include <pd/core/fnv.hpp>
|
||||
#include <pd/core/io.hpp>
|
||||
#include <pd/core/mat.hpp>
|
||||
#include <pd/core/sl/sl.hpp>
|
||||
|
||||
53
include/pd/core/fnv.hpp
Normal file
53
include/pd/core/fnv.hpp
Normal 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
|
||||
@@ -28,18 +28,18 @@ class u128 {
|
||||
return u128();
|
||||
}
|
||||
|
||||
u128 operator+(const u128& v) const {
|
||||
constexpr 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 {
|
||||
constexpr u128 operator&(const u128& v) const {
|
||||
return u128(pLow & v.pLow, pHigh & v.pHigh);
|
||||
}
|
||||
|
||||
u128 operator<<(u32 s) const {
|
||||
constexpr u128 operator<<(u32 s) const {
|
||||
if (s == 0) {
|
||||
return *this;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class u128 {
|
||||
return u128(pLow << s, (pHigh << s) | (pLow >> (64 - s)));
|
||||
}
|
||||
|
||||
u128 operator>>(u32 s) const {
|
||||
constexpr u128 operator>>(u32 s) const {
|
||||
if (s == 0) {
|
||||
return *this;
|
||||
}
|
||||
@@ -65,23 +65,23 @@ class u128 {
|
||||
return u128((pLow >> s) | (pHigh << (64 - s)), pHigh >> s);
|
||||
}
|
||||
|
||||
u128& operator|=(const u128& v) {
|
||||
constexpr u128& operator|=(const u128& v) {
|
||||
pLow |= v.pLow;
|
||||
pHigh |= v.pHigh;
|
||||
return *this;
|
||||
}
|
||||
|
||||
u128 operator|(const u128& v) const {
|
||||
constexpr u128 operator|(const u128& v) const {
|
||||
return u128(pLow | v.pLow, pHigh | v.pHigh);
|
||||
}
|
||||
|
||||
u128& operator&=(const u128& v) {
|
||||
constexpr u128& operator&=(const u128& v) {
|
||||
pLow &= v.pLow;
|
||||
pHigh &= v.pHigh;
|
||||
return *this;
|
||||
}
|
||||
|
||||
u128 operator~() const { return u128(~pLow, ~pHigh); }
|
||||
constexpr u128 operator~() const { return u128(~pLow, ~pHigh); }
|
||||
|
||||
/**
|
||||
* Old why to make if checks possible
|
||||
@@ -92,7 +92,7 @@ class u128 {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -100,12 +100,14 @@ class u128 {
|
||||
* 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; }
|
||||
constexpr 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; }
|
||||
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
|
||||
|
||||
|
||||
@@ -30,6 +30,13 @@ namespace PD {
|
||||
* Set of String Utillity Functions
|
||||
*/
|
||||
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
|
||||
* @param str Input string
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace PD {
|
||||
* Class to calculate Maximum/Minimum and Average Timings
|
||||
*/
|
||||
class TimeStats {
|
||||
public:
|
||||
public:
|
||||
/**
|
||||
* Constructor taking a lengh for the List
|
||||
* @param l Lengh of the data list
|
||||
@@ -55,7 +55,8 @@ class TimeStats {
|
||||
* @return Average
|
||||
*/
|
||||
u64 GetAverage() {
|
||||
if (!num_val) return 0.f;
|
||||
if (!num_val)
|
||||
return 0.f;
|
||||
u64 res = 0;
|
||||
for (int i = 0; i < num_val; i++) {
|
||||
res += val[smart_idx(i)];
|
||||
@@ -68,7 +69,8 @@ class TimeStats {
|
||||
* @return Minimum value
|
||||
*/
|
||||
u64 GetMin() {
|
||||
if (!num_val) return 0.f;
|
||||
if (!num_val)
|
||||
return 0.f;
|
||||
u64 res = std::numeric_limits<u64>::max();
|
||||
for (int i = 0; i < num_val; i++) {
|
||||
res = std::min(val[smart_idx(i)], res);
|
||||
@@ -81,7 +83,8 @@ class TimeStats {
|
||||
* @return Max Value
|
||||
*/
|
||||
u64 GetMax() {
|
||||
if (!num_val) return 0.f;
|
||||
if (!num_val)
|
||||
return 0.f;
|
||||
u64 res = 0;
|
||||
for (int i = 0; i < num_val; i++) {
|
||||
res = std::max(val[smart_idx(i)], res);
|
||||
@@ -119,7 +122,7 @@ class TimeStats {
|
||||
*/
|
||||
const size_t GetNumValues() { return num_val; }
|
||||
|
||||
private:
|
||||
private:
|
||||
/**
|
||||
* Get the Next Position to write to
|
||||
* @param c current position
|
||||
@@ -149,9 +152,9 @@ namespace TT {
|
||||
* Data Structure for a TimeTrace Result
|
||||
*/
|
||||
class Res {
|
||||
public:
|
||||
public:
|
||||
/** Constructore that Inits a protocol at size of 60 frames */
|
||||
Res(): start(0), end(0) { protocol = TimeStats::New(60); }
|
||||
Res() : start(0), end(0) { protocol = TimeStats::New(60); }
|
||||
~Res() = default;
|
||||
|
||||
PD_SHARED(Res);
|
||||
@@ -201,7 +204,7 @@ class Res {
|
||||
*/
|
||||
TimeStats::Ref GetProtocol() { return protocol; }
|
||||
|
||||
private:
|
||||
private:
|
||||
/** Trace ID */
|
||||
std::string id;
|
||||
/** Start time */
|
||||
@@ -237,7 +240,7 @@ PD_CORE_API void End(const std::string &id);
|
||||
* ```
|
||||
*/
|
||||
class Scope {
|
||||
public:
|
||||
public:
|
||||
/**
|
||||
* Constructor requiring a Name for the Trace
|
||||
* @param id Name of the Trace
|
||||
@@ -251,7 +254,7 @@ class Scope {
|
||||
*/
|
||||
~Scope() { End(ID); }
|
||||
|
||||
private:
|
||||
private:
|
||||
/** Trace Name/ID */
|
||||
std::string ID;
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@ class Tween {
|
||||
* @param delta deltatime
|
||||
*/
|
||||
void Update(float delta) {
|
||||
time += delta / 1000.f;
|
||||
time += delta * 0.001f;
|
||||
if (time > tend) {
|
||||
finished = true;
|
||||
time = tend;
|
||||
@@ -162,10 +162,10 @@ class Tween {
|
||||
return -(end - start) * t * (t - 2) + start;
|
||||
break;
|
||||
case EaseInOutQuad:
|
||||
t = time / (tend / 2);
|
||||
if (t < 1) return (end - start) / 2 * t * t + start;
|
||||
t = time / (tend * 0.5f);
|
||||
if (t < 1) return (end - start) * 0.5f * t * t + start;
|
||||
t--;
|
||||
return -(end - start) / 2 * (t * (t - 2) - 1) + start;
|
||||
return -(end - start) * 0.5f * (t * (t - 2) - 1) + start;
|
||||
break;
|
||||
case EaseInCubic:
|
||||
t = time / tend;
|
||||
@@ -177,20 +177,20 @@ class Tween {
|
||||
return (end - start) * (t * t * t + 1) + start;
|
||||
break;
|
||||
// case EaseInOutCubic:
|
||||
// t = time / (tend / 2);
|
||||
// if (t < 1) return (end - start) / 2 * t * t * t + start;
|
||||
// t = time / (tend *0.5f);
|
||||
// if (t < 1) return (end - start) *0.5f * t * t * t + start;
|
||||
// t--;
|
||||
// return (end - start) / 2 * (t * t * t * 2) + start;
|
||||
// return (end - start) *0.5f * (t * t * t * 2) + start;
|
||||
// break;
|
||||
case EaseInSine:
|
||||
return -(end - start) * cos(time / tend * (M_PI / 2)) + (end - start) +
|
||||
start;
|
||||
return -(end - start) * cos(time / tend * (M_PI * 0.5f)) +
|
||||
(end - start) + start;
|
||||
break;
|
||||
case EaseOutSine:
|
||||
return (end - start) * sin(time / tend * (M_PI / 2)) + start;
|
||||
return (end - start) * sin(time / tend * (M_PI * 0.5f)) + start;
|
||||
break;
|
||||
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;
|
||||
|
||||
default: // Linear
|
||||
|
||||
45
include/pd/drivers/snd.hpp
Normal file
45
include/pd/drivers/snd.hpp
Normal 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
|
||||
@@ -97,7 +97,7 @@ class PD_LITHIUM_API DrawList {
|
||||
* Extended Draw Text Function
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
* @note For Primitives like Rect or Triangle mak sure to use
|
||||
|
||||
@@ -101,6 +101,8 @@ class PD_LITHIUM_API Font {
|
||||
*/
|
||||
void pMakeAtlas(bool final, std::vector<u8>& font_tex, int texszs,
|
||||
PD::Li::Texture::Ref tex);
|
||||
std::string pWrapText(const std::string& txt, float scale,
|
||||
const PD::fvec2& max, PD::fvec2& dim);
|
||||
|
||||
/** Data Section */
|
||||
int PixelHeight;
|
||||
|
||||
@@ -45,8 +45,8 @@ class ID {
|
||||
* used when directly placing a string istead of using ID("")
|
||||
* @param text Input String
|
||||
*/
|
||||
ID(const char* text) {
|
||||
pID = PD::Strings::FastHash(text);
|
||||
constexpr ID(const char* text) {
|
||||
pID = PD::FNV1A32(text);
|
||||
pName = text;
|
||||
}
|
||||
/**
|
||||
@@ -56,16 +56,17 @@ class ID {
|
||||
~ID() = default;
|
||||
|
||||
/** 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 */
|
||||
const u32& RawID() const { return pID; }
|
||||
constexpr const u32& RawID() const { return pID; }
|
||||
|
||||
/** Return the ID when casting to u32 */
|
||||
operator u32() const { return pID; }
|
||||
constexpr operator u32() const { return pID; }
|
||||
|
||||
u32 pID; ///< Hash of the name
|
||||
std::string pName; ///< Name
|
||||
std::string_view pName; ///< Name
|
||||
};
|
||||
} // namespace UI7
|
||||
} // namespace PD
|
||||
@@ -52,7 +52,7 @@ class PD_UI7_API 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 fvec2& GetPosition() const { return Pos; }
|
||||
|
||||
@@ -37,7 +37,7 @@ SOFTWARE.
|
||||
* Major Minor Patch Build
|
||||
* 0x01010000 -> 1.1.0-0
|
||||
*/
|
||||
#define UI7_VERSION 0x00050100
|
||||
#define UI7_VERSION 0x00060000
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
@@ -55,18 +55,18 @@ class PD_UI7_API Context {
|
||||
|
||||
PD_SHARED(Context);
|
||||
|
||||
void AddViewPort(const ID &id, const ivec4 &vp);
|
||||
void UseViewPort(const ID &id);
|
||||
void AddViewPort(const ID& id, const ivec4& vp);
|
||||
void UseViewPort(const ID& id);
|
||||
void Update();
|
||||
bool BeginMenu(const ID &id, UI7MenuFlags flags = 0, bool *pShow = nullptr);
|
||||
bool BeginMenu(const ID& id, UI7MenuFlags flags = 0, bool* pShow = nullptr);
|
||||
void EndMenu();
|
||||
void AboutMenu(bool *show = nullptr);
|
||||
void MetricsMenu(bool *show = nullptr);
|
||||
void StyleEditor(bool *show = nullptr);
|
||||
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);
|
||||
if (menu == pMenus.end()) {
|
||||
pMenus[id] = Menu::New(id, pIO);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
source/bit_util.cpp
|
||||
|
||||
@@ -25,39 +25,6 @@ SOFTWARE.
|
||||
#include <pd/core/color.hpp>
|
||||
|
||||
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 {
|
||||
/** Need to int cast (so it is used as num and not char...) */
|
||||
std::stringstream s;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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)
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ PD_LITHIUM_API void DrawList::Clear() {
|
||||
pNumIndices = 0;
|
||||
pNumVertices = 0;
|
||||
pDrawList.clear();
|
||||
pPath.Clear();
|
||||
pClipRects.Clear();
|
||||
}
|
||||
|
||||
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,
|
||||
const std::string &text, u32 color,
|
||||
LiTextFlags flags, fvec2 box) {
|
||||
LiTextFlags flags, const fvec2 &box) {
|
||||
if (!pCurrentFont) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -250,6 +250,10 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
|
||||
fvec2 td;
|
||||
fvec2 rpos = pos;
|
||||
fvec2 rbox = box;
|
||||
std::string txt = text;
|
||||
if (flags & LiTextFlags_Wrap) {
|
||||
txt = pWrapText(txt, scale, box, td);
|
||||
}
|
||||
if (flags & (LiTextFlags_AlignMid | LiTextFlags_AlignRight)) {
|
||||
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::istringstream iss(text);
|
||||
std::istringstream iss(txt);
|
||||
std::string tmp;
|
||||
while (std::getline(iss, 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 PD
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
source/theme.cpp
|
||||
|
||||
@@ -27,21 +27,21 @@ SOFTWARE.
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
Menu::Menu(const ID &id, IO::Ref io) : pIO(io), pID(id) {
|
||||
Menu::Menu(const ID& id, IO::Ref io) : pIO(io), pID(id) {
|
||||
pLayout = Layout::New(id, io);
|
||||
TitleBarHeight = io->FontScale * 30.f;
|
||||
pLayout->WorkRect.y += TitleBarHeight;
|
||||
pLayout->CursorInit();
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::Label(const std::string &label) {
|
||||
PD_UI7_API void Menu::Label(const std::string& label) {
|
||||
// Layout API
|
||||
auto r = Label::New(label, pIO);
|
||||
r->SetClipRect(fvec4(pLayout->GetPosition(), pLayout->GetSize()));
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API bool Menu::Button(const std::string &label) {
|
||||
PD_UI7_API bool Menu::Button(const std::string& label) {
|
||||
bool ret = false;
|
||||
u32 id = Strings::FastHash("btn" + label +
|
||||
std::to_string(pLayout->Objects.Size()));
|
||||
@@ -57,7 +57,7 @@ PD_UI7_API bool Menu::Button(const std::string &label) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::Checkbox(const std::string &label, bool &v) {
|
||||
PD_UI7_API void Menu::Checkbox(const std::string& label, bool& v) {
|
||||
u32 id = Strings::FastHash("cbx" + label +
|
||||
std::to_string(pLayout->Objects.Size()));
|
||||
Container::Ref r = pLayout->FindObject(id);
|
||||
@@ -76,7 +76,7 @@ PD_UI7_API void Menu::Image(Li::Texture::Ref img, fvec2 size, Li::Rect uv) {
|
||||
PD_UI7_API void Menu::Separator() {
|
||||
// Dynamic Objects are very simple...
|
||||
Container::Ref r = DynObj::New(
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container *self) {
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) {
|
||||
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||
pIO->Theme->Get(UI7Color_TextDead));
|
||||
});
|
||||
@@ -85,10 +85,10 @@ PD_UI7_API void Menu::Separator() {
|
||||
pLayout->AddObject(r);
|
||||
}
|
||||
|
||||
PD_UI7_API void Menu::SeparatorText(const std::string &label) {
|
||||
PD_UI7_API void Menu::SeparatorText(const std::string& label) {
|
||||
// Also note to use [=] instead of [&] to not undefined access label
|
||||
Container::Ref r = DynObj::New([=, this](UI7::IO::Ref io, Li::DrawList::Ref l,
|
||||
UI7::Container *self) {
|
||||
UI7::Container* self) {
|
||||
fvec2 size = self->GetSize();
|
||||
fvec2 tdim = io->Font->GetTextBounds(label, io->FontScale);
|
||||
fvec2 pos = self->FinalPos();
|
||||
@@ -141,7 +141,7 @@ PD_UI7_API void Menu::HandleScrolling() {
|
||||
pLayout->ScrollStart = pLayout->ScrollOffset;
|
||||
}
|
||||
if (pIO->InputHandler->DragObject(
|
||||
"sbg" + pID.pName,
|
||||
"sbg" + pID.GetName(),
|
||||
fvec4(pLayout->Pos, fvec2(0.f)) + pLayout->WorkRect)) {
|
||||
if (pIO->InputHandler->DragReleasedAW) {
|
||||
} else {
|
||||
@@ -238,7 +238,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
|
||||
/** 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) {
|
||||
[](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());
|
||||
@@ -254,7 +254,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
|
||||
|
||||
/** Background */
|
||||
Container::Ref r = DynObj::New([](IO::Ref io, Li::DrawList::Ref l,
|
||||
UI7::Container *self) {
|
||||
UI7::Container* self) {
|
||||
l->Layer = 0;
|
||||
l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f,
|
||||
LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot);
|
||||
@@ -271,7 +271,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
|
||||
}
|
||||
if (!(Flags & UI7MenuFlags_NoTitlebar)) {
|
||||
Container::Ref r = DynObj::New(
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container *self) {
|
||||
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, UI7::Container* self) {
|
||||
l->Layer = 20;
|
||||
/** Header Bar */
|
||||
l->DrawRectFilled(self->FinalPos(), self->GetSize(),
|
||||
@@ -295,7 +295,7 @@ PD_UI7_API void Menu::DrawBaseLayout() {
|
||||
/** Collapse Sym */
|
||||
if (!(Flags & UI7MenuFlags_NoCollapse)) {
|
||||
r = DynObj::New([=, this](UI7::IO::Ref io, Li::DrawList::Ref l,
|
||||
UI7::Container *self) {
|
||||
UI7::Container* self) {
|
||||
/** This sym actually requires layer 21 (i dont know why) */
|
||||
l->Layer = 21;
|
||||
/**
|
||||
@@ -351,7 +351,7 @@ PD_UI7_API void Menu::Update() {
|
||||
pLayout->Update();
|
||||
}
|
||||
|
||||
PD_UI7_API bool Menu::BeginTreeNode(const ID &id) {
|
||||
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()) {
|
||||
@@ -368,7 +368,7 @@ PD_UI7_API bool Menu::BeginTreeNode(const ID &id) {
|
||||
|
||||
// Object
|
||||
auto r =
|
||||
DynObj::New([=, this](IO::Ref io, Li::DrawList::Ref l, Container *self) {
|
||||
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) {
|
||||
@@ -383,7 +383,7 @@ PD_UI7_API bool Menu::BeginTreeNode(const ID &id) {
|
||||
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) {
|
||||
r->AddInputHandler([=, this](IO::Ref io, Container* self) {
|
||||
if (io->InputHandler->DragObject(
|
||||
ID(pID.GetName() + id.GetName()),
|
||||
fvec4(self->FinalPos(), self->GetSize()))) {
|
||||
|
||||
Reference in New Issue
Block a user