24 Commits
Author SHA1 Message Date
tobid7 d2806b2061 Add Nee Backend Structure
Use TexAddress instead of Texture::Ref in Cmds
Add a .clang-format??
2026-01-25 00:04:40 +01:00
tobid7 da79db223f Add MacOS support as well as OpenGL 3.3 support 2026-01-24 23:08:03 +01:00
tobid7 b2c7c1fdbf UI7 Add Containers to Layout
- Hotfix in CommandPool
- Add UI7 ItemRowHeight (Universal Item Size/Height)
- Add Containers to Layout
- Add ColorEdit to Menu
- Switch Back to COlorEdit in UI7::StyleEditor
- Add DrawList Layer Sorting to UI7 (Not working as expected)
- STart Work at ColorEdit container
2026-01-24 11:58:41 +01:00
tobid7 4a73e8c8da UI7 hotfix
- Fix Image has No Size
- Fix DragData PathRect Positioning
2026-01-24 09:27:21 +01:00
tobid7 641fc27e55 Auto Menu Sizing 2026-01-23 16:11:09 +01:00
tobid7 b8c25d6901 Add a Drag Slider to UI7 2026-01-23 15:45:25 +01:00
tobid7 931e02aefb Move CmdPool code to a source file 2026-01-22 19:25:01 +01:00
tobid7 0db4953125 Reimplement list sorting and Fix UI7 Layers 2026-01-22 16:34:46 +01:00
tobid7 2b7d25cf06 Update
- Added DestroyTex to 3ds backend
- Added Size() -> ivec2 to PD::Image
- Added CmdPool Copy as well as DrawList Copy (Static rendering)
- Added == ooperator for Rect
- Added UI7 Frame Rounding
- Fix UI7 Image usage withour size or uv
- Added New way to use BeginMenu
2026-01-18 19:25:50 +01:00
tobid7 0ef6d34435 Refactor the Command / DrawList System
Use Command Pool instead of always allocating.
This gives us e big performance diffrence on the 3ds
Fixed IDS of ui7 for now
2026-01-16 12:13:48 +01:00
tobid7 eb5d5f9974 backend updates
pd-3ds:
Add support for RGB565 textures
pd-desktop:
Add support for A8 textures
Add glfw callback chain to not break other libs using the same callback
2026-01-05 14:37:57 +01:00
tobid7 3575a6787d hotfix 2025-12-28 21:38:41 +01:00
tobid7 7fc7a2ecb9 QoL Changes
fix timetrace last diff
2025-12-27 23:35:23 +01:00
tobid7 03f65e069f Add TextMapSystem WIP 2025-12-24 18:17:58 +01:00
tobid7 c618c616fe Fix UI7 Crash by safe deleting the elements 2025-12-24 15:05:05 +01:00
tobid7 ac281dc7a9 Update
- Add data getter to DrawList
- Add NoOOS (Out Of screen Rendering) flag to text renderer (requires a textbox)
- UI7 Label Wrapping (optinal and beta)
2025-12-23 19:20:31 +01:00
tobid7 0cb5de882f Fixes and function additions
- Fixed Text pos at NoCollapse flag
- Fix Button Input Api (HandleScrolling after layout Update)
- Add getter for IO and Current Menu
- Add AdObject func wrappers to Menu
2025-12-20 19:25:20 +01:00
tobid7 b3d621a847 Add LayerOptimisation / QoL change 2025-12-19 21:08:32 +01:00
tobid7 4ad00cd2be pd-3ds: Add sysfont loader
- add support for Alpha only textures in rendering
2025-12-19 21:07:57 +01:00
tobid7 1e35dbd743 ReAdd text shorting 2025-12-18 21:51:48 +01:00
tobid7 803fa5cdb5 Remove custom standard lib
Why?? cause it was russian roulette with pointer access stuff etc
2025-12-17 10:02:05 +01:00
tobid7 66d3825481 bknd-3ds: implement libpicasso to load shader 2025-12-17 09:25:36 +01:00
tobid7 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
tobid7 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
72 changed files with 2116 additions and 1221 deletions
+334
View File
@@ -0,0 +1,334 @@
---
Language: Cpp
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: true
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AttributeMacros:
- __capability
- absl_nonnull
- absl_nullable
- absl_nullability_unknown
BinPackArguments: true
BinPackLongBracedList: true
BinPackParameters: BinPack
BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: Yes
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExportBlock: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
KeepFormFeed: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
OneLineFormatOffRegex: ''
PackConstructorInitializers: NextLine
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
PPIndentWidth: -1
QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: Always
RemoveBracesLLVM: false
RemoveEmptyLinesInUnwrappedLines: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes:
Enabled: true
IgnoreCase: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
WrapNamespaceBodyWithEmptyLines: Leave
...
+3
View File
@@ -1,3 +1,6 @@
[submodule "backends/desktop/glfw"] [submodule "backends/desktop/glfw"]
path = backends/desktop/glfw path = backends/desktop/glfw
url = https://github.com/glfw/glfw url = https://github.com/glfw/glfw
[submodule "backends/3ds/libpicasso"]
path = backends/3ds/libpicasso
url = https://github.com/npid7/libpicasso
+1 -1
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)
+1 -1
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
+3 -3
View File
@@ -1,13 +1,13 @@
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
source/bknd-hid.cpp source/bknd-hid.cpp
source/pd-3ds.cpp source/pd-3ds.cpp
) )
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libpicasso)
pd_add_lib(pd-3ds SRC_FILES ${SRC}) pd_add_lib(pd-3ds SRC_FILES ${SRC})
target_include_directories(pd-3ds PUBLIC include) target_include_directories(pd-3ds PUBLIC include)
target_link_libraries(pd-3ds PUBLIC m palladium ctru citro3d) target_link_libraries(pd-3ds PUBLIC m palladium ctru citro3d pica::pica)
+2 -1
View File
@@ -28,5 +28,6 @@ SOFTWARE.
#include <pd-3ds/bknd-hid.hpp> #include <pd-3ds/bknd-hid.hpp>
namespace PD { namespace PD {
PD::Li::Font::Ref LoadSystemFont();
void Init(void* data = nullptr); void Init(void* data = nullptr);
} } // namespace PD
+6 -14
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") {}
@@ -51,19 +42,20 @@ class GfxC3D : public GfxDriver {
void Deinit() override; void Deinit() override;
void NewFrame() override; void NewFrame() override;
void BindTex(PD::Li::TexAddress addr) override; void BindTex(PD::Li::TexAddress addr) override;
void RenderDrawData( void RenderDrawData(const PD::Li::CmdPool& Commands) override;
const std::vector<PD::Li::Command::Ref>& Commands) override;
PD::Li::Texture::Ref LoadTex( PD::Li::Texture::Ref LoadTex(
const std::vector<PD::u8>& pixels, int w, int h, const std::vector<PD::u8>& pixels, int w, int h,
PD::Li::Texture::Type type = PD::Li::Texture::Type::RGBA32, PD::Li::Texture::Type type = PD::Li::Texture::Type::RGBA32,
PD::Li::Texture::Filter filter = PD::Li::Texture::Filter filter =
PD::Li::Texture::Filter::LINEAR) override; PD::Li::Texture::Filter::LINEAR) override;
void DestroyTex(PD::Li::Texture::Ref tex) 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;
C3D_AttrInfo ShaderInfo; C3D_AttrInfo ShaderInfo;
std::vector<u8> pRawShader;
}; };
} // namespace PD } // namespace PD
@@ -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
+54 -35
View File
@@ -23,11 +23,8 @@ SOFTWARE.
*/ */
#include <pd-3ds/bknd-gfx.hpp> #include <pd-3ds/bknd-gfx.hpp>
#include <pica.hpp>
/// @brief Shader Code (Unused as i dont want to use libpicasso here (yet))
/// Update: Picasso breaks the linearRam or ram for somereason
/// as far as i found out loading anything into linear ram after
/// using libpicasso to compile a shader leads into a system freeze
const char* LIShaderCTR = R"( const char* LIShaderCTR = R"(
; LI7 Shader ; LI7 Shader
; Constants ; Constants
@@ -65,13 +62,6 @@ const char* LIShaderCTR = R"(
.end .end
)"; )";
// clang-format off
unsigned char li_shader[] = {
0x44, 0x56, 0x4c, 0x42, 0x1, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x50, 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x1, 0xf0, 0x7, 0x4e, 0x2, 0x8, 0x2, 0x8, 0x3, 0x18, 0x2, 0x8, 0x4, 0x28, 0x2, 0x8, 0x5, 0x38, 0x2, 0x8, 0x6, 0x10, 0x40, 0x4c, 0x7, 0xf1, 0x27, 0x22, 0x8, 0x10, 0x21, 0x4c, 0x0, 0x0, 0x0, 0x88, 0xac, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xd5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x45, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x1, 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x13, 0x0, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x0,
};
// clang-format on
size_t li_shader_size = 0x124;
namespace PD { namespace PD {
GPU_TEXCOLOR GetTexFmt(Li::Texture::Type type) { GPU_TEXCOLOR GetTexFmt(Li::Texture::Type type) {
if (type == Li::Texture::RGBA32) if (type == Li::Texture::RGBA32)
@@ -92,13 +82,40 @@ int GetBPP(Li::Texture::Type type) {
return 0; // Error return 0; // Error
} }
void FragCfg(GPU_TEXCOLOR clr) {
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
switch (clr) {
case GPU_A4:
case GPU_A8:
case GPU_L4:
case GPU_L8:
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
break;
case GPU_RGB565:
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE);
C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE);
break;
default:
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
break;
}
}
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;
ShaderCode = DVLB_ParseFile((uint32_t*)li_shader, li_shader_size); pRawShader = Pica::AssembleCode(LIShaderCTR);
ShaderCode = DVLB_ParseFile((uint32_t*)&pRawShader[0], pRawShader.size());
shaderProgramInit(&Shader); shaderProgramInit(&Shader);
shaderProgramSetVsh(&Shader, &ShaderCode->DVLE[0]); shaderProgramSetVsh(&Shader, &ShaderCode->DVLE[0]);
pLocProjection = pLocProjection =
@@ -130,8 +147,7 @@ void GfxC3D::BindTex(PD::Li::TexAddress addr) {
C3D_TexBind(0, reinterpret_cast<C3D_Tex*>(addr)); C3D_TexBind(0, reinterpret_cast<C3D_Tex*>(addr));
} }
void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) { void GfxC3D::RenderDrawData(const PD::Li::CmdPool& Commands) {
// C3D_BindProgram(&Shader);
shaderProgramUse(&Shader); shaderProgramUse(&Shader);
C3D_SetAttrInfo(&ShaderInfo); C3D_SetAttrInfo(&ShaderInfo);
C3D_Mtx proj; C3D_Mtx proj;
@@ -139,31 +155,26 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
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); // 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_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, (C3D_Mtx*)&proj);
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
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.GetCmd(index)->Tex;
if (!Tex) { if (!Tex) {
index++; index++;
continue; continue;
} }
bool ScissorEnabled = Commands[index]->ScissorOn; bool ScissorEnabled = Commands.GetCmd(index)->ScissorOn;
ivec4 ScissorRect = Commands[index]->ScissorRect; ivec4 ScissorRect = Commands.GetCmd(index)->ScissorRect;
size_t StartIndex = CurrentIndex; size_t StartIndex = CurrentIndex;
while (index < Commands.size() && Commands[index]->Tex == Tex && while (index < Commands.Size() && Commands.GetCmd(index)->Tex == Tex &&
Commands[index]->ScissorOn == ScissorEnabled && Commands.GetCmd(index)->ScissorOn == ScissorEnabled &&
Commands[index]->ScissorRect == ScissorRect) { Commands.GetCmd(index)->ScissorRect == ScissorRect) {
auto c = Commands[index].get(); auto c = Commands.GetCmd(index);
for (size_t i = 0; i < c->IndexBuffer.Size(); i++) { for (size_t i = 0; i < c->IndexBuffer.size(); i++) {
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++) {
VertexBuffer[CurrentVertex++] = c->VertexBuffer.At(i); VertexBuffer[CurrentVertex++] = c->VertexBuffer.at(i);
} }
index++; index++;
} }
@@ -176,13 +187,14 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
} else { } else {
C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0); C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0);
} }
FragCfg(((C3D_Tex*)Tex->Address)->fmt);
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);
} }
@@ -248,4 +260,11 @@ PD::Li::Texture::Ref GfxC3D::LoadTex(const std::vector<PD::u8>& pixels, int w,
<< std::endl; << std::endl;
return res; return res;
} }
void GfxC3D::DestroyTex(PD::Li::Texture::Ref tex) {
C3D_Tex* t = reinterpret_cast<C3D_Tex*>(tex->Address);
C3D_TexDelete(t);
delete t;
tex->Address = 0;
}
} // namespace PD } // namespace PD
+96
View File
@@ -22,10 +22,106 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include <3ds.h>
#include <palladium> #include <palladium>
#include <pd-3ds.hpp> #include <pd-3ds.hpp>
namespace PD { namespace PD {
PD::Li::Font::Ref LoadSystemFont() {
TT::Scope st("LI_SystemFont"); // Trace loading time
Li::Font::Ref ret = Li::Font::New();
fontEnsureMapped(); // Call this to be sure the font is mapped
// Get some const references for system font loading
const auto fnt = fontGetSystemFont();
const auto fnt_info = fontGetInfo(fnt);
const auto glyph_info = fontGetGlyphInfo(fnt);
// Resize the Texture list by the num of sysfont textures
ret->Textures.resize(glyph_info->nSheets + 1);
/// Modify the Pixel Height by 1.1f to fit the
/// Size og ttf font Rendering
ret->PixelHeight = glyph_info->cellHeight;
// Load the Textures and make sure they don't auto unload
for (size_t i = 0; i < glyph_info->nSheets; i++) {
auto stex = Li::Texture::New();
auto tx = new C3D_Tex;
tx->data = fontGetGlyphSheetTex(fnt, i);
tx->fmt = (GPU_TEXCOLOR)glyph_info->sheetFmt;
tx->size = glyph_info->sheetSize;
tx->width = glyph_info->sheetWidth;
tx->height = glyph_info->sheetHeight;
tx->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) |
GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) |
GPU_TEXTURE_WRAP_S(GPU_REPEAT) | GPU_TEXTURE_WRAP_T(GPU_REPEAT);
tx->border = 0xffffffff;
tx->lodParam = 0;
stex->Address = (Li::TexAddress)tx;
stex->Size = fvec2(tx->width, tx->height);
stex->UV = fvec4(0, 1, 1, 0);
ret->Textures[i] = stex;
}
std::vector<unsigned int> charSet;
// Write the Charset into a vector
for (auto cmap = fnt_info->cmap; cmap; cmap = cmap->next) {
if (cmap->mappingMethod == CMAP_TYPE_DIRECT) {
if (cmap->codeEnd >= cmap->codeBegin) {
charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1);
for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) {
if (cmap->indexOffset + (i - cmap->codeBegin) == 0xFFFF) break;
charSet.emplace_back(i);
}
}
} else if (cmap->mappingMethod == CMAP_TYPE_TABLE) {
if (cmap->codeEnd >= cmap->codeBegin) {
charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1);
for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) {
if (cmap->indexTable[i - cmap->codeBegin] == 0xFFFF) continue;
charSet.emplace_back(i);
}
}
} else if (cmap->mappingMethod == CMAP_TYPE_SCAN) {
charSet.reserve(charSet.size() + cmap->nScanEntries);
for (unsigned i = 0; i < cmap->nScanEntries; ++i) {
if (cmap->scanEntries[i].code >= cmap->codeBegin &&
cmap->scanEntries[i].code <= cmap->codeEnd) {
if (cmap->scanEntries[i].glyphIndex != 0xFFFF) {
charSet.emplace_back(cmap->scanEntries[i].code);
}
}
}
} else {
continue;
}
}
// Sort the charset and make sure all values are unique
std::sort(charSet.begin(), charSet.end());
charSet.erase(std::unique(charSet.begin(), charSet.end()));
// Setup the Codepoint map by the charset
for (auto cp : charSet) {
int gidx = fontGlyphIndexFromCodePoint(fnt, cp);
if (gidx >= 0xFFFF) continue;
Li::Font::Codepoint codepoint;
fontGlyphPos_s dat;
fontCalcGlyphPos(&dat, fnt, gidx, GLYPH_POS_CALC_VTXCOORD, 1.f, 1.f);
codepoint.pCodepoint = cp;
codepoint.SimpleUV = fvec4(dat.texcoord.left, dat.texcoord.top,
dat.texcoord.right, dat.texcoord.bottom);
if (dat.sheetIndex < (int)ret->Textures.size()) {
codepoint.Tex = ret->Textures[dat.sheetIndex];
} else {
codepoint.pInvalid = true;
}
codepoint.Size = fvec2(dat.vtxcoord.right, dat.vtxcoord.bottom);
codepoint.Offset = 0;
ret->CodeMap[cp] = codepoint;
}
return ret;
}
void Init(void* data) { void Init(void* data) {
// Dekstop Init Stage // Dekstop Init Stage
// First use default OS Driver // First use default OS Driver
+12
View File
@@ -2,6 +2,14 @@ cmake_minimum_required(VERSION 3.22)
project(pd-desktop LANGUAGES CXX VERSION 0.5.0) project(pd-desktop LANGUAGES CXX VERSION 0.5.0)
set(PD_GL_VERSION 21 CACHE STRING "OpenGL Version (2.1 -> 21, 3.3 -> 33)")
if(APPLE)
set(PD_GL_VERSION 33 CACHE STRING "33" FORCE)
endif()
message("Using OpenGL: " ${PD_GL_VERSION})
add_subdirectory(glad) add_subdirectory(glad)
add_subdirectory(glfw) add_subdirectory(glfw)
@@ -14,3 +22,7 @@ set(SRC
pd_add_lib(pd-desktop SRC_FILES ${SRC}) pd_add_lib(pd-desktop SRC_FILES ${SRC})
target_include_directories(pd-desktop PUBLIC include) target_include_directories(pd-desktop PUBLIC include)
target_link_libraries(pd-desktop PUBLIC palladium glad glfw) target_link_libraries(pd-desktop PUBLIC palladium glad glfw)
target_compile_definitions(pd-desktop
PRIVATE PD_OPENGL=${PD_GL_VERSION}
)
@@ -44,19 +44,47 @@ class GfxGL2 : public GfxDriver {
void Deinit() override; void Deinit() override;
void NewFrame() override; void NewFrame() override;
void BindTex(PD::Li::TexAddress addr) override; void BindTex(PD::Li::TexAddress addr) override;
void RenderDrawData( void RenderDrawData(const Li::CmdPool& Commands) override;
const std::vector<PD::Li::Command::Ref>& Commands) override;
PD::Li::Texture::Ref LoadTex( PD::Li::Texture::Ref LoadTex(
const std::vector<PD::u8>& pixels, int w, int h, const std::vector<PD::u8>& pixels, int w, int h,
PD::Li::Texture::Type type = PD::Li::Texture::Type::RGBA32, PD::Li::Texture::Type type = PD::Li::Texture::Type::RGBA32,
PD::Li::Texture::Filter filter = PD::Li::Texture::Filter filter =
PD::Li::Texture::Filter::LINEAR) override; PD::Li::Texture::Filter::LINEAR) override;
PD::Vec<Li::Vertex> VertexBuffer; std::vector<Li::Vertex> VertexBuffer;
PD::Vec<PD::u16> IndexBuffer; std::vector<PD::u16> IndexBuffer;
GLuint Shader; GLuint Shader;
GLuint pLocProjection; GLuint pLocProjection;
GLuint pLocTex; GLuint pLocTex;
GLuint VBO, IBO; GLuint pLocAlfa;
GLuint VBO, IBO, VAO; // vao is only used in > 3.3
};
class GfxGL3 : public GfxDriver2 {
public:
GfxGL3() : GfxDriver2("OpenGL3") {}
~GfxGL3() = default;
PD_SHARED(GfxGL3);
void Init() override;
void Deinit() override;
// void NewFrame() override;
void TexBind(PD::Li::TexAddress addr) override;
void Draw(const Li::CmdPool& pool) override;
PD::Li::TexAddress TexLoad(
const std::vector<PD::u8>& pixels, int w, int h,
PD::Li::Texture::Type type = PD::Li::Texture::Type::RGBA32,
PD::Li::Texture::Filter filter =
PD::Li::Texture::Filter::LINEAR) override;
void TexDelete(PD::Li::TexAddress tex) override;
std::vector<Li::Vertex> VertexBuffer;
std::vector<PD::u16> IndexBuffer;
GLuint Shader;
GLuint pLocProjection;
GLuint pLocTex;
GLuint pLocAlfa;
GLuint VBO, IBO, VAO; // vao is only used in > 3.3
}; };
} // namespace PD } // namespace PD
@@ -64,6 +64,7 @@ class HidGLFW : public HidDriver {
GLFWwindow* Window; GLFWwindow* Window;
int PrevState; int PrevState;
std::unordered_map<int, int> PrevStates; std::unordered_map<int, int> PrevStates;
static GLFWcharfun pOldTextCB;
static std::string* pText; static std::string* pText;
bool pInTextMode = false; bool pInTextMode = false;
PD::u64 pLastUpdate = 0; PD::u64 pLastUpdate = 0;
+265 -21
View File
@@ -25,6 +25,7 @@ SOFTWARE.
#include <pd-desktop/bknd-gfx.hpp> #include <pd-desktop/bknd-gfx.hpp>
namespace PD { namespace PD {
#if PD_OPENGL >= 21 && PD_OPENGL < 33
const char* vertex_shader = R"( const char* vertex_shader = R"(
#version 120 #version 120
@@ -53,12 +54,62 @@ const char* frag_shader = R"(
varying vec4 oColor; varying vec4 oColor;
uniform sampler2D tex; uniform sampler2D tex;
uniform bool alfa;
void main() { void main() {
vec4 tc = texture2D(tex, oUV); vec4 tc = texture2D(tex, oUV);
gl_FragColor = tc*oColor; if (alfa) {
gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a);
} else {
gl_FragColor = tc * oColor;
}
} }
)"; )";
#elif PD_OPENGL >= 33
const char* vertex_shader = R"(
#version 330 core
layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 uv;
layout(location = 2) in vec4 color;
out vec2 oUV;
out vec4 oColor;
// Probably forgot about this matrix and
// searched hours for why the rendering isn't working :/
uniform mat4 projection;
void main() {
gl_Position = projection*vec4(pos, 0.0, 1.0);
oUV = uv;
oColor = color;
}
)";
const char* frag_shader = R"(
#version 330 core
in vec2 oUV;
in vec4 oColor;
uniform sampler2D tex;
uniform bool alfa;
out vec4 FragColor;
void main() {
vec4 tc = texture(tex, oUV);
if (alfa) {
FragColor = vec4(oColor.rgb, tc.a * oColor.a);
} else {
FragColor = tc * oColor;
}
}
)";
#else
// Need to show error
#endif
GLuint compileShader(const std::string& source, GLenum type) { GLuint compileShader(const std::string& source, GLenum type) {
GLuint shader = glCreateShader(type); GLuint shader = glCreateShader(type);
@@ -123,30 +174,52 @@ void SetupShaderAttribs(GLuint Shader) {
/** Actual Backend */ /** Actual Backend */
void GfxGL2::Init() { void GfxGL2::Init() {
VertexBuffer.Resize(4 * 8192); VertexBuffer.resize(4 * 8192);
IndexBuffer.Resize(6 * 8192); IndexBuffer.resize(6 * 8192);
Shader = createShaderProgram(vertex_shader, frag_shader); Shader = createShaderProgram(vertex_shader, frag_shader);
glUseProgram(Shader); glUseProgram(Shader);
#if PD_OPENGL >= 33
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
#endif
glGenBuffers(1, &VBO); glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO);
// Attribs Setup #if PD_OPENGL < 33
SetupShaderAttribs(Shader); SetupShaderAttribs(Shader); // GL 2.1
#else
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, Pos));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, UV));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, Color));
#endif
glGenBuffers(1, &IBO); glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
pLocTex = glGetUniformLocation(Shader, "tex"); pLocTex = glGetUniformLocation(Shader, "tex");
pLocAlfa = glGetUniformLocation(Shader, "alfa");
pLocProjection = glGetUniformLocation(Shader, "projection"); pLocProjection = glGetUniformLocation(Shader, "projection");
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#if PD_OPENGL >= 33
glBindVertexArray(0);
#endif
} }
void GfxGL2::Deinit() { void GfxGL2::Deinit() {
glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &IBO); glDeleteBuffers(1, &IBO);
#if PD_OPENGL >= 33
glDeleteBuffers(1, &VAO);
#endif
} }
void GfxGL2::NewFrame() { void GfxGL2::NewFrame() {
@@ -172,29 +245,32 @@ void GfxGL2::BindTex(PD::Li::TexAddress addr) {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, (GLuint)addr); glBindTexture(GL_TEXTURE_2D, (GLuint)addr);
glUniform1i(pLocTex, 0); glUniform1i(pLocTex, 0);
GLint fmt = 0;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
} }
void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) { void GfxGL2::RenderDrawData(const Li::CmdPool& Commands) {
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::TexAddress Tex = Commands.GetCmd(index)->Tex;
if (!Tex) { if (!Tex) {
index++; index++;
continue; continue;
} }
size_t StartIndex = CurrentIndex; size_t StartIndex = CurrentIndex;
bool ScissorOn = Commands[index]->ScissorOn; bool ScissorOn = Commands.GetCmd(index)->ScissorOn;
ivec4 ScissorRect = Commands[index]->ScissorRect; ivec4 ScissorRect = Commands.GetCmd(index)->ScissorRect;
while (index < Commands.size() && Commands[index]->Tex == Tex && while (index < Commands.Size() && Commands.GetCmd(index)->Tex == Tex &&
Commands[index]->ScissorOn == ScissorOn && Commands.GetCmd(index)->ScissorOn == ScissorOn &&
Commands[index]->ScissorRect == ScissorRect) { Commands.GetCmd(index)->ScissorRect == ScissorRect) {
auto c = Commands[index].get(); auto c = Commands.GetCmd(index);
for (size_t i = 0; i < c->IndexBuffer.Size(); i++) { for (size_t i = 0; i < c->IndexBuffer.size(); i++) {
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++) {
VertexBuffer[CurrentVertex++] = c->VertexBuffer.At(i); VertexBuffer[CurrentVertex++] = c->VertexBuffer.at(i);
} }
index++; index++;
} }
@@ -205,13 +281,21 @@ void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
} else { } else {
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
} }
BindTex(Tex->Address); BindTex(Tex);
#if PD_OPENGL >= 33
glBindVertexArray(VAO);
#endif
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);
#if PD_OPENGL < 33
// For some reason we need to set these every frame for every buffer // For some reason we need to set these every frame for every buffer
// Found that out when creating My 3d Engine // Found that out when creating My 3d Engine
SetupShaderAttribs(Shader); SetupShaderAttribs(Shader);
#endif
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),
@@ -223,6 +307,9 @@ void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
BindTex(0); BindTex(0);
#if PD_OPENGL >= 33
glBindVertexArray(0);
#endif
} }
} }
@@ -253,4 +340,161 @@ 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;
} }
void GfxGL3::Init() {
VertexBuffer.resize(4 * 8192);
IndexBuffer.resize(6 * 8192);
Shader = createShaderProgram(vertex_shader, frag_shader);
glUseProgram(Shader);
#if PD_OPENGL >= 33
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
#endif
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
#if PD_OPENGL < 33
SetupShaderAttribs(Shader); // GL 2.1
#else
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, Pos));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, UV));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, Color));
#endif
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
pLocTex = glGetUniformLocation(Shader, "tex");
pLocAlfa = glGetUniformLocation(Shader, "alfa");
pLocProjection = glGetUniformLocation(Shader, "projection");
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#if PD_OPENGL >= 33
glBindVertexArray(0);
#endif
}
void GfxGL3::Deinit() {
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &IBO);
#if PD_OPENGL >= 33
glDeleteBuffers(1, &VAO);
#endif
}
// void NewFrame() {
//}
void GfxGL3::TexBind(PD::Li::TexAddress addr) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, (GLuint)addr);
glUniform1i(pLocTex, 0);
GLint fmt = 0;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
}
void GfxGL3::Draw(const Li::CmdPool& pool) {
size_t index = 0;
while (index < pool.Size()) {
PD::Li::TexAddress Tex = pool.GetCmd(index)->Tex;
if (Tex == 0) {
index++;
continue;
}
size_t StartIndex = CurrentIndex;
bool ScissorOn = pool.GetCmd(index)->ScissorOn;
ivec4 ScissorRect = pool.GetCmd(index)->ScissorRect;
while (index < pool.Size() && pool.GetCmd(index)->Tex == Tex &&
pool.GetCmd(index)->ScissorOn == ScissorOn &&
pool.GetCmd(index)->ScissorRect == ScissorRect) {
auto c = pool.GetCmd(index);
for (size_t i = 0; i < c->IndexBuffer.size(); i++) {
IndexBuffer[CurrentIndex++] = CurrentVertex + c->IndexBuffer.at(i);
}
for (size_t i = 0; i < c->VertexBuffer.size(); i++) {
VertexBuffer[CurrentVertex++] = c->VertexBuffer.at(i);
}
index++;
}
if (ScissorOn) {
glScissor(ScissorRect.x, ViewPort.y - (ScissorRect.y + ScissorRect.w),
ScissorRect.z, ScissorRect.w);
glEnable(GL_SCISSOR_TEST);
} else {
glDisable(GL_SCISSOR_TEST);
}
TexBind(Tex);
#if PD_OPENGL >= 33
glBindVertexArray(VAO);
#endif
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
&VertexBuffer[0], GL_DYNAMIC_DRAW);
#if PD_OPENGL < 33
// For some reason we need to set these every frame for every buffer
// Found that out when creating My 3d Engine
SetupShaderAttribs(Shader);
#endif
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
&IndexBuffer[0], GL_DYNAMIC_DRAW);
glDrawElements(GL_TRIANGLES, CurrentIndex - StartIndex, GL_UNSIGNED_SHORT,
(void*)(StartIndex * sizeof(PD::u16)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
TexBind(0);
#if PD_OPENGL >= 33
glBindVertexArray(0);
#endif
}
}
PD::Li::TexAddress GfxGL3::TexLoad(const std::vector<PD::u8>& pixels, int w,
int h, PD::Li::Texture::Type type,
PD::Li::Texture::Filter filter) {
GLuint texID;
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
// Set base format (Always using RGBA as base)
GLenum fmt = GL_RGBA;
if (type == PD::Li::Texture::Type::RGB24) {
fmt = GL_RGB;
} else if (type == PD::Li::Texture::Type::A8) {
fmt = GL_ALPHA;
}
glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
pixels.data());
if (filter == PD::Li::Texture::Filter::LINEAR) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else if (filter == PD::Li::Texture::Filter::NEAREST) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
glBindTexture(GL_TEXTURE_2D, 0);
return texID;
}
void GfxGL3::TexDelete(PD::Li::TexAddress tex) {
GLuint tex_ = tex;
glDeleteTextures(1, &tex_);
}
} // namespace PD } // namespace PD
+13 -3
View File
@@ -24,11 +24,21 @@ SOFTWARE.
#include <pd-desktop/bknd-hid.hpp> #include <pd-desktop/bknd-hid.hpp>
namespace PD { namespace PD {
std::string* HidGLFW::pText; std::string* HidGLFW::pText = nullptr;
GLFWcharfun HidGLFW::pOldTextCB = nullptr;
// Default Call back (If no Text input is requsted) // Default Call back (If no Text input is requsted)
void NullTextCB(GLFWwindow* win, unsigned int c) {} void NullTextCB(GLFWwindow* win, unsigned int c) {
// Chain
if (HidGLFW::pOldTextCB) {
HidGLFW::pOldTextCB(win, c);
}
}
// Text callback if requested // Text callback if requested
void TextCB(GLFWwindow* win, unsigned int c) { void TextCB(GLFWwindow* win, unsigned int c) {
// Chain
if (HidGLFW::pOldTextCB) {
HidGLFW::pOldTextCB(win, c);
}
if (!HidGLFW::pText) { if (!HidGLFW::pText) {
return; return;
} }
@@ -36,7 +46,7 @@ void TextCB(GLFWwindow* win, unsigned int c) {
} }
HidGLFW::HidGLFW(GLFWwindow* win) : HidDriver("HidGLFW") { HidGLFW::HidGLFW(GLFWwindow* win) : HidDriver("HidGLFW") {
Window = win; Window = win;
glfwSetCharCallback(Window, NullTextCB); HidGLFW::pOldTextCB = glfwSetCharCallback(Window, NullTextCB);
Flags |= Flags_HasKeyboard; Flags |= Flags_HasKeyboard;
Flags |= Flags_HasMouse; Flags |= Flags_HasMouse;
pBinds[GLFW_MOUSE_BUTTON_LEFT] = Touch; pBinds[GLFW_MOUSE_BUTTON_LEFT] = Touch;
+27 -9
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;
+14
View File
@@ -32,6 +32,7 @@ SOFTWARE.
#include <fstream> #include <fstream>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include <list>
#include <map> #include <map>
#include <memory> #include <memory>
#include <numbers> #include <numbers>
@@ -52,6 +53,16 @@ SOFTWARE.
return std::make_shared<x>(std::forward<Args>(args)...); \ return std::make_shared<x>(std::forward<Args>(args)...); \
} }
#define PD_RAW(x) \
using Ref = x*; \
template <typename... Args> \
static Ref New(Args&&... args) { \
x* v = new x; \
new (v) x(std::forward<Args>(args)...); \
return v; \
} \
static void Delete(Ref ref) { delete ref; }
#define PD_UNIQUE(x) \ #define PD_UNIQUE(x) \
using Ref = std::unique_ptr<x>; \ using Ref = std::unique_ptr<x>; \
template <typename... Args> \ template <typename... Args> \
@@ -62,6 +73,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;
+2 -1
View File
@@ -25,11 +25,12 @@ 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/strings.hpp> #include <pd/core/strings.hpp>
#include <pd/core/timer.hpp> #include <pd/core/timer.hpp>
#include <pd/core/timetrace.hpp> #include <pd/core/timetrace.hpp>
#include <pd/core/tween.hpp> #include <pd/core/tween.hpp>
#include <pd/core/u128.hpp>
#include <pd/core/vec.hpp> #include <pd/core/vec.hpp>
+23 -13
View File
@@ -2,8 +2,7 @@
/* /*
MIT License MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Copyright (c) 2024 - 2025 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
@@ -22,22 +21,33 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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.
*/ */
#include <pd/core/common.hpp> #include <pd/core/common.hpp>
namespace PD { namespace PD {
/** /**
* Function to get Arraysize for any type using modern c++ to * FNV-1a 32Bit hasing function
* get the size at compiletime instead of runtime * https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
* @note this function only works for Arrays declared as
* type arr[size] and not for pointer references.
* This function will precalculate the size at compile time
* while keeping the code clean to not hardcode arraysizes
* into functions like std::fill_n
*/ */
template <typename T, size_t N> constexpr u32 FNV1A32(std::string_view str) {
constexpr size_t ArraySize(T (&)[N]) noexcept { u32 ret = 0x811c9dc5; // Offset basis
return N; 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 } // namespace PD
-51
View File
@@ -1,51 +0,0 @@
#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 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 {
/**
* Custom Allocator for Custom Vec and probably other stuff in future
*/
template <typename T>
class Allocator {
public:
Allocator() = default;
~Allocator() = default;
virtual T* Allocate(size_t n) { return new T[n]; }
virtual T* AllocateRaw(size_t n) {
return reinterpret_cast<T*>(::operator new(sizeof(T) * n));
}
virtual void DeallocateRaw(T* ptr) { operator delete(ptr); }
virtual void Deallocate(T* ptr) { delete[] ptr; }
template <typename... Args>
void Construct(T* ptr, Args&&... args) {
new (ptr) T(std::forward<Args>(args)...);
}
void Destroy(T* ptr) { ptr->~T(); }
};
} // namespace PD
-71
View File
@@ -1,71 +0,0 @@
#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 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>
#include <pd/core/sl/list.hpp>
#include <pd/core/sl/pair.hpp>
namespace PD {
template <typename K, typename V, size_t bucket_count = 10>
class HashMap {
public:
HashMap() {}
~HashMap() {}
void Insert(const K& k, const V& v) {
size_t idx = Hash(k);
auto& bukket = pBuckets[idx];
for (auto& it : bukket) {
if (it.First == k) {
it.Second = v;
return;
}
}
bukket.PushBack(Pair(k, v));
}
bool Contains(const K& k) const {
size_t idx = Hash(k);
auto& bukket = pBuckets[idx];
for (auto& it : bukket) {
if (it.First == k) {
return true;
}
}
return false;
}
void Clear() {
for (size_t i = 0; i < bucket_count; i++) {
pBuckets[i].Clear();
}
}
size_t Hash(const K& k) const { return std::hash<K>{}(k) % bucket_count; }
PD::List<PD::Pair<K, V>> pBuckets[bucket_count];
};
} // namespace PD
-210
View File
@@ -1,210 +0,0 @@
#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 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 {
template <typename T>
class List {
public:
List() {}
~List() {}
struct Node {
Node(const T& v) : Data(v) {}
T Data;
Node* Prev = nullptr;
Node* Next = nullptr;
};
class Iterator {
public:
Iterator(Node* n) : pNode(n) {}
T& operator*() { return pNode->Data; }
Iterator& operator++() {
pNode = pNode->Next;
return *this;
}
bool operator!=(const Iterator& o) const { return pNode != o.pNode; }
Node* pNode = nullptr;
};
void PushFront(const T& val) {
Node* node = new Node(val);
// node->Data = val;
node->Prev = nullptr;
node->Next = pHead;
if (pHead) {
pHead->Prev = node;
}
pHead = node;
if (!pTail) {
pTail = node;
}
pSize++;
}
void PushBack(const T& val) {
Node* node = new Node(val);
// node->Data = val;
node->Prev = pTail;
node->Next = nullptr;
if (pTail) {
pTail->Next = node;
}
pTail = node;
if (!pHead) {
pHead = node;
}
pSize++;
}
void PopFront() {
if (!pHead) {
return;
}
Node* t = pHead;
pHead = pHead->Next;
if (pHead) {
pHead->Prev = nullptr;
} else {
pTail = nullptr;
}
delete t;
pSize--;
}
void PopBack() {
if (!pTail) {
return;
}
Node* t = pTail;
pTail = pTail->Prev;
if (pTail) {
pTail->Next = nullptr;
} else {
pHead = nullptr;
}
delete t;
pSize--;
}
void Clear() {
while (pHead) {
PopFront();
}
}
void Remove(const T& v) {
Node* s = pHead;
while (s) {
if (s->Data == v) {
if (s->Prev) {
s->Prev->Next = s->Next;
} else {
pHead = s->Next;
}
if (s->Next) {
s->Next->Prev = s->Prev;
} else {
pTail = s->Prev;
}
delete s;
pSize--;
return;
}
s = s->Next;
}
}
void Reverse() {
Node* cur = pHead;
while (cur) {
Node* temp = cur->Prev;
cur->Prev = cur->Next;
cur->Next = temp;
cur = cur->Prev;
}
Node* temp = pHead;
pHead = pTail;
pTail = temp;
}
T& Front() {
if (pHead) {
return pHead->Data;
}
// Need a List Empty Error Here (exceptions are disabled on 3ds)
exit(1);
}
const T& Front() const {
if (pHead) {
return pHead->Data;
}
// Need a List Empty Error Here (exceptions are disabled on 3ds)
exit(1);
}
T& Back() {
if (pTail) {
return pTail->Data;
}
// Need a List Empty Error Here (exceptions are disabled on 3ds)
exit(1);
}
const T& Back() const {
if (pTail) {
return pTail->Data;
}
// Need a List Empty Error Here (exceptions are disabled on 3ds)
exit(1);
}
size_t Size() const { return pSize; }
Iterator begin() { return Iterator(pHead); }
Iterator end() { return Iterator(nullptr); }
private:
Node* Find(const T& v) const {
Node* t = pHead;
while (t) {
if (t->Data == v) {
return t;
}
t = t->Next;
}
return nullptr;
}
Node* pHead = nullptr;
Node* pTail = nullptr;
size_t pSize = 0;
};
} // namespace PD
-34
View File
@@ -1,34 +0,0 @@
#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 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/sl/allocator.hpp>
#include <pd/core/sl/hashmap.hpp>
#include <pd/core/sl/list.hpp>
#include <pd/core/sl/pair.hpp>
#include <pd/core/sl/stack.hpp>
#include <pd/core/sl/tools.hpp>
#include <pd/core/sl/u128.hpp>
#include <pd/core/sl/vector.hpp>
-70
View File
@@ -1,70 +0,0 @@
#pragma once
/*
MIT License
Copyright (c) 2024 - 2025 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>
#include <pd/core/sl/vector.hpp>
namespace PD {
/**
* Custom Stack class (caus std::stack ofsten lead to memory coruption)
*/
template <typename T, typename Alloc = Allocator<T>>
class Stack {
public:
Stack() = default;
explicit Stack(size_t cap) : pVec(cap) {}
void Push(const T& val) { pVec.Add(val); }
void Pop() {
if (pVec.Size() == 0) {
exit(1);
}
pVec.PopBack();
}
T& Top() {
if (pVec.Size() == 0) {
exit(1);
}
return pVec[pVec.Size() - 1];
}
const T& Top() const {
if (pVec.Size() == 0) {
exit(1);
}
return pVec[pVec.Size() - 1];
}
bool IsEmpty() const { return pVec.Size() == 0; }
size_t Size() const { return pVec.Size(); }
void Clear() { pVec.Clear(); }
private:
Vec<T, Alloc> pVec;
};
} // namespace PD
-165
View File
@@ -1,165 +0,0 @@
#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>
#include <pd/core/sl/allocator.hpp>
namespace PD {
/**
* Open Access Vector class (Alternative to std::vector)
*/
template <typename T, typename Alloc = Allocator<T>>
class Vec {
public:
Vec() {
pData = pAllocator.Allocate(2);
pCap = 2;
Clear();
pPos = 0;
};
Vec(const size_t& Size) {
pData = pAllocator.Allocate(Size + 2);
pCap = Size + 2;
Clear();
pPos = Size;
}
Vec(const size_t& Size, const T& v) {
pData = pAllocator.Allocate(Size + 2);
pCap = Size + 2;
Clear();
pPos = Size;
std::fill_n(pData, Size, v);
}
Vec(const T* s, const T* e) {
pData = pAllocator.Allocate(2);
pCap = 2;
Clear();
pPos = 0;
Resize(e - s);
std::copy_n(s, e - s, pData);
}
Vec(const Vec& v) {
pCap = v.pCap;
pPos = v.pPos;
pData = pAllocator.Allocate(pCap);
for (size_t i = 0; i < pPos; i++) {
pData[i] = v.pData[i];
}
}
~Vec() { pAllocator.Deallocate(pData); }
void Add(const T& v) {
if (pPos >= pCap) {
Reserve(pCap * 2);
}
pData[pPos++] = v;
}
void PopBack() {
if (pPos == 0) return;
pPos--;
}
T Pop() {
if (pPos == 0) {
// Todo: LOG
exit(1);
}
return pData[pPos--];
}
T& At(const size_t& Idx) {
if (Idx >= pPos) {
// Log
exit(1);
}
return pData[Idx];
}
const T& At(const size_t& Idx) const {
if (Idx >= pPos) {
// Log
exit(1);
}
return pData[Idx];
}
T& operator[](const size_t& Idx) { return At(Idx); }
const T& operator[](const size_t& Idx) const { return At(Idx); }
void operator+=(T v) { Add(v); }
T* Begin() { return pData; }
const T* Begin() const { return pData; }
T* End() { return pData + pPos; }
const T* End() const { return pData + pPos; }
// Support: `for(auto& it : Vec)` //
T* begin() { return pData; }
const T* begin() const { return pData; }
T* end() { return pData + pPos; }
const T* end() const { return pData + pPos; }
T* Data() { return pData; }
T* Data() const { return pData; }
size_t Size() const { return pPos; }
size_t Capacity() const { return pCap; }
void Clear() {
// Avoid memset to support std::string for now
// probably revert this decision based if it lacks performance
// or make it a setting
std::fill(pData, pData + pCap, T());
pPos = 0;
}
void Reserve(const size_t& Size) {
if (Size <= pCap) return;
T* tmp = pAllocator.Allocate(Size);
std::fill(tmp, tmp + Size, T());
std::copy(pData, pData + pCap, tmp);
pAllocator.Deallocate(pData);
pData = tmp;
pCap = Size;
}
void Resize(size_t Size) {
if (Size < pPos) {
pPos = Size;
} else if (Size > pCap) {
Reserve(Size);
}
std::fill(pData + pPos, pData + Size, T());
pPos = Size;
}
// Allocator
Alloc pAllocator;
// Data Reference Pointer
T* pData;
// Capacity
size_t pCap;
// Current Position (Size)
size_t pPos;
};
} // namespace PD
+7
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
+5 -2
View File
@@ -151,7 +151,7 @@ namespace TT {
class Res { class Res {
public: public:
/** Constructore that Inits a protocol at size of 60 frames */ /** 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; ~Res() = default;
PD_SHARED(Res); PD_SHARED(Res);
@@ -182,6 +182,7 @@ class Res {
*/ */
void SetEnd(u64 v) { void SetEnd(u64 v) {
end = v; end = v;
diff = end - start;
protocol->Add(GetLastDiff()); protocol->Add(GetLastDiff());
} }
/** /**
@@ -194,7 +195,7 @@ class Res {
* Get Last Diffrence between end and start * Get Last Diffrence between end and start
* @return end - start * @return end - start
*/ */
u64 GetLastDiff() { return end - start; } u64 GetLastDiff() { return diff; }
/** /**
* Get Protcol Reference * Get Protcol Reference
* @return Protocol Ref * @return Protocol Ref
@@ -208,6 +209,8 @@ class Res {
u64 start; u64 start;
/** End Time */ /** End Time */
u64 end; u64 end;
/** Last Diff */
u64 diff;
/** Protocol */ /** Protocol */
TimeStats::Ref protocol; TimeStats::Ref protocol;
}; };
+11 -11
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
@@ -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
+32 -2
View File
@@ -34,6 +34,31 @@ enum LiBackendFlags_ {
}; };
namespace PD { namespace PD {
// The backend api nobody asked for
class GfxDriver2 {
public:
GfxDriver2(const std::string& name = "NullGfx") : pName(name) {};
~GfxDriver2() = default;
virtual void Init() {}
virtual void Deinit() {}
virtual void Draw(const PD::Li::CmdPool& pool) {}
virtual void TexBind(PD::Li::TexAddress addr) {}
virtual PD::Li::TexAddress TexLoad(
const std::vector<PD::u8>& pixels, int w, int h,
PD::Li::Texture::Type type = PD::Li::Texture::Type::RGBA32,
PD::Li::Texture::Filter filter = PD::Li::Texture::Filter::LINEAR) {
return 0;
}
virtual void TexDelete(PD::Li::TexAddress tex) {}
protected:
const std::string pName;
LiBackendFlags pFlags = 0;
size_t CurrentIndex = 0;
size_t CurrentVertex = 0;
ivec2 ViewPort;
};
class GfxDriver { class GfxDriver {
public: public:
GfxDriver(const std::string& name = "NullGfx") : pName(name) {}; GfxDriver(const std::string& name = "NullGfx") : pName(name) {};
@@ -49,7 +74,7 @@ class GfxDriver {
virtual void BindTex(Li::TexAddress addr) {} virtual void BindTex(Li::TexAddress addr) {}
virtual void RenderDrawData(const std::vector<Li::Command::Ref>& Commands) {} virtual void RenderDrawData(const Li::CmdPool& Commands) {}
void SetViewPort(const ivec2& vp) { ViewPort = vp; } void SetViewPort(const ivec2& vp) { ViewPort = vp; }
@@ -61,6 +86,8 @@ class GfxDriver {
return nullptr; return nullptr;
} }
virtual void DestroyTex(PD::Li::Texture::Ref tex) {}
Li::Texture::Ref GetSolidTex() { return pSolid; } Li::Texture::Ref GetSolidTex() { return pSolid; }
const std::string pName = "NullGfx"; const std::string pName = "NullGfx";
@@ -94,8 +121,9 @@ class Gfx {
static void BindTex(Li::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 SetViewPort(const ivec2& vp) { pGfx->SetViewPort(vp); }
static void SetViewPort(int w, int h) { pGfx->SetViewPort(PD::ivec2(w, h)); }
static void RenderDrawData(const std::vector<Li::Command::Ref>& Commands) { static void RenderDrawData(const Li::CmdPool& Commands) {
pGfx->RenderDrawData(Commands); pGfx->RenderDrawData(Commands);
} }
@@ -107,6 +135,8 @@ class Gfx {
return pGfx->LoadTex(pixels, w, h, type, filter); return pGfx->LoadTex(pixels, w, h, type, filter);
} }
static void DestroyTex(Li::Texture::Ref tex) { pGfx->DestroyTex(tex); }
static Li::Texture::Ref GetSolidTex() { return pGfx->GetSolidTex(); } static Li::Texture::Ref GetSolidTex() { return pGfx->GetSolidTex(); }
static GfxDriver::Ref pGfx; static GfxDriver::Ref pGfx;
+16 -12
View File
@@ -2,8 +2,7 @@
/* /*
MIT License MIT License
Copyright (c) 2024 - 2025 René Amthor (tobid7)
Copyright (c) 2024 - 2025 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
@@ -22,20 +21,25 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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.
*/ */
#include <pd/core/common.hpp> #include <pd/core/core.hpp>
namespace PD { namespace PD {
template <typename T1, typename T2> class Snd {
class Pair {
public: public:
Pair() = default; Snd(const std::string& name = "NullSnd") : pName(name) {};
Pair(const T1& f, const T2& s) : First(f), Second(s) {} ~Snd() = default;
Pair(T1&& f, T2&& s) : First(std::move(f)), Second(std::move(s)) {}
~Pair() = default;
T1 First; PD_SHARED(Snd);
T2 Second;
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 } // namespace PD
+1
View File
@@ -57,6 +57,7 @@ class PD_IMAGE_API Image {
int Width() const { return pWidth; } int Width() const { return pWidth; }
int Height() const { return pHeight; } int Height() const { return pHeight; }
ivec2 Size() const { return ivec2(pWidth, pHeight); }
Format Fmt() const { return pFmt; } Format Fmt() const { return pFmt; }
void FlipVertical(); void FlipVertical();
-23
View File
@@ -55,28 +55,5 @@ void RGB32toRGBA24(std::vector<u8> &out, const std::vector<u8> &in,
*/ */
PD_IMAGE_API void Reverse32(std::vector<u8> &buf, const int &w, const int &h); PD_IMAGE_API void Reverse32(std::vector<u8> &buf, const int &w, const int &h);
PD_IMAGE_API void ReverseBuf(std::vector<u8> &buf, size_t bpp, int w, int h); PD_IMAGE_API void ReverseBuf(std::vector<u8> &buf, size_t bpp, int w, int h);
/**
* Convert RGB24 to RGBA32 by adding a 4th alpha value set to 255
* to every pixel
* @param out Result List
* @param in Input Buffer List (rgb24)
* @param w width of the image
* @param h height of the image
*/
PD_IMAGE_API
void RGB24toRGBA32(PD::Vec<u8> &out, const PD::Vec<u8> &in, const int &w,
const int &h);
PD_IMAGE_API
void RGB32toRGBA24(PD::Vec<u8> &out, const PD::Vec<u8> &in, const int &w,
const int &h);
/**
* Reverse 32 (RGBA -> ABGR || ABGR -> RGBA)
* @param buf Buffer to convert
* @param w width
* @param h height
*/
PD_IMAGE_API void Reverse32(PD::Vec<u8> &buf, const int &w, const int &h);
PD_IMAGE_API void ReverseBuf(PD::Vec<u8> &buf, size_t bpp, int w, int h);
} // namespace ImgConvert } // namespace ImgConvert
} // namespace PD } // namespace PD
+53 -8
View File
@@ -24,6 +24,7 @@ SOFTWARE.
*/ */
#include <pd/core/core.hpp> #include <pd/core/core.hpp>
#include <pd/lithium/pd_p_api.hpp>
#include <pd/lithium/texture.hpp> #include <pd/lithium/texture.hpp>
#include <pd/lithium/vertex.hpp> #include <pd/lithium/vertex.hpp>
@@ -34,25 +35,69 @@ class Command {
Command() = default; Command() = default;
~Command() = default; ~Command() = default;
PD_UNIQUE(Command); PD_RAW(Command);
Command& AddIdx(const u16& idx) { Command& AddIdx(const u16& idx) {
IndexBuffer.Add(VertexBuffer.Size() + idx); IndexBuffer.push_back(VertexBuffer.size() + idx);
return *this;
}
Command& AddIdxs(const u16& a, const u16& b, const u16& c) {
IndexBuffer.push_back(VertexBuffer.size() + a);
IndexBuffer.push_back(VertexBuffer.size() + b);
IndexBuffer.push_back(VertexBuffer.size() + c);
return *this; return *this;
} }
Command& AddVtx(const Vertex& v) { Command& AddVtx(const Vertex& v) {
VertexBuffer.Add(std::move(v)); VertexBuffer.push_back(std::move(v));
return *this; return *this;
} }
PD::Vec<Vertex> VertexBuffer; void Clear() {
PD::Vec<u16> IndexBuffer; VertexBuffer.clear();
IndexBuffer.clear();
Index = 0;
Layer = 0;
Tex = 0;
ScissorOn = false;
ScissorRect = ivec4();
}
std::vector<Vertex> VertexBuffer;
std::vector<u16> IndexBuffer;
ivec4 ScissorRect; ivec4 ScissorRect;
bool ScissorOn = false; bool ScissorOn = false;
int Layer; int Layer = 0;
int Index; int Index = 0;
Texture::Ref Tex; TexAddress Tex;
};
class PD_LITHIUM_API CmdPool {
public:
CmdPool() {}
~CmdPool() {}
Command::Ref NewCmd();
void Init(size_t initial_size);
void Deinit();
void Resize(size_t nulen);
void Reset();
Command::Ref GetCmd(size_t idx) const;
Command::Ref GetCmd(size_t idx);
size_t Size() const;
size_t Cap() const;
void Merge(CmdPool& p);
void Copy(CmdPool& p);
void Sort();
private:
static bool pTheOrder(const Command::Ref& a, const Command::Ref& b);
friend class DrawList;
Command::Ref* begin() { return &pPool[0]; }
Command::Ref* end() { return &pPool[pPoolIdx - 1]; }
std::vector<Command::Ref> pPool;
u32 pPoolIdx = 0;
int Layer = 0;
}; };
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD
+43 -20
View File
@@ -48,8 +48,8 @@ namespace PD {
namespace Li { namespace Li {
class PD_LITHIUM_API DrawList { class PD_LITHIUM_API DrawList {
public: public:
DrawList() { DrawSolid(); } DrawList(int initial_size = 64);
~DrawList() { pDrawList.clear(); } ~DrawList();
/** Require Copy and Move Constructors */ /** Require Copy and Move Constructors */
@@ -64,14 +64,29 @@ class PD_LITHIUM_API DrawList {
/** /**
* Append an input drawlist on top of this one * Append an input drawlist on top of this one
* This Function will clear the Input list to make sure * This Function will clear the Input list to make sure
* THat the moved memory blocks don't get used * That the moved memory blocks don't get used
* @param list DrawList to move into current * @param list DrawList to move into current
*/ */
void Merge(DrawList::Ref list); void Merge(DrawList::Ref list);
/**
* Copy another drawlist to this drawist.
* This is important for static prerendered Drawlists
* @param list DrawList Reference to copy from
*/
void Copy(DrawList::Ref list);
/**
* Optimize a Drawlist to a more or less perfect order
* to reduce drawcall overhead... This function also uses
* the Layersystem to keep specific stuff in the correct order
*/
void Optimize();
Command::Ref PreGenerateCmd(); Command::Ref GetNewCmd();
void AddCommand(Command::Ref v);
void Clear(); void Clear();
void Layer(int l) { this->pPool.Layer = l; }
int Layer() { return this->pPool.Layer; }
void LayerUp() { this->pPool.Layer++; }
void LayerDown() { this->pPool.Layer--; }
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; }
@@ -97,7 +112,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
@@ -106,7 +121,7 @@ class PD_LITHIUM_API DrawList {
* @param flags Additional Flags (Close for go back to starting point) * @param flags Additional Flags (Close for go back to starting point)
* @param thickness Thickness of the Line * @param thickness Thickness of the Line
*/ */
void DrawPolyLine(const Vec<fvec2>& points, u32 clr, u32 flags = 0, void DrawPolyLine(const std::vector<fvec2>& points, u32 clr, u32 flags = 0,
int thickness = 1); int thickness = 1);
/** /**
* Take a List ofpoints and display it as Filled Shape * Take a List ofpoints and display it as Filled Shape
@@ -114,7 +129,7 @@ class PD_LITHIUM_API DrawList {
* @param points List of Points * @param points List of Points
* @param clr Color of the shape * @param clr Color of the shape
*/ */
void DrawConvexPolyFilled(const Vec<fvec2>& points, u32 clr); void DrawConvexPolyFilled(const std::vector<fvec2>& points, u32 clr);
// SECTION: PATH API // // SECTION: PATH API //
@@ -124,20 +139,28 @@ class PD_LITHIUM_API DrawList {
* @param num_points Number of Positions you want to add * @param num_points Number of Positions you want to add
*/ */
void PathReserve(size_t num_points) { void PathReserve(size_t num_points) {
pPath.Reserve(pPath.Size() + num_points); pPath.reserve(pPath.size() + num_points);
} }
/** /**
* Clear current Path * Clear current Path
* @note PathStroke and PathFill will automatically clear * @note PathStroke and PathFill will automatically clear
*/ */
void PathClear() { pPath.Clear(); } void PathClear() { pPath.clear(); }
/** /**
* Add a Point to the Path * Add a Point to the Path
* @note Keep in mind that this function is used for * @note Keep in mind that this function is used for
* setting the starting point * setting the starting point
* @param v Position to add * @param v Position to add
*/ */
void PathAdd(const fvec2& v) { pPath.Add(v); } void PathAdd(const fvec2& v) { pPath.push_back(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.push_back(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
@@ -148,7 +171,7 @@ class PD_LITHIUM_API DrawList {
*/ */
void PathStroke(u32 clr, int thickness = 1, u32 flags = 0) { void PathStroke(u32 clr, int thickness = 1, u32 flags = 0) {
DrawPolyLine(pPath, clr, flags, thickness); DrawPolyLine(pPath, clr, flags, thickness);
pPath.Clear(); pPath.clear();
} }
/** /**
* Fill a Path with a Color * Fill a Path with a Color
@@ -158,7 +181,7 @@ class PD_LITHIUM_API DrawList {
*/ */
void PathFill(u32 clr) { void PathFill(u32 clr) {
DrawConvexPolyFilled(pPath, clr); DrawConvexPolyFilled(pPath, clr);
pPath.Clear(); pPath.clear();
} }
void PathArcToN(const fvec2& c, float radius, float a_min, float a_max, void PathArcToN(const fvec2& c, float radius, float a_min, float a_max,
int segments); int segments);
@@ -175,25 +198,25 @@ class PD_LITHIUM_API DrawList {
/// @param flags DrawFlags (for special rounding rules) /// @param flags DrawFlags (for special rounding rules)
void PathRectEx(fvec2 a, fvec2 b, float rounding = 0.f, u32 flags = 0); void PathRectEx(fvec2 a, fvec2 b, float rounding = 0.f, u32 flags = 0);
void PushClipRect(const fvec4& cr) { pClipRects.Push(cr); } void PushClipRect(const fvec4& cr) { pClipRects.push(cr); }
void PopClipRect() { void PopClipRect() {
if (pClipRects.IsEmpty()) { if (pClipRects.empty()) {
return; return;
} }
pClipRects.Pop(); pClipRects.pop();
} }
const CmdPool& Data() const { return pPool; }
/** One linear Clip rect Setup */ /** One linear Clip rect Setup */
void pClipCmd(Command* cmd); void pClipCmd(Command* cmd);
/** Data Section */ /** Data Section */
Stack<fvec4> pClipRects; std::stack<fvec4> pClipRects;
int Layer;
float pFontScale = 0.7f; float pFontScale = 0.7f;
Font::Ref pCurrentFont; Font::Ref pCurrentFont;
Texture::Ref CurrentTex; Texture::Ref CurrentTex;
std::vector<Command::Ref> pDrawList; CmdPool pPool;
PD::Vec<fvec2> pPath; std::vector<fvec2> pPath;
u32 pNumIndices = 0; u32 pNumIndices = 0;
u32 pNumVertices = 0; u32 pNumVertices = 0;
}; };
+20 -2
View File
@@ -39,6 +39,7 @@ enum LiTextFlags_ {
LiTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS LiTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS
LiTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS LiTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS
LiTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long] LiTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
}; };
namespace PD { namespace PD {
@@ -92,15 +93,24 @@ class PD_LITHIUM_API Font {
/** /**
* Extended Draw Text Function that vreates a Command List * Extended Draw Text Function that vreates a Command List
*/ */
void CmdTextEx(std::vector<Command::Ref>& cmds, const fvec2& pos, u32 color, void CmdTextEx(CmdPool& cmds, const fvec2& pos, u32 color, float scale,
float scale, const std::string& text, LiTextFlags flags = 0, const std::string& text, LiTextFlags flags = 0,
const fvec2& box = 0); const fvec2& box = 0);
/**
* Garbage collection for TextMapSystem
*/
void CleanupTMS();
/** /**
* Utility function to create a font atlas * Utility function to create a font atlas
* During TTF loading (Internal and should not be called) * During TTF loading (Internal and should not be called)
*/ */
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);
std::string pShortText(const std::string& txt, float scale,
const PD::fvec2& max, PD::fvec2& dim);
/** Data Section */ /** Data Section */
int PixelHeight; int PixelHeight;
@@ -111,6 +121,14 @@ class PD_LITHIUM_API Font {
* **Now using unordered map** * **Now using unordered map**
*/ */
std::unordered_map<u32, Codepoint> CodeMap; std::unordered_map<u32, Codepoint> CodeMap;
/** TMS */
struct TMELEM {
PD::u32 ID;
PD::fvec2 Size;
std::string Text;
u64 TimeStamp;
};
std::unordered_map<u32, TMELEM> pTMS;
}; };
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD
+2
View File
@@ -131,6 +131,8 @@ class Rect {
return *this; return *this;
} }
bool operator==(Rect& r) { return Top == r.Top && Bot == r.Bot; }
void SwapVec2XY() { void SwapVec2XY() {
Top.SwapXY(); Top.SwapXY();
Top.SwapZW(); Top.SwapZW();
+5 -4
View File
@@ -46,10 +46,11 @@ class PD_LITHIUM_API Renderer {
u32 color); u32 color);
static void CmdTriangle(Command* cmd, const fvec2 a, const fvec2 b, static void CmdTriangle(Command* cmd, const fvec2 a, const fvec2 b,
const fvec2 c, u32 clr); const fvec2 c, u32 clr);
static void CmdPolyLine(const Vec<fvec2>& points, u32 clr, u32 flags = 0, static void CmdPolyLine(const std::vector<fvec2>& points, u32 clr,
int thickness = 1); u32 flags = 0, int thickness = 1);
static void CmdConvexPolyFilled(Command* cmd, const Vec<fvec2>& points, static void CmdConvexPolyFilled(Command* cmd,
u32 clr, Texture::Ref tex); const std::vector<fvec2>& points, u32 clr,
Texture::Ref tex);
// SECTION: InBounds Checks // SECTION: InBounds Checks
+2
View File
@@ -38,6 +38,8 @@ class Vertex {
} }
~Vertex() {} ~Vertex() {}
PD_RAW(Vertex);
// private: // private:
/** Open Access Data Section */ /** Open Access Data Section */
+8 -6
View File
@@ -39,13 +39,15 @@ class PD_UI7_API Image : public Container {
*/ */
Image(Li::Texture::Ref img, fvec2 size = 0.f, Li::Rect uv = fvec4(0.f)) { Image(Li::Texture::Ref img, fvec2 size = 0.f, Li::Rect uv = fvec4(0.f)) {
this->img = img; this->img = img;
this->newsize = size; if (size == fvec2(0.f)) {
this->cuv = uv; size = img->GetSize();
if (size.x != 0 || size.y != 0) {
this->SetSize(size);
} else {
this->SetSize(fvec2(img->GetSize().x, img->GetSize().y));
} }
if (uv == Li::Rect(fvec4(0.f))) {
uv = img->GetUV();
}
this->cuv = uv;
this->newsize = size;
SetSize(size);
} }
~Image() = default; ~Image() = default;
+4
View File
@@ -51,6 +51,10 @@ class PD_UI7_API Label : public Container {
* @note This function is usally called by Menu::Update * @note This function is usally called by Menu::Update
* */ * */
void Draw() override; void Draw() override;
/**
* Override Update func to support Text modifications
*/
void Update() override;
private: private:
fvec2 tdim; ///< Text Size fvec2 tdim; ///< Text Size
+91
View File
@@ -0,0 +1,91 @@
#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/ui7/container/container.hpp>
#include <pd/ui7/io.hpp>
namespace PD {
namespace UI7 {
/**
* Slider Object can take a datatype or a list
* and modifys these by moving left or right when dragging
*/
template <typename T>
class PD_UI7_API Slider : public Container {
public:
/**
* Constructor
* @param label Label of the Button
* @param data Data reference (Supported types can be seen in Slider.cpp)
* @param num_elms Number of Array elements (for exaple with use ofvec4)
* @param io IO Reference
* @param min minimum number using Minimum limit
* @param max Maximum number set by max limit by default
* @param step To set the modifier for drag movement
* @param precision for float and double to set precision
*/
Slider(const std::string& label, T* data, UI7::IO::Ref io,
T min = std::numeric_limits<T>::min(),
T max = std::numeric_limits<T>::max(), int precision = 1) {
// PD::Assert(data != nullptr, "Input Data Address is null!");
this->label = label;
this->data = data;
this->min = min;
this->max = max;
this->precision = precision;
this->width = io->CurrentViewPort.z * 0.3f;
this->tdim = io->Font->GetTextBounds(label, io->FontScale);
}
~Slider() = default;
/** Als ob das funktioniert... */
PD_SHARED(Slider<T>);
/**
* Override for the Input Handler
* @note This function is usally called by Menu::Update
*/
void HandleInput() override;
/**
* Override for the Rendering Handler
* @note This function is usally called by Menu::Update
* */
void Draw() override;
/** Function to Update Size if framepadding changes */
void Update() override;
private:
fvec2 tdim; ///< Text size
float width; ///< Size
std::string label; ///< Label of the Button
T* data;
T min;
T max;
int precision = 1;
float slw = 0.f; // silider drag width (calculated in update)
float slp = 0.f; // silider drag pos (calculated in update)
};
} // namespace UI7
} // namespace PD
+1
View File
@@ -30,3 +30,4 @@ SOFTWARE.
#include <pd/ui7/container/dynobj.hpp> #include <pd/ui7/container/dynobj.hpp>
#include <pd/ui7/container/image.hpp> #include <pd/ui7/container/image.hpp>
#include <pd/ui7/container/label.hpp> #include <pd/ui7/container/label.hpp>
#include <pd/ui7/container/slider.hpp>
+3 -2
View File
@@ -47,8 +47,9 @@ enum UI7MenuFlags_ {
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 // POC
UI7MenuFlags_Maximize = 1 << 11, ///< Add a Maximize Button UI7MenuFlags_Maximize = 1 << 11, ///< Add a Maximize Button
UI7MenuFlags_Minimize = 1 << 12, ///< Add a Minimize Button UI7MenuFlags_Minimize = 1 << 12, ///< Add a Minimize Button
UI7MenuFlags_AlwaysAutoSize = 1 << 13, ///< Always Auto Resize Menu
// Enable Horizontal and Vertical Scrolling // Enable Horizontal and Vertical Scrolling
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling, UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
}; };
+8 -5
View File
@@ -38,6 +38,7 @@ class ID {
*/ */
ID(const std::string& text) { ID(const std::string& text) {
pID = PD::Strings::FastHash(text); pID = PD::Strings::FastHash(text);
// pStrName = text;
pName = text; pName = text;
} }
/** /**
@@ -45,8 +46,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 +57,18 @@ 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 pName; ///< Name
// std::string pStrName; ///< Keep this stringview alive
}; };
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD
+7 -5
View File
@@ -73,25 +73,27 @@ class PD_UI7_API IO {
UI7::Theme::Ref Theme; UI7::Theme::Ref Theme;
fvec2 MenuPadding = 5.f; fvec2 MenuPadding = 5.f;
fvec2 FramePadding = 5.f; fvec2 FramePadding = 5.f;
float ItemRowHeight = 0.f;
float FrameRounding = 0.f;
fvec2 ItemSpace = vec2(5.f, 2.f); fvec2 ItemSpace = vec2(5.f, 2.f);
fvec2 MinSliderDragSize = 10.f; // Min height (Vt) and Min Width (Hz) fvec2 MinSliderDragSize = 10.f; // Min height (Vt) and Min Width (Hz)
bool ShowMenuBorder = true; bool ShowMenuBorder = true;
bool ShowFrameBorder = false; // not implemented yet bool ShowFrameBorder = false; // not implemented yet
bool WrapLabels = false; // Beta state
float OverScrollMod = 0.15f; float OverScrollMod = 0.15f;
u64 DoubleClickTime = 500; // Milliseconds u64 DoubleClickTime = 500; // Milliseconds
PD::List<Pair<UI7::ID, Li::DrawList::Ref>> DrawListRegestry; std::list<std::pair<UI7::ID, Li::DrawList::Ref>> DrawListRegestry;
// Short define for DrawKistRegestryLast // Short define for DrawKistRegestryLast
PD::List<Pair<UI7::ID, Li::DrawList::Ref>> pDLRL; std::list<std::pair<UI7::ID, Li::DrawList::Ref>> pDLRL;
// std::vector<std::pair<UI7::ID, Li::DrawList::Ref>> DrawListRegestry;
Li::DrawList::Ref Back; Li::DrawList::Ref Back;
Li::DrawList::Ref Front; Li::DrawList::Ref Front;
u32 NumVertices = 0; ///< Debug Vertices Num u32 NumVertices = 0; ///< Debug Vertices Num
u32 NumIndices = 0; ///< Debug Indices Num u32 NumIndices = 0; ///< Debug Indices Num
Vec<u32> MenuOrder; std::vector<u32> MenuOrder;
// DrawListApi // DrawListApi
void RegisterDrawList(const UI7::ID& id, Li::DrawList::Ref v) { void RegisterDrawList(const UI7::ID& id, Li::DrawList::Ref v) {
DrawListRegestry.PushBack(Pair(id, v)); DrawListRegestry.push_back(std::make_pair(id, v));
} }
void AddViewPort(const ID& id, const ivec4& size) { void AddViewPort(const ID& id, const ivec4& size) {
+80 -12
View File
@@ -26,6 +26,8 @@ SOFTWARE.
#include <pd/core/core.hpp> #include <pd/core/core.hpp>
#include <pd/ui7/container/container.hpp> #include <pd/ui7/container/container.hpp>
#include <pd/ui7/container/dragdata.hpp>
#include <pd/ui7/container/slider.hpp>
#include <pd/ui7/flags.hpp> #include <pd/ui7/flags.hpp>
#include <pd/ui7/input_api.hpp> #include <pd/ui7/input_api.hpp>
#include <pd/ui7/pd_p_api.hpp> #include <pd/ui7/pd_p_api.hpp>
@@ -35,7 +37,7 @@ namespace PD {
namespace UI7 { namespace UI7 {
class PD_UI7_API Layout { class PD_UI7_API Layout {
public: public:
Layout(const ID& id, IO::Ref io) : ID(id) { Layout(const ID &id, IO::Ref io) : ID(id) {
this->IO = io; this->IO = io;
DrawList = Li::DrawList::New(); DrawList = Li::DrawList::New();
DrawList->SetFont(IO->Font); DrawList->SetFont(IO->Font);
@@ -44,29 +46,93 @@ class PD_UI7_API Layout {
Scrolling[1] = false; Scrolling[1] = false;
CursorInit(); CursorInit();
Pos = fvec2(io->CurrentViewPort.x, io->CurrentViewPort.y); Pos = fvec2(io->CurrentViewPort.x, io->CurrentViewPort.y);
Size = fvec2(io->CurrentViewPort.z - io->CurrentViewPort.x, Size = 0;
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;
PD_SHARED(Layout); PD_SHARED(Layout);
const std::string& GetName() const { return ID.GetName(); } /** SECTION CONTAINERS */
const UI7::ID& GetID() const { return this->ID; } /**
* Render a Simple Label
* @param label The text to draw
*/
void Label(const std::string &label);
template <typename... Args>
void Label(std::format_string<Args...> s, Args &&...args) {
Label(std::format(s, std::forward<Args>(args)...));
}
/**
* Render a Button
* @param label The buttons text
* @return if the button was pressed
*/
bool Button(const std::string &label);
/**
* Render a Checkbox
* @param label Label of the Checkbox
* @param v A value to update
*/
void Checkbox(const std::string &label, bool &v);
/**
* Render an Image
* @param img Texture reference of the image
* @param size a Custom Size if needed
*/
void Image(Li::Texture::Ref img, fvec2 size = 0.f, Li::Rect uv = fvec4(0));
/**
* Render a Drag Object witth any supported type:
* [`int`, `float`, `double`, `u8`, `u16`, `u32`]
* @param label Name of the Drag
* @param data Reference to Data Object (can be multiple as well)
* @param num_elements Defien the number of Elements in the Data addr
* @param precission Difine the Format string len for float/double
*/
template <typename T>
void DragData(const std::string &label, T *data, size_t num_elms = 1,
T min = std::numeric_limits<T>::min(),
T max = std::numeric_limits<T>::max(), T step = 1,
int precision = 1) {
u32 id = Strings::FastHash("drd" + label + std::to_string((uintptr_t)data));
Container::Ref r = FindObject(id);
if (!r) {
r = UI7::DragData<T>::New(label, data, num_elms, this->IO, min, max, step,
precision);
r->SetID(id);
}
AddObject(r);
}
template <typename T>
void Slider(const std::string &label, T *data,
T min = std::numeric_limits<T>::min(),
T max = std::numeric_limits<T>::max(), int precision = 1) {
u32 id = Strings::FastHash("drd" + label + std::to_string((uintptr_t)data));
Container::Ref r = FindObject(id);
if (!r) {
r = UI7::Slider<T>::New(label, data, this->IO, min, max, precision);
r->SetID(id);
}
AddObject(r);
}
const fvec2& GetPosition() const { return Pos; } /** SECTION OTHERSTUFF */
void SetPosition(const fvec2& v) { Pos = v; }
const fvec2& GetSize() const { return Size; } const std::string GetName() const { return ID.GetName(); }
void SetSize(const fvec2& v) { Size = v; } const UI7::ID &GetID() const { return this->ID; }
const fvec2 &GetPosition() const { return Pos; }
void SetPosition(const fvec2 &v) { Pos = v; }
const fvec2 &GetSize() const { return Size; }
void SetSize(const fvec2 &v) { Size = v; }
Li::DrawList::Ref GetDrawList() { return DrawList; } Li::DrawList::Ref GetDrawList() { return DrawList; }
void CursorInit(); void CursorInit();
void SameLine(); void SameLine();
void CursorMove(const fvec2& size); void CursorMove(const fvec2 &size);
bool ObjectWorkPos(fvec2& movpos); bool ObjectWorkPos(fvec2 &movpos);
/** /**
* Extended Object Add Func to Add Object in Front or disable * Extended Object Add Func to Add Object in Front or disable
@@ -103,6 +169,8 @@ class PD_UI7_API Layout {
void Update(); void Update();
fvec2 DbgScrollOffset() { return ScrollOffset; }
private: private:
friend class Menu; friend class Menu;
friend class Context; friend class Context;
@@ -135,7 +203,7 @@ class PD_UI7_API Layout {
bool Scrolling[2]; bool Scrolling[2];
// Objects // Objects
PD::List<Container::Ref> Objects; std::list<Container::Ref> Objects;
std::vector<Container::Ref> IDObjects; std::vector<Container::Ref> IDObjects;
}; };
} // namespace UI7 } // namespace UI7
+20
View File
@@ -25,6 +25,7 @@ SOFTWARE.
*/ */
#include <pd/core/core.hpp> #include <pd/core/core.hpp>
#include <pd/ui7/containers.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>
@@ -92,6 +93,19 @@ class PD_UI7_API Menu {
} }
pLayout->AddObject(r); pLayout->AddObject(r);
} }
template <typename T>
void Slider(const std::string &label, T *data,
T min = std::numeric_limits<T>::min(),
T max = std::numeric_limits<T>::max(), int precision = 1) {
u32 id = Strings::FastHash("drd" + label + std::to_string((uintptr_t)data));
Container::Ref r = pLayout->FindObject(id);
if (!r) {
r = UI7::Slider<T>::New(label, data, pIO, min, max, precision);
r->SetID(id);
}
pLayout->AddObject(r);
}
void ColorEdit(const std::string &label, u32 &clr);
void SameLine() { pLayout->SameLine(); } void SameLine() { pLayout->SameLine(); }
void Separator(); void Separator();
void SeparatorText(const std::string &label); void SeparatorText(const std::string &label);
@@ -103,6 +117,12 @@ class PD_UI7_API Menu {
void HandleTitlebarActions(); void HandleTitlebarActions();
void DrawBaseLayout(); void DrawBaseLayout();
void AddObject(PD::UI7::Container::Ref obj) { pLayout->AddObject(obj); }
void AddObjectEx(PD::UI7::Container::Ref obj, PD::u32 flags) {
pLayout->AddObjectEx(obj, flags);
}
Container::Ref FindObject(u32 id) { return pLayout->FindObject(id); }
void Update(); void Update();
/** Data Section */ /** Data Section */
+11 -8
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 {
@@ -55,18 +55,21 @@ class PD_UI7_API Context {
PD_SHARED(Context); PD_SHARED(Context);
void AddViewPort(const ID &id, const ivec4 &vp); IO::Ref GetIO() { return pIO; }
void UseViewPort(const ID &id); void AddViewPort(const ID& id, const ivec4& vp);
void UseViewPort(const ID& id);
void Update(); void Update();
bool BeginMenu(const ID &id, UI7MenuFlags flags = 0, bool *pShow = nullptr); Menu::Ref BeginMenu(const ID& id, UI7MenuFlags flags = 0,
bool* pShow = nullptr);
Menu::Ref CurrentMenu() { return pCurrent; }
void EndMenu(); void EndMenu();
void AboutMenu(bool *show = nullptr); void AboutMenu(bool* show = nullptr);
void MetricsMenu(bool *show = nullptr); void MetricsMenu(bool* show = nullptr);
void StyleEditor(bool *show = nullptr); void StyleEditor(bool* show = nullptr);
Li::DrawList::Ref GetDrawData() { return pIO->FDL; } 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);
if (menu == pMenus.end()) { if (menu == pMenus.end()) {
pMenus[id] = Menu::New(id, pIO); pMenus[id] = Menu::New(id, pIO);
+1 -1
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
+1 -34
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;
@@ -65,7 +32,7 @@ PD_CORE_API std::string Color::Hex(bool rgba) const {
s << std::hex << std::setw(2) << std::setfill('0') << (int)r; s << std::hex << std::setw(2) << std::setfill('0') << (int)r;
s << std::hex << std::setw(2) << std::setfill('0') << (int)g; s << std::hex << std::setw(2) << std::setfill('0') << (int)g;
s << std::hex << std::setw(2) << std::setfill('0') << (int)b; s << std::hex << std::setw(2) << std::setfill('0') << (int)b;
if (rgba) { if (rgba || a != 255) { // QoL change btw
s << std::hex << std::setw(2) << std::setfill('0') << (int)a; s << std::hex << std::setw(2) << std::setfill('0') << (int)a;
} }
return s.str(); return s.str();
+1 -1
View File
@@ -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.1) project(pd-drivers LANGUAGES CXX VERSION 0.6.0)
set(SRC set(SRC
source/hid.cpp source/hid.cpp
-55
View File
@@ -79,59 +79,4 @@ PD_IMAGE_API void ReverseBuf(std::vector<u8> &buf, size_t bpp, int w, int h) {
} }
} }
} }
PD_IMAGE_API void RGB24toRGBA32(PD::Vec<u8> &out, const PD::Vec<u8> &in,
const int &w, const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int src = (y * w + x) * 3;
int dst = (y * w + x) * 4;
out[dst + 0] = in[src + 0];
out[dst + 1] = in[src + 1];
out[dst + 2] = in[src + 2];
out[dst + 3] = 255;
}
}
}
PD_IMAGE_API void RGB32toRGBA24(PD::Vec<u8> &out, const PD::Vec<u8> &in,
const int &w, const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int src = (y * w + x) * 4;
int dst = (y * w + x) * 3;
out[dst + 0] = in[src + 0];
out[dst + 1] = in[src + 1];
out[dst + 2] = in[src + 2];
}
}
}
PD_IMAGE_API void Reverse32(PD::Vec<u8> &buf, const int &w, const int &h) {
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int i = y * w + x;
u8 t0 = buf[i + 0];
u8 t1 = buf[i + 1];
buf[i + 0] = buf[i + 3];
buf[i + 1] = buf[i + 2];
buf[i + 3] = t0;
buf[i + 2] = t1;
}
}
}
PD_IMAGE_API void ReverseBuf(PD::Vec<u8> &buf, size_t bpp, int w, int h) {
PD::Vec<u8> cpy = buf;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pos = (y * w + x) * bpp;
for (size_t i = 0; i < bpp; i++) {
buf[pos + bpp - 1 - i] = cpy[pos + i];
}
}
}
}
} // namespace PD::ImgConvert } // namespace PD::ImgConvert
+2 -1
View File
@@ -1,10 +1,11 @@
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)
set(SRC set(SRC
source/command.cpp
source/drawlist.cpp source/drawlist.cpp
source/font.cpp source/font.cpp
source/fonts.cpp source/fonts.cpp
+81
View File
@@ -0,0 +1,81 @@
#include <pd/lithium/command.hpp>
PD_LITHIUM_API PD::Li::Command::Ref PD::Li::CmdPool::NewCmd() {
if (pPoolIdx >= pPool.size()) {
Resize(pPool.size() + 128);
}
Command::Ref nu = pPool[pPoolIdx++];
nu->Layer = Layer;
nu->Index = pPoolIdx - 1;
return nu;
}
PD_LITHIUM_API void PD::Li::CmdPool::Init(size_t initial_size) {
Resize(initial_size);
}
PD_LITHIUM_API void PD::Li::CmdPool::Deinit() {
for (auto it : pPool) {
Command::Delete(it);
}
pPool.clear();
}
PD_LITHIUM_API void PD::Li::CmdPool::Resize(size_t nulen) {
if (nulen <= pPool.size()) {
return; // no idea yet
}
size_t oldlen = pPool.size();
pPool.resize(nulen);
for (size_t i = oldlen; i < pPool.size(); i++) {
pPool[i] = Command::New();
}
}
PD_LITHIUM_API void PD::Li::CmdPool::Reset() {
for (u32 i = 0; i < pPoolIdx; i++) {
pPool[i]->Clear();
}
pPoolIdx = 0;
}
PD::Li::Command::Ref PD::Li::CmdPool::GetCmd(size_t idx) const {
return pPool[idx];
}
PD::Li::Command::Ref PD::Li::CmdPool::GetCmd(size_t idx) { return pPool[idx]; }
size_t PD::Li::CmdPool::Size() const { return pPoolIdx; }
size_t PD::Li::CmdPool::Cap() const { return pPool.size(); }
PD_LITHIUM_API void PD::Li::CmdPool::Merge(CmdPool& p) {
Copy(p);
p.Reset();
}
PD_LITHIUM_API void PD::Li::CmdPool::Copy(CmdPool& p) {
if (pPoolIdx + p.Size() > pPool.size()) {
Resize(pPoolIdx + p.Size());
}
for (size_t i = 0; i < p.Size(); i++) {
size_t idx = pPoolIdx++;
*pPool[idx] = *p.GetCmd(i);
pPool[idx]->Index = idx;
pPool[idx]->Layer += Layer;
}
}
PD_LITHIUM_API void PD::Li::CmdPool::Sort() {
if (pPoolIdx < 2) return;
std::sort(begin(), end(), pTheOrder);
}
PD_LITHIUM_API bool PD::Li::CmdPool::pTheOrder(const Command::Ref& a,
const Command::Ref& b) {
if (a->Layer == b->Layer) {
if (a->Tex == b->Tex) {
return a->Index < b->Index;
}
return a->Tex < b->Tex;
}
return a->Layer < b->Layer;
}
+83 -65
View File
@@ -31,47 +31,79 @@ SOFTWARE.
namespace PD { namespace PD {
namespace Li { namespace Li {
PD_LITHIUM_API DrawList::DrawList(int initial_size) {
DrawSolid();
pPool.Init(initial_size);
}
PD_LITHIUM_API DrawList::~DrawList() {
Clear();
pPool.Deinit();
}
PD_LITHIUM_API void DrawList::DrawSolid() { CurrentTex = Gfx::GetSolidTex(); } PD_LITHIUM_API void DrawList::DrawSolid() { CurrentTex = Gfx::GetSolidTex(); }
PD_LITHIUM_API void DrawList::Clear() { PD_LITHIUM_API void DrawList::Clear() {
pNumIndices = 0; pNumIndices = 0;
pNumVertices = 0; pNumVertices = 0;
pDrawList.clear(); pPool.Reset();
} pPath.clear();
if (pCurrentFont) {
PD_LITHIUM_API void DrawList::AddCommand(Command::Ref v) { pCurrentFont->CleanupTMS();
pNumIndices += v->IndexBuffer.Size(); }
pNumVertices += v->VertexBuffer.Size(); while (!pClipRects.empty()) {
pDrawList.push_back(std::move(v)); pClipRects.pop();
}
} }
PD_LITHIUM_API void DrawList::Merge(DrawList::Ref list) { PD_LITHIUM_API void DrawList::Merge(DrawList::Ref list) {
for (size_t i = 0; i < list->pDrawList.size(); i++) { pPool.Merge(list->pPool);
pNumIndices += list->pDrawList[i]->IndexBuffer.Size(); /*for (size_t i = 0; i < list->pDrawList.size(); i++) {
pNumVertices += list->pDrawList[i]->VertexBuffer.Size(); pNumIndices += list->pDrawList[i]->IndexBuffer.size();
pDrawList.push_back(std::move(list->pDrawList[i])); pNumVertices += list->pDrawList[i]->VertexBuffer.size();
} auto cmd = pPool.NewCmd();
pDrawList.push_back(list->pDrawList[i]);
}*/
/** Make sure The list gets cleared */ /** Make sure The list gets cleared */
list->Clear(); list->Clear();
} }
PD_LITHIUM_API Command::Ref DrawList::PreGenerateCmd() { PD_LITHIUM_API void DrawList::Copy(DrawList::Ref list) {
Command::Ref cmd = Command::New(); pPool.Copy(list->pPool);
cmd->Layer = Layer; }
cmd->Index = pDrawList.size();
cmd->Tex = CurrentTex; PD_LITHIUM_API void DrawList::Optimize() {
pClipCmd(cmd.get()); #ifndef NDEBUG
PD::TT::Scope s("Optimize");
#endif
/*std::sort(pDrawList.begin(), pDrawList.end(),
[](const PD::Li::Command::Ref &a, const PD::Li::Command::Ref &b) {
if (a->Layer == b->Layer) { // Same layer
if (a->Tex == b->Tex) { // same tex
return a->Index < b->Index;
}
return a->Tex < b->Tex; // order by address
}
return a->Layer < b->Layer; // Order by layer
});*/
}
PD_LITHIUM_API Command::Ref DrawList::GetNewCmd() {
Command::Ref cmd = pPool.NewCmd();
cmd->Index = pPool.Size() - 1;
cmd->Tex = CurrentTex->Address;
pClipCmd(cmd);
return cmd; return cmd;
} }
PD_LITHIUM_API void DrawList::pClipCmd(Command *cmd) { PD_LITHIUM_API void DrawList::pClipCmd(Command::Ref cmd) {
if (!pClipRects.IsEmpty()) { if (!pClipRects.empty()) {
cmd->ScissorOn = true; cmd->ScissorOn = true;
cmd->ScissorRect = ivec4(pClipRects.Top()); cmd->ScissorRect = ivec4(pClipRects.top());
} }
} }
PD_LITHIUM_API void DrawList::PathArcToN(const fvec2 &c, float radius, PD_LITHIUM_API void DrawList::PathArcToN(const fvec2& c, float radius,
float a_min, float a_max, float a_min, float a_max,
int segments) { int segments) {
// Path.push_back(c); // Path.push_back(c);
@@ -82,7 +114,7 @@ PD_LITHIUM_API void DrawList::PathArcToN(const fvec2 &c, float radius,
} }
} }
PD_LITHIUM_API void DrawList::PathFastArcToN(const fvec2 &c, float r, PD_LITHIUM_API void DrawList::PathFastArcToN(const fvec2& c, float r,
float amin, float amax, int s) { float amin, float amax, int s) {
/** /**
* Funcion with less division overhead * Funcion with less division overhead
@@ -178,19 +210,19 @@ PD_LITHIUM_API void DrawList::PathRectEx(fvec2 a, fvec2 b, float rounding,
} }
} }
PD_LITHIUM_API void DrawList::DrawRect(const fvec2 &pos, const fvec2 &size, PD_LITHIUM_API void DrawList::DrawRect(const fvec2& pos, const fvec2& size,
u32 color, int thickness) { u32 color, int thickness) {
PathRect(pos, pos + size); PathRect(pos, pos + size);
// Flags is currently hardcoded (1 = close) // Flags is currently hardcoded (1 = close)
PathStroke(color, thickness, 1); PathStroke(color, thickness, 1);
} }
void DrawList::DrawRectFilled(const fvec2 &pos, const fvec2 &size, u32 color) { void DrawList::DrawRectFilled(const fvec2& pos, const fvec2& size, u32 color) {
PathRect(pos, pos + size); PathRect(pos, pos + size);
PathFill(color); PathFill(color);
} }
PD_LITHIUM_API void DrawList::DrawTriangle(const fvec2 &a, const fvec2 &b, PD_LITHIUM_API void DrawList::DrawTriangle(const fvec2& a, const fvec2& b,
const fvec2 &c, u32 color, const fvec2& c, u32 color,
int thickness) { int thickness) {
PathAdd(a); PathAdd(a);
PathAdd(b); PathAdd(b);
@@ -198,15 +230,15 @@ PD_LITHIUM_API void DrawList::DrawTriangle(const fvec2 &a, const fvec2 &b,
PathStroke(color, thickness, 1); PathStroke(color, thickness, 1);
} }
PD_LITHIUM_API void DrawList::DrawTriangleFilled(const fvec2 &a, const fvec2 &b, PD_LITHIUM_API void DrawList::DrawTriangleFilled(const fvec2& a, const fvec2& b,
const fvec2 &c, u32 color) { const fvec2& c, u32 color) {
PathAdd(a); PathAdd(a);
PathAdd(b); PathAdd(b);
PathAdd(c); PathAdd(c);
PathFill(color); PathFill(color);
} }
PD_LITHIUM_API void DrawList::DrawCircle(const fvec2 &center, float rad, PD_LITHIUM_API void DrawList::DrawCircle(const fvec2& center, float rad,
u32 color, int num_segments, u32 color, int num_segments,
int thickness) { int thickness) {
if (num_segments <= 0) { if (num_segments <= 0) {
@@ -219,7 +251,7 @@ PD_LITHIUM_API void DrawList::DrawCircle(const fvec2 &center, float rad,
PathStroke(color, thickness, (1 << 0)); PathStroke(color, thickness, (1 << 0));
} }
PD_LITHIUM_API void DrawList::DrawCircleFilled(const fvec2 &center, float rad, PD_LITHIUM_API void DrawList::DrawCircleFilled(const fvec2& center, float rad,
u32 color, int num_segments) { u32 color, int num_segments) {
if (num_segments <= 0) { if (num_segments <= 0) {
// Auto Segment // Auto Segment
@@ -231,68 +263,54 @@ PD_LITHIUM_API void DrawList::DrawCircleFilled(const fvec2 &center, float rad,
} }
// TODO: Don't render OOS // TODO: Don't render OOS
PD_LITHIUM_API void DrawList::DrawPolyLine(const Vec<fvec2> &points, u32 clr, PD_LITHIUM_API void DrawList::DrawPolyLine(const std::vector<fvec2>& points,
u32 flags, int thickness) { u32 clr, u32 flags, int thickness) {
if (points.Size() < 2) { if (points.size() < 2) {
return; return;
} }
DrawSolid(); DrawSolid();
auto cmd = PreGenerateCmd(); auto cmd = GetNewCmd();
bool close = (flags & (1 << 0)); bool close = (flags & (1 << 0));
int num_points = close ? (int)points.Size() : (int)points.Size() - 1; int num_points = close ? (int)points.size() : (int)points.size() - 1;
if (flags & (1 << 1)) { if (flags & (1 << 1)) {
// TODO: Find a way to draw less garbage looking lines // TODO: Find a way to draw less garbage looking lines
} else { } else {
// Non antialiased lines look awful when rendering with thickness != 1 // Non antialiased lines look awful when rendering with thickness != 1
for (int i = 0; i < num_points; i++) { for (int i = 0; i < num_points; i++) {
int j = (i + 1) == (int)points.Size() ? 0 : (i + 1); int j = (i + 1) == (int)points.size() ? 0 : (i + 1);
auto line = Renderer::PrimLine(points[i], points[j], thickness); auto line = Renderer::PrimLine(points[i], points[j], thickness);
Renderer::CmdQuad(cmd.get(), line, vec4(0.f, 1.f, 1.f, 0.f), clr); Renderer::CmdQuad(cmd, line, vec4(0.f, 1.f, 1.f, 0.f), clr);
} }
} }
AddCommand(std::move(cmd));
} }
PD_LITHIUM_API void DrawList::DrawConvexPolyFilled(const Vec<fvec2> &points, PD_LITHIUM_API void DrawList::DrawConvexPolyFilled(
u32 clr) { const std::vector<fvec2>& points, u32 clr) {
if (points.Size() < 3) { if (points.size() < 3) {
return; // Need at least three points return; // Need at least three points
} }
auto cmd = PreGenerateCmd(); auto cmd = GetNewCmd();
Renderer::CmdConvexPolyFilled(cmd.get(), points, clr, CurrentTex); Renderer::CmdConvexPolyFilled(cmd, points, clr, CurrentTex);
AddCommand(std::move(cmd));
} }
PD_LITHIUM_API void DrawList::DrawText(const fvec2 &pos, PD_LITHIUM_API void DrawList::DrawText(const fvec2& pos,
const std::string &text, u32 color) { const std::string& text, u32 color) {
if (!pCurrentFont) { if (!pCurrentFont) {
return; return;
} }
std::vector<Command::Ref> cmds; pCurrentFont->CmdTextEx(pPool, pos, color, pFontScale, text);
pCurrentFont->CmdTextEx(cmds, pos, color, pFontScale, text);
for (size_t i = 0; i < cmds.size(); i++) {
cmds[i]->Index = pDrawList.size();
cmds[i]->Layer = Layer;
AddCommand(std::move(cmds[i]));
}
} }
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;
} }
std::vector<Command::Ref> cmds; pCurrentFont->CmdTextEx(pPool, p, color, pFontScale, text, flags, box);
pCurrentFont->CmdTextEx(cmds, p, color, pFontScale, text, flags, box);
for (size_t i = 0; i < cmds.size(); i++) {
cmds[i]->Index = pDrawList.size();
cmds[i]->Layer = Layer;
AddCommand(std::move(cmds[i]));
}
} }
PD_LITHIUM_API void DrawList::DrawLine(const fvec2 &a, const fvec2 &b, PD_LITHIUM_API void DrawList::DrawLine(const fvec2& a, const fvec2& b,
u32 color, int t) { u32 color, int t) {
PathAdd(a); PathAdd(a);
PathAdd(b); PathAdd(b);
+140 -26
View File
@@ -49,7 +49,7 @@ PD_LITHIUM_API void Font::LoadDefaultFont(int id, int pixel_height) {
#endif #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 * Just use LoadFile2Mem which looks way cleaner
* and helps not having the font loading code twice * and helps not having the font loading code twice
@@ -60,7 +60,7 @@ PD_LITHIUM_API void Font::LoadTTF(const std::string &path, int height) {
LoadTTF(font, height); LoadTTF(font, height);
} }
PD_LITHIUM_API void Font::pMakeAtlas(bool final, std::vector<u8> &font_tex, PD_LITHIUM_API void Font::pMakeAtlas(bool final, std::vector<u8>& font_tex,
int texszs, PD::Li::Texture::Ref tex) { int texszs, PD::Li::Texture::Ref tex) {
auto t = auto t =
Gfx::LoadTex(font_tex, texszs, texszs, Texture::RGBA32, Texture::LINEAR); Gfx::LoadTex(font_tex, texszs, texszs, Texture::RGBA32, Texture::LINEAR);
@@ -68,7 +68,7 @@ PD_LITHIUM_API void Font::pMakeAtlas(bool final, std::vector<u8> &font_tex,
Textures.push_back(tex); Textures.push_back(tex);
} }
PD_LITHIUM_API void Font::LoadTTF(const std::vector<u8> &data, int height) { PD_LITHIUM_API void Font::LoadTTF(const std::vector<u8>& data, int height) {
/** /**
* Some additional Info: * Some additional Info:
* Removed the stbtt get bitmapbox as we dont need to place * Removed the stbtt get bitmapbox as we dont need to place
@@ -107,7 +107,7 @@ PD_LITHIUM_API void Font::LoadTTF(const std::vector<u8> &data, int height) {
if (stbtt_IsGlyphEmpty(&inf, gi)) 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, ii, &w, &h, &xo, &yo); stbtt_GetCodepointBitmap(&inf, scale, scale, ii, &w, &h, &xo, &yo);
if (!bitmap || w <= 0 || h <= 0) { if (!bitmap || w <= 0 || h <= 0) {
if (bitmap) free(bitmap); if (bitmap) free(bitmap);
@@ -184,7 +184,7 @@ PD_LITHIUM_API void Font::LoadTTF(const std::vector<u8> &data, int height) {
} }
} }
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
auto res = CodeMap.find(cp); auto res = CodeMap.find(cp);
if (res == CodeMap.end()) { if (res == CodeMap.end()) {
@@ -195,7 +195,12 @@ PD_LITHIUM_API Font::Codepoint &Font::GetCodepoint(u32 cp) {
return res->second; return res->second;
} }
PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) { PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string& text, float scale) {
u32 id = PD::FNV1A32(text);
if (pTMS.find(id) != pTMS.end()) {
pTMS[id].TimeStamp = PD::OS::GetTime();
return pTMS[id].Size;
}
// Use wstring for exemple for german äöü // Use wstring for exemple for german äöü
auto wtext = Strings::MakeWstring(text); auto wtext = Strings::MakeWstring(text);
// Create a temp position and offset as [0, 0] // Create a temp position and offset as [0, 0]
@@ -205,7 +210,7 @@ PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) {
float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight; float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight;
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 == L'\0') { if (it == L'\0') {
break; break;
} }
@@ -237,19 +242,25 @@ PD_LITHIUM_API fvec2 Font::GetTextBounds(const std::string &text, float scale) {
} }
res.x = std::max(res.x, x); res.x = std::max(res.x, x);
res.y += lh; res.y += lh;
pTMS[id].ID = id;
pTMS[id].Size = res;
pTMS[id].TimeStamp = PD::OS::GetTime();
return res; return res;
} }
PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds, PD_LITHIUM_API void Font::CmdTextEx(CmdPool& cmds, const fvec2& pos, u32 color,
const fvec2 &pos, u32 color, float scale, float scale, const std::string& text,
const std::string &text, LiTextFlags flags, LiTextFlags flags, const fvec2& box) {
const fvec2 &box) {
fvec2 off; fvec2 off;
float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight; float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight;
float lh = (float)PixelHeight * cfs; float lh = (float)PixelHeight * cfs;
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,32 +272,44 @@ 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);
} }
for (auto &it : lines) { for (auto& it : lines) {
/*if (flags & LITextFlags_Short) { if (flags & LiTextFlags_NoOOS) {
if (rpos.y + off.y + lh < 0) {
off.y += lh;
continue;
}
if (rpos.y + off.y > box.y && box.y != 0) {
break;
}
}
if (flags & LiTextFlags_Short) {
fvec2 tmp_dim; fvec2 tmp_dim;
it = ShortText(it, box.x() - pos.x(), tmp_dim); it = pShortText(it, scale, box - pos, tmp_dim);
}*/ }
auto wline = Strings::MakeWstring(it); auto wline = Strings::MakeWstring(it);
auto cmd = Command::New(); auto cmd = cmds.NewCmd();
auto Tex = GetCodepoint(wline[0]).Tex; auto Tex = GetCodepoint(wline[0]).Tex;
cmd->Tex = Tex; if (Tex) {
for (auto &jt : wline) { cmd->Tex = Tex->Address;
}
for (auto& jt : wline) {
auto cp = GetCodepoint(jt); auto cp = GetCodepoint(jt);
if ((cp.pInvalid && jt != L' ' && jt != L'\n' && jt != L'\t') && if ((cp.pInvalid && jt != L' ' && jt != L'\n' && jt != L'\t') &&
jt != L'\r') { jt != L'\r') {
continue; continue;
} }
if (Tex != cp.Tex) { if (Tex != cp.Tex) {
cmds.push_back(std::move(cmd)); cmd = cmds.NewCmd();
cmd = Command::New();
Tex = cp.Tex; Tex = cp.Tex;
cmd->Tex = Tex; if (Tex) {
cmd->Tex = Tex->Address;
}
} }
if (jt == L'\t') { if (jt == L'\t') {
off.x += 16 * cfs; off.x += 16 * cfs;
@@ -295,25 +318,116 @@ PD_LITHIUM_API void Font::CmdTextEx(std::vector<Command::Ref> &cmds,
if (flags & LiTextFlags_Shaddow) { if (flags & LiTextFlags_Shaddow) {
// Draw // Draw
Rect rec = Renderer::PrimRect( Rect rec = Renderer::PrimRect(
rpos + vec2(off.x + 1, off.y + (cp.Offset * cfs)) + 1, rpos + fvec2(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, rec, cp.SimpleUV, 0xff111111);
} }
// Draw // Draw
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, rec, cp.SimpleUV, color);
off.x += cp.Size.x * cfs + 2 * cfs; off.x += cp.Size.x * cfs + 2 * cfs;
} else { } else {
off.x += 4 * cfs; off.x += 4 * cfs;
} }
} }
} }
cmds.push_back(std::move(cmd));
off.y += lh; off.y += lh;
off.x = 0; off.x = 0;
} }
} }
PD_LITHIUM_API std::string Font::pWrapText(const std::string& txt, float scale,
const PD::fvec2& max,
PD::fvec2& dim) {
u32 id = PD::FNV1A32(txt);
if (pTMS.find(id) != pTMS.end()) {
if (pTMS[id].Text.size()) {
dim = pTMS[id].Size;
pTMS[id].TimeStamp = PD::OS::GetTime();
return pTMS[id].Text;
}
}
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);
pTMS[id].ID = id;
pTMS[id].Size = dim;
pTMS[id].Text = ret;
pTMS[id].TimeStamp = PD::OS::GetTime();
return ret;
}
PD_LITHIUM_API std::string Font::pShortText(const std::string& txt, float scale,
const PD::fvec2& max,
PD::fvec2& dim) {
u32 id = PD::FNV1A32(txt);
if (pTMS.find(id) != pTMS.end()) {
if (pTMS[id].Text.size()) {
dim = pTMS[id].Size;
pTMS[id].TimeStamp = PD::OS::GetTime();
return pTMS[id].Text;
}
}
auto test = GetTextBounds(txt, scale);
if (test.x < max.x) {
return txt;
}
std::string ext;
std::string ph = "(...)"; // placeholder
std::string tmp = txt;
std::string ret;
auto maxlen = max.x;
size_t ext_ = tmp.find_last_of('.');
if (ext_ != tmp.npos) {
ext = tmp.substr(ext_);
tmp = tmp.substr(0, ext_);
}
maxlen -= GetTextBounds(ext, scale).x;
maxlen -= GetTextBounds(ph, scale).x;
for (auto& it : tmp) {
if (GetTextBounds(ret, scale).x > maxlen) {
ret += ph;
ret += ext;
dim = GetTextBounds(ret, scale);
return ret;
}
ret += it;
}
pTMS[id].ID = id;
pTMS[id].Size = dim;
pTMS[id].Text = ret;
pTMS[id].TimeStamp = PD::OS::GetTime();
return ret;
}
PD_LITHIUM_API void Font::CleanupTMS() {
u64 t = PD::OS::GetTime();
for (auto it = pTMS.begin(); it != pTMS.end();) {
if (t - it->second.TimeStamp > 1000) {
it = pTMS.erase(it);
} else {
it++;
}
}
}
} // namespace Li } // namespace Li
} // namespace PD } // namespace PD
+13 -13
View File
@@ -88,7 +88,7 @@ PD_LITHIUM_API Rect Renderer::PrimLine(const fvec2& a, const fvec2& b,
return Rect(a + off, b + off, a - off, b - off); return Rect(a + off, b + off, a - off, b - off);
} }
PD_LITHIUM_API void Renderer::CmdQuad(Command* cmd, const Rect& quad, PD_LITHIUM_API void Renderer::CmdQuad(Command::Ref cmd, const Rect& quad,
const Rect& uv, u32 color) { const Rect& uv, u32 color) {
cmd->AddIdx(0).AddIdx(1).AddIdx(2); cmd->AddIdx(0).AddIdx(1).AddIdx(2);
cmd->AddIdx(0).AddIdx(2).AddIdx(3); cmd->AddIdx(0).AddIdx(2).AddIdx(3);
@@ -98,7 +98,7 @@ PD_LITHIUM_API void Renderer::CmdQuad(Command* cmd, const Rect& quad,
cmd->AddVtx(Vertex(quad.BotLeft(), uv.BotLeft(), color)); cmd->AddVtx(Vertex(quad.BotLeft(), uv.BotLeft(), color));
} }
PD_LITHIUM_API void Renderer::CmdTriangle(Command* cmd, const fvec2 a, PD_LITHIUM_API void Renderer::CmdTriangle(Command::Ref cmd, const fvec2 a,
const fvec2 b, const fvec2 c, const fvec2 b, const fvec2 c,
u32 clr) { u32 clr) {
cmd->AddIdx(2).AddIdx(1).AddIdx(0); cmd->AddIdx(2).AddIdx(1).AddIdx(0);
@@ -110,10 +110,10 @@ PD_LITHIUM_API void Renderer::CmdTriangle(Command* cmd, const fvec2 a,
// TODO: Don't render OOS (Probably make it with a define as it // TODO: Don't render OOS (Probably make it with a define as it
// would probably be faster to render out of screen than checking if // would probably be faster to render out of screen than checking if
// it could be skipped) // it could be skipped)
PD_LITHIUM_API void Renderer::CmdConvexPolyFilled(Command* cmd, PD_LITHIUM_API void Renderer::CmdConvexPolyFilled(
const Vec<fvec2>& points, Command::Ref cmd, const std::vector<fvec2>& points, u32 clr,
u32 clr, Texture::Ref tex) { Texture::Ref tex) {
if (points.Size() < 3 || tex == nullptr) { if (points.size() < 3 || tex == nullptr) {
return; // Need at least three points return; // Need at least three points
} }
@@ -121,11 +121,11 @@ PD_LITHIUM_API void Renderer::CmdConvexPolyFilled(Command* cmd,
float minX = points[0].x, minY = points[0].y; float minX = points[0].x, minY = points[0].y;
float maxX = minX, maxY = minY; float maxX = minX, maxY = minY;
// Check for the max and min Positions // Check for the max and min Positions
for (auto it = points.Begin(); it != points.End(); it++) { for (const auto& it : points) {
if ((*it).x < minX) minX = (*it).x; if (it.x < minX) minX = it.x;
if ((*it).y < minY) minY = (*it).y; if (it.y < minY) minY = it.y;
if ((*it).x > maxX) maxX = (*it).x; if (it.x > maxX) maxX = it.x;
if ((*it).y > maxY) maxY = (*it).y; if (it.y > maxY) maxY = it.y;
} }
// Get Short defines for UV // Get Short defines for UV
// (Bottom Right is not required) // (Bottom Right is not required)
@@ -134,10 +134,10 @@ PD_LITHIUM_API void Renderer::CmdConvexPolyFilled(Command* cmd,
auto uv_bl = tex->UV.BotLeft(); auto uv_bl = tex->UV.BotLeft();
// Render // Render
for (int i = 2; i < (int)points.Size(); i++) { for (int i = 2; i < (int)points.size(); i++) {
cmd->AddIdx(0).AddIdx(i).AddIdx(i - 1); cmd->AddIdx(0).AddIdx(i).AddIdx(i - 1);
} }
for (int i = 0; i < (int)points.Size(); i++) { for (int i = 0; i < (int)points.size(); i++) {
// Calculate U and V coords // Calculate U and V coords
float u = float u =
uv_tl.x + ((points[i].x - minX) / (maxX - minX)) * (uv_tr.x - uv_tl.x); uv_tl.x + ((points[i].x - minX) / (maxX - minX)) * (uv_tr.x - uv_tl.x);
+2 -1
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
@@ -17,6 +17,7 @@ set(SRC
source/container/dynobj.cpp source/container/dynobj.cpp
source/container/image.cpp source/container/image.cpp
source/container/label.cpp source/container/label.cpp
source/container/slider.cpp
) )
if(PD_BUILD_SHARED) if(PD_BUILD_SHARED)
+4 -3
View File
@@ -49,11 +49,12 @@ PD_UI7_API void Button::HandleInput() {
PD_UI7_API void Button::Draw() { PD_UI7_API void Button::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);
list->DrawRectFilled(FinalPos(), size, io->Theme->Get(color)); list->PathRect(FinalPos(), FinalPos() + size, io->FrameRounding);
list->Layer++; list->PathFill(io->Theme->Get(color));
list->LayerUp();
list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label, list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label,
io->Theme->Get(UI7Color_Text)); io->Theme->Get(UI7Color_Text));
list->Layer--; list->LayerDown();
} }
PD_UI7_API void Button::Update() { PD_UI7_API void Button::Update() {
+5 -3
View File
@@ -48,10 +48,11 @@ PD_UI7_API void Checkbox::HandleInput() {
PD_UI7_API void Checkbox::Draw() { PD_UI7_API void Checkbox::Draw() {
// Assert(list.get() && io.get(), "Did you run Container::Init correctly?"); // Assert(list.get() && io.get(), "Did you run Container::Init correctly?");
// io->Ren->OnScreen(screen); // io->Ren->OnScreen(screen);
list->DrawRectFilled(FinalPos(), cbs, io->Theme->Get(color)); list->PathRect(FinalPos(), FinalPos() + cbs, io->FrameRounding);
list->PathFill(io->Theme->Get(color));
if (usr_ref) { if (usr_ref) {
list->DrawRectFilled(FinalPos() + 2, cbs - 4, list->PathRect(FinalPos() + 2, FinalPos() + cbs - 2, io->FrameRounding);
io->Theme->Get(UI7Color_Checkmark)); list->PathFill(io->Theme->Get(UI7Color_Checkmark));
} }
list->DrawText( list->DrawText(
FinalPos() + fvec2(cbs.x + io->ItemSpace.x, cbs.y * 0.5 - tdim.y * 0.5), FinalPos() + fvec2(cbs.x + io->ItemSpace.x, cbs.y * 0.5 - tdim.y * 0.5),
@@ -60,6 +61,7 @@ PD_UI7_API void Checkbox::Draw() {
PD_UI7_API void Checkbox::Update() { PD_UI7_API void Checkbox::Update() {
// Assert(io.get(), "Did you run Container::Init correctly?"); // Assert(io.get(), "Did you run Container::Init correctly?");
cbs = io->ItemRowHeight;
this->SetSize(cbs + fvec2(tdim.x + io->ItemSpace.x, 0)); this->SetSize(cbs + fvec2(tdim.x + io->ItemSpace.x, 0));
} }
} // namespace UI7 } // namespace UI7
+43 -9
View File
@@ -22,7 +22,7 @@ SOFTWARE.
*/ */
#include <pd/ui7/container/coloredit.hpp> #include <pd/ui7/container/coloredit.hpp>
#include <pd/ui7/container/label.hpp> #include <pd/ui7/containers.hpp>
namespace PD { namespace PD {
namespace UI7 { namespace UI7 {
@@ -33,8 +33,9 @@ PD_UI7_API void ColorEdit::HandleInput() {
} }
// Assert(screen.get(), "Screen is not set up!"); // Assert(screen.get(), "Screen is not set up!");
// if (screen->ScreenType() == Screen::Bottom) { // if (screen->ScreenType() == Screen::Bottom) {
if (io->InputHandler->DragObject(this->GetID(), fvec4(FinalPos(), size))) { if (io->InputHandler->DragObject(this->GetID() + 2,
if (io->InputHandler->DragReleased) { fvec4(FinalPos(), size))) {
if (io->InputHandler->DragReleasedAW) {
is_shown = !is_shown; is_shown = !is_shown;
} }
} }
@@ -44,22 +45,55 @@ PD_UI7_API void ColorEdit::HandleInput() {
PD_UI7_API void ColorEdit::Draw() { PD_UI7_API void ColorEdit::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);
list->DrawRectFilled(FinalPos(), fvec2(20, 20), *color_ref); list->PathRect(FinalPos(), FinalPos() + io->ItemRowHeight, io->FrameRounding);
list->DrawText(FinalPos() + fvec2(io->ItemSpace.x + 20, 0), label, list->PathFill(*color_ref);
io->Theme->Get(UI7Color_Text)); list->DrawText(FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
label, io->Theme->Get(UI7Color_Text));
if (is_shown) { if (is_shown) {
if (!layout) { if (!layout) {
layout = Layout::New(GetID(), io); layout = Layout::New(GetID(), io);
} }
layout->AddObject(Label::New("Hello World!", io)); layout->SetPosition(FinalPos());
layout->AddObjectEx(
DynObj::New(
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, Container* thiz) {
thiz->SetSize(layout->GetSize());
l->Layer(30);
l->PathRect(thiz->GetPos(), thiz->GetPos() + thiz->GetSize(),
io->FrameRounding);
l->PathFill(io->Theme->Get(UI7Color_FrameBackground));
}),
UI7LytAdd_Front | UI7LytAdd_NoCursorUpdate | UI7LytAdd_NoScrollHandle);
auto obj = DynObj::New(
[=, this](UI7::IO::Ref io, Li::DrawList::Ref l, Container* thiz) {
l->PathRect(thiz->FinalPos(), thiz->FinalPos() + io->ItemRowHeight,
io->FrameRounding);
l->PathFill(*color_ref);
l->DrawText(
thiz->FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
label, io->Theme->Get(UI7Color_Text));
});
obj->SetSize(PD::fvec2(200, io->ItemRowHeight));
layout->AddObject(obj);
layout->Label("RGBA: ({}, {}, {}, {})", *((u8*)color_ref),
*(((u8*)color_ref) + 1), *(((u8*)color_ref) + 2),
*(((u8*)color_ref) + 3));
layout->Label("Hex: {}", PD::Color(*color_ref).Hex(true));
layout->Slider<u8>("R", ((u8*)color_ref));
layout->Slider<u8>("G", ((u8*)color_ref) + 1);
layout->Slider<u8>("B", ((u8*)color_ref) + 2);
layout->Slider<u8>("A", ((u8*)color_ref) + 3);
layout->Update(); layout->Update();
io->RegisterDrawList(GetID(), layout->GetDrawList()); list->Merge(layout->GetDrawList());
// io->RegisterDrawList(GetID(), layout->GetDrawList());
} }
} }
PD_UI7_API void ColorEdit::Update() { PD_UI7_API void ColorEdit::Update() {
// Assert(io.get(), "Did you run Container::Init correctly?"); // Assert(io.get(), "Did you run Container::Init correctly?");
this->SetSize(fvec2(tdim.x + io->ItemSpace.x + 20, 20)); this->SetSize(
fvec2(tdim.x + io->ItemSpace.x + io->ItemRowHeight, io->ItemRowHeight));
} }
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD
+6 -4
View File
@@ -81,13 +81,15 @@ PD_UI7_API void DragData<T>::Draw() {
p = std::format("{}", data[i]); p = std::format("{}", data[i]);
} }
vec2 td = io->Font->GetTextBounds(p, io->FontScale); vec2 td = io->Font->GetTextBounds(p, io->FontScale);
list->DrawRectFilled(FinalPos() + fvec2(off_x, 0), td + io->FramePadding, list->PathRect(FinalPos() + fvec2(off_x, 0),
io->Theme->Get(UI7Color_Button)); FinalPos() + fvec2(off_x, 0) + td + io->FramePadding,
list->Layer++; io->FrameRounding);
list->PathFill(io->Theme->Get(UI7Color_Button));
list->LayerUp();
list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p, list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p,
io->Theme->Get(UI7Color_Text), LiTextFlags_AlignMid, io->Theme->Get(UI7Color_Text), LiTextFlags_AlignMid,
td + io->FramePadding); td + io->FramePadding);
list->Layer--; list->LayerDown();
off_x += td.x + io->ItemSpace.x + io->FramePadding.x; off_x += td.x + io->ItemSpace.x + io->FramePadding.x;
} }
list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5), label, list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5), label,
+2 -2
View File
@@ -29,11 +29,11 @@ PD_UI7_API void Image::Draw() {
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?"); // Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
// Assert(img.get(), "Image is nullptr!"); // Assert(img.get(), "Image is nullptr!");
// io->Ren->OnScreen(screen); // io->Ren->OnScreen(screen);
list->Layer++; list->LayerUp();
list->DrawTexture(img); list->DrawTexture(img);
list->DrawRectFilled(FinalPos(), newsize, 0xffffffff); list->DrawRectFilled(FinalPos(), newsize, 0xffffffff);
list->DrawSolid(); list->DrawSolid();
list->Layer--; list->LayerDown();
} }
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD
+18 -1
View File
@@ -31,10 +31,27 @@ PD_UI7_API void Label::Draw() {
if (pCLipRectUsed) { if (pCLipRectUsed) {
list->PushClipRect(pClipRect); list->PushClipRect(pClipRect);
} }
list->DrawText(FinalPos(), label, io->Theme->Get(UI7Color_Text)); list->DrawTextEx(FinalPos(), label, io->Theme->Get(UI7Color_Text),
LiTextFlags_NoOOS, PD::fvec2(0, io->CurrentViewPort.w));
if (pCLipRectUsed) { if (pCLipRectUsed) {
list->PopClipRect(); list->PopClipRect();
} }
} }
PD_UI7_API void Label::Update() {
/**
* Todo: This is a hacky workaround
* Needs proper optimisation
* Needs a max size (to support sligning dynaically by the window size)
*/
if (io->WrapLabels) {
this->label =
io->Font->pWrapText(this->label, io->FontScale,
PD::fvec2(io->CurrentViewPort.z - FinalPos().x * 4,
io->CurrentViewPort.w),
this->tdim);
SetSize(tdim);
}
}
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD
+107
View File
@@ -0,0 +1,107 @@
/*
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/ui7/container/label.hpp>
#include <pd/ui7/container/slider.hpp>
#include <type_traits>
namespace PD {
namespace UI7 {
// Setup Supported Datatypes (Probably making this Object
// header only to not care about datatype support)
template class PD_UI7_API Slider<float>;
template class PD_UI7_API Slider<int>;
template class PD_UI7_API Slider<double>;
template class PD_UI7_API Slider<u8>;
template class PD_UI7_API Slider<u16>;
template class PD_UI7_API Slider<u32>;
template class PD_UI7_API Slider<u64>;
template <typename T>
PD_UI7_API void Slider<T>::HandleInput() {
/// Ensure to only check input once
if (inp_done) {
return;
}
// Assert(screen.get(), "Screen is not set up!");
std::string p;
if constexpr (std::is_floating_point_v<T>) {
p = std::format("{:.{}f}", *data, precision);
} else {
p = std::format("{}", *data);
}
// Unsafe but is the fastest solution
float xps = FinalPos().x;
if (io->InputHandler->DragObject(
this->GetID(),
fvec4(FinalPos() + fvec2(2, 0), fvec2(width, GetSize().y)))) {
if (!io->InputHandler->DragReleasedAW) {
*data = std::clamp(
T(max * (std::clamp(io->InputHandler->DragLastPosition.x - xps, 0.f,
width) /
width)),
this->min, this->max);
}
}
inp_done = true;
}
template <typename T>
PD_UI7_API void Slider<T>::Draw() {
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
// io->Ren->OnScreen(screen);
std::string p;
if constexpr (std::is_floating_point_v<T>) {
p = std::format("{:.{}f}", *data, precision);
} else {
p = std::format("{}", *data);
}
fvec2 td = io->Font->GetTextBounds(p, io->FontScale);
list->PathRect(FinalPos(), FinalPos() + fvec2(width, td.y) + io->FramePadding,
io->FrameRounding);
list->PathFill(io->Theme->Get(UI7Color_Button));
list->PathRect(FinalPos() + 2 + PD::fvec2(slp, 0),
FinalPos() + fvec2(slp + slw - 2, td.y - 2) + io->FramePadding,
io->FrameRounding);
list->PathFill(io->Theme->Get(UI7Color_ButtonActive));
list->LayerUp();
list->DrawTextEx(FinalPos(), p, io->Theme->Get(UI7Color_Text),
LiTextFlags_AlignMid, fvec2(width, td.y) + io->FramePadding);
list->LayerDown();
list->DrawText(FinalPos() + fvec2(width + io->FramePadding.x * 2.f,
io->FramePadding.y * 0.5),
label, io->Theme->Get(UI7Color_Text));
}
template <typename T>
PD_UI7_API void Slider<T>::Update() {
// Assert(io.get(), "Did you run Container::Init correctly?");
// Probably need to find a faster solution (caching sizes calculated here)
slw = std::clamp(static_cast<float>(width / max), 3.f, width);
slp = static_cast<float>((float)*data / (float)max) * (width - slw);
fvec2 tdim = io->Font->GetTextBounds(label, io->FontScale);
this->SetSize(
fvec2(width + tdim.x + io->ItemSpace.x * 2, tdim.y + io->FramePadding.y));
}
} // namespace UI7
} // namespace PD
+3 -3
View File
@@ -34,9 +34,9 @@ PD_UI7_API void UI7::IO::Update() {
Time->Update(); Time->Update();
InputHandler->Update(); InputHandler->Update();
Framerate = 1000.f / Delta; Framerate = 1000.f / Delta;
DrawListRegestry.Clear(); DrawListRegestry.clear();
DrawListRegestry.PushFront( DrawListRegestry.push_front(std::make_pair("CtxBackList", Back));
Pair<UI7::ID, Li::DrawList::Ref>("CtxBackList", Back)); if (Font) ItemRowHeight = FontScale * Font->PixelHeight;
// RegisterDrawList("CtxBackList", Back); // RegisterDrawList("CtxBackList", Back);
NumIndices = FDL->pNumIndices; NumIndices = FDL->pNumIndices;
NumVertices = FDL->pNumVertices; NumVertices = FDL->pNumVertices;
+55 -11
View File
@@ -21,6 +21,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include <pd/ui7/containers.hpp>
#include <pd/ui7/layout.hpp> #include <pd/ui7/layout.hpp>
namespace PD { namespace PD {
@@ -66,7 +67,7 @@ PD_UI7_API void Layout::AddObject(Container::Ref obj) {
obj->Update(); obj->Update();
CursorMove(obj->GetSize()); CursorMove(obj->GetSize());
obj->HandleScrolling(ScrollOffset, WorkRect); obj->HandleScrolling(ScrollOffset, WorkRect);
Objects.PushBack(obj); Objects.push_back(obj);
} }
PD_UI7_API void Layout::AddObjectEx(Container::Ref obj, u32 flags) { PD_UI7_API void Layout::AddObjectEx(Container::Ref obj, u32 flags) {
@@ -83,9 +84,9 @@ PD_UI7_API void Layout::AddObjectEx(Container::Ref obj, u32 flags) {
obj->HandleScrolling(ScrollOffset, WorkRect); obj->HandleScrolling(ScrollOffset, WorkRect);
} }
if (flags & UI7LytAdd_Front) { if (flags & UI7LytAdd_Front) {
Objects.PushFront(obj); Objects.push_front(obj);
} else { } else {
Objects.PushBack(obj); Objects.push_back(obj);
} }
} }
@@ -113,6 +114,9 @@ PD_UI7_API fvec2 Layout::AlignPosition(fvec2 pos, fvec2 size, fvec4 area,
} }
PD_UI7_API void Layout::Update() { PD_UI7_API void Layout::Update() {
if (Size == fvec2(0.f)) {
Size = fvec2(MaxPosition) + IO->MenuPadding * 2;
}
for (auto& it : Objects) { for (auto& it : Objects) {
if (it->GetID() != 0 && !FindObject(it->GetID())) { if (it->GetID() != 0 && !FindObject(it->GetID())) {
IDObjects.push_back(it); IDObjects.push_back(it);
@@ -124,18 +128,58 @@ PD_UI7_API void Layout::Update() {
it->Draw(); it->Draw();
} }
} }
std::vector<size_t> tbr;
for (size_t i = 0; i < IDObjects.size(); i++) { for (auto it = IDObjects.begin(); it != IDObjects.end();) {
if (IDObjects[i]->Removable()) { if ((*it)->Removable()) {
tbr.push_back(i); it = IDObjects.erase(it);
} else {
it++;
} }
} }
for (auto& it : tbr) {
IDObjects.erase(IDObjects.begin() + it); Objects.clear();
}
Objects.Clear();
WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO->MenuPadding); WorkRect = fvec4(fvec2(WorkRect.x, WorkRect.y), Size - IO->MenuPadding);
CursorInit(); CursorInit();
} }
/** SECTION CONTAINERS (STOLEN FROM FORMER MENU) */
PD_UI7_API void Layout::Label(const std::string& label) {
// Layout API
auto r = Label::New(label, IO);
r->SetClipRect(fvec4(GetPosition(), GetPosition() + GetSize()));
AddObject(r);
}
PD_UI7_API bool Layout::Button(const std::string& label) {
bool ret = false;
u32 id = Strings::FastHash("btn" + label + std::to_string(Objects.size()));
Container::Ref r = FindObject(id);
if (!r) {
r = Button::New(label, IO);
r->SetID(id);
}
AddObject(r);
if (!r->Skippable()) {
ret = std::static_pointer_cast<UI7::Button>(r)->IsPressed();
}
return ret;
}
PD_UI7_API void Layout::Checkbox(const std::string& label, bool& v) {
u32 id = Strings::FastHash("cbx" + label + std::to_string(Objects.size()));
Container::Ref r = FindObject(id);
if (!r) {
r = Checkbox::New(label, v, IO);
r->SetID(id);
}
AddObject(r);
}
PD_UI7_API void Layout::Image(Li::Texture::Ref img, fvec2 size, Li::Rect uv) {
Container::Ref r = Image::New(img, size, uv);
AddObject(r);
}
} // namespace UI7 } // namespace UI7
} // namespace PD } // namespace PD
+52 -34
View File
@@ -27,24 +27,25 @@ SOFTWARE.
namespace PD { namespace PD {
namespace UI7 { 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); pLayout = Layout::New(id, io);
TitleBarHeight = io->FontScale * 30.f; TitleBarHeight = pIO->FontScale * pIO->Font->PixelHeight + pIO->MenuPadding.y;
pLayout->WorkRect.y += TitleBarHeight; pLayout->WorkRect.y += TitleBarHeight;
pLayout->CursorInit(); pLayout->CursorInit();
} }
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())); r->SetClipRect(fvec4(pLayout->GetPosition(),
pLayout->GetPosition() + pLayout->GetSize()));
pLayout->AddObject(r); 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; bool ret = false;
u32 id = Strings::FastHash("btn" + label + u32 id = Strings::FastHash("btn" + label +
std::to_string(pLayout->Objects.Size())); std::to_string(pLayout->Objects.size()));
Container::Ref r = pLayout->FindObject(id); Container::Ref r = pLayout->FindObject(id);
if (!r) { if (!r) {
r = Button::New(label, pIO); r = Button::New(label, pIO);
@@ -57,9 +58,9 @@ PD_UI7_API bool Menu::Button(const std::string &label) {
return ret; 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 + u32 id = Strings::FastHash("cbx" + label +
std::to_string(pLayout->Objects.Size())); std::to_string(pLayout->Objects.size()));
Container::Ref r = pLayout->FindObject(id); Container::Ref r = pLayout->FindObject(id);
if (!r) { if (!r) {
r = Checkbox::New(label, v, pIO); r = Checkbox::New(label, v, pIO);
@@ -73,22 +74,34 @@ PD_UI7_API void Menu::Image(Li::Texture::Ref img, fvec2 size, Li::Rect uv) {
pLayout->AddObject(r); pLayout->AddObject(r);
} }
PD_UI7_API void Menu::ColorEdit(const std::string& label, u32& clr) {
u32 id = Strings::FastHash("drd" + label);
Container::Ref r = pLayout->FindObject(id);
if (!r) {
r = UI7::ColorEdit::New(label, &clr, pIO);
r->SetID(id);
}
pLayout->AddObject(r);
}
PD_UI7_API void Menu::Separator() { PD_UI7_API void Menu::Separator() {
// Dynamic Objects are very simple... // Dynamic Objects are very simple...
Container::Ref r = DynObj::New( 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(), l->DrawRectFilled(self->FinalPos(), self->GetSize(),
pIO->Theme->Get(UI7Color_TextDead)); pIO->Theme->Get(UI7Color_TextDead));
}); });
// Set size before pushing (cause Cursor Move will require it) // Set size before pushing (cause Cursor Move will require it)
r->SetSize(fvec2(pLayout->Size.x - 10, 1)); r->SetSize(fvec2(
pLayout->Size.x - pIO->MenuPadding.x * 2 - pLayout->InitialCursorOffset.x,
1));
pLayout->AddObject(r); 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 // 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, 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 size = self->GetSize();
fvec2 tdim = io->Font->GetTextBounds(label, io->FontScale); fvec2 tdim = io->Font->GetTextBounds(label, io->FontScale);
fvec2 pos = self->FinalPos(); fvec2 pos = self->FinalPos();
@@ -109,8 +122,9 @@ PD_UI7_API void Menu::SeparatorText(const std::string &label) {
fvec2(pLayout->Size.x, self->GetSize().y)); fvec2(pLayout->Size.x, self->GetSize().y));
}); });
// Set size before pushing (cause Cursor Move will require it) // Set size before pushing (cause Cursor Move will require it)
r->SetSize( r->SetSize(fvec2(
fvec2(pLayout->Size.x - 10, pIO->Font->PixelHeight * pIO->FontScale)); pLayout->Size.x - pIO->MenuPadding.x * 2 - pLayout->InitialCursorOffset.x,
pIO->Font->PixelHeight * pIO->FontScale));
pLayout->AddObject(r); pLayout->AddObject(r);
} }
PD_UI7_API void Menu::HandleFocus() { PD_UI7_API void Menu::HandleFocus() {
@@ -141,14 +155,14 @@ 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 {
pLayout->ScrollOffset.y = std::clamp( pLayout->ScrollOffset.y = std::clamp(
pLayout->ScrollStart.y + pIO->InputHandler->DragSourcePos.y - pLayout->ScrollStart.y + pIO->InputHandler->DragSourcePos.y -
pIO->InputHandler->DragPosition.y, pIO->InputHandler->DragPosition.y,
20.f, pLayout->MaxPosition.y - 220); -20.f, pLayout->MaxPosition.y - 220);
} }
} }
} else { } else {
@@ -238,8 +252,8 @@ PD_UI7_API void Menu::DrawBaseLayout() {
/** Resize Sym (Render on Top of Everything) */ /** Resize Sym (Render on Top of Everything) */
if (!(Flags & UI7MenuFlags_NoResize)) { if (!(Flags & UI7MenuFlags_NoResize)) {
Container::Ref r = DynObj::New( 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->Layer(1);
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20)); l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(0, 20));
l->PathAdd(self->FinalPos() + self->GetSize()); l->PathAdd(self->FinalPos() + self->GetSize());
l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0)); l->PathAdd(self->FinalPos() + self->GetSize() - fvec2(20, 0));
@@ -254,8 +268,8 @@ PD_UI7_API void Menu::DrawBaseLayout() {
/** Background */ /** 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);
l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f, l->PathRectEx(self->FinalPos(), self->FinalPos() + self->GetSize(), 10.f,
LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot); LiPathRectFlags_KeepTop | LiPathRectFlags_KeepBot);
l->PathFill(io->Theme->Get(UI7Color_Background)); l->PathFill(io->Theme->Get(UI7Color_Background));
@@ -271,20 +285,20 @@ PD_UI7_API void Menu::DrawBaseLayout() {
} }
if (!(Flags & UI7MenuFlags_NoTitlebar)) { if (!(Flags & UI7MenuFlags_NoTitlebar)) {
Container::Ref r = DynObj::New( 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; l->Layer(20);
/** Header Bar */ /** Header Bar */
l->DrawRectFilled(self->FinalPos(), self->GetSize(), l->DrawRectFilled(self->FinalPos(), self->GetSize(),
io->Theme->Get(UI7Color_Header)); io->Theme->Get(UI7Color_Header));
l->Layer = 21; l->Layer(21);
/** Inline if statement to shift the Text if collapse sym is shown */ /** Inline if statement to shift the Text if collapse sym is shown */
/** What the hell is this code btw (didn't found a better way) */ /** What the hell is this code btw (didn't found a better way) */
l->DrawText(self->FinalPos() + fvec2(Flags & UI7MenuFlags_NoClose l->DrawText(self->FinalPos() + fvec2((Flags & UI7MenuFlags_NoCollapse)
? 0 ? pIO->FramePadding.x
: (TitleBarHeight - : (TitleBarHeight -
pIO->FramePadding.y * 2 + pIO->FramePadding.y * 2 +
(io->FramePadding.x * 2)), (io->FramePadding.x * 2)),
0), 2),
pID.GetName(), io->Theme->Get(UI7Color_Text)); pID.GetName(), io->Theme->Get(UI7Color_Text));
}); });
r->SetSize(fvec2(pLayout->GetSize().x, TitleBarHeight)); r->SetSize(fvec2(pLayout->GetSize().x, TitleBarHeight));
@@ -295,9 +309,9 @@ PD_UI7_API void Menu::DrawBaseLayout() {
/** Collapse Sym */ /** Collapse Sym */
if (!(Flags & UI7MenuFlags_NoCollapse)) { if (!(Flags & UI7MenuFlags_NoCollapse)) {
r = DynObj::New([=, this](UI7::IO::Ref io, Li::DrawList::Ref l, 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) */ /** This sym actually requires layer 21 (i dont know why) */
l->Layer = 21; l->Layer(21);
/** /**
* Symbol (Position Swapping set by pIsOpen ? openpos : closepos;) * Symbol (Position Swapping set by pIsOpen ? openpos : closepos;)
*/ */
@@ -336,22 +350,26 @@ PD_UI7_API void Menu::DrawBaseLayout() {
PD_UI7_API void Menu::Update() { PD_UI7_API void Menu::Update() {
HandleFocus(); HandleFocus();
if (pLayout->Size == fvec2(0.f) || Flags & UI7MenuFlags_AlwaysAutoSize) {
pLayout->Size = fvec2(pLayout->MaxPosition) + pIO->MenuPadding * 2;
}
if (!(Flags & UI7MenuFlags_NoTitlebar)) { if (!(Flags & UI7MenuFlags_NoTitlebar)) {
TitleBarHeight = pIO->FontScale * 30.f; TitleBarHeight =
pIO->FontScale * pIO->Font->PixelHeight + pIO->MenuPadding.y;
pLayout->WorkRect.y = 5.f + TitleBarHeight; pLayout->WorkRect.y = 5.f + TitleBarHeight;
HandleTitlebarActions(); HandleTitlebarActions();
} else { } else {
TitleBarHeight = 0.f; TitleBarHeight = 0.f;
pLayout->WorkRect.y = 5.f; pLayout->WorkRect.y = 5.f;
} }
DrawBaseLayout();
pLayout->Update();
if (Flags & UI7MenuFlags_VtScrolling || Flags & UI7MenuFlags_HzScrolling) { if (Flags & UI7MenuFlags_VtScrolling || Flags & UI7MenuFlags_HzScrolling) {
HandleScrolling(); HandleScrolling();
} }
DrawBaseLayout();
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: // As of some notes this should work:
auto n = pTreeNodes.find(id); auto n = pTreeNodes.find(id);
if (n == pTreeNodes.end()) { if (n == pTreeNodes.end()) {
@@ -368,7 +386,7 @@ PD_UI7_API bool Menu::BeginTreeNode(const ID &id) {
// Object // Object
auto r = 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 ts = self->FinalPos() + fvec2(0, 7);
fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)}; fvec2 pl[2] = {fvec2(10, 5), fvec2(0, 10)};
if (n->second) { if (n->second) {
@@ -383,7 +401,7 @@ PD_UI7_API bool Menu::BeginTreeNode(const ID &id) {
id.GetName(), io->Theme->Get(UI7Color_Text)); id.GetName(), io->Theme->Get(UI7Color_Text));
}); });
/** Yes this new function handler was created for tree nodes */ /** 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( if (io->InputHandler->DragObject(
ID(pID.GetName() + id.GetName()), ID(pID.GetName() + id.GetName()),
fvec4(self->FinalPos(), self->GetSize()))) { fvec4(self->FinalPos(), self->GetSize()))) {
+30 -33
View File
@@ -51,25 +51,25 @@ PD_UI7_API void Context::UseViewPort(const ID &id) {
pIO->CurrentViewPort = pIO->ViewPorts[id]->GetSize(); pIO->CurrentViewPort = pIO->ViewPorts[id]->GetSize();
} }
PD_UI7_API bool Context::BeginMenu(const ID &id, UI7MenuFlags flags, PD_UI7_API Menu::Ref Context::BeginMenu(const ID &id, UI7MenuFlags flags,
bool *pShow) { bool *pShow) {
if (pCurrent) { if (pCurrent) {
std::cout << "[UI7] Error: You are already in " << pCurrent->pID.GetName() std::cout << "[UI7] Error: You are already in " << pCurrent->pID.GetName()
<< " Menu" << std::endl; << " Menu" << std::endl;
return false; return nullptr;
} }
if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), (u32)id) != if (std::find(pCurrentMenus.begin(), pCurrentMenus.end(), (u32)id) !=
pCurrentMenus.end()) { pCurrentMenus.end()) {
std::cout << "[UI7] Error: Menu " << id.GetName() << " already exists!" std::cout << "[UI7] Error: Menu " << id.GetName() << " already exists!"
<< std::endl; << std::endl;
return false; return nullptr;
} }
pCurrent = pGetOrCreateMenu(id); pCurrent = pGetOrCreateMenu(id);
this->pCurrent->pIsShown = pShow; this->pCurrent->pIsShown = pShow;
if (pCurrent->pIsShown != nullptr) { if (pCurrent->pIsShown != nullptr) {
if (!*pCurrent->pIsShown) { if (!*pCurrent->pIsShown) {
pCurrent = nullptr; pCurrent = nullptr;
return false; return nullptr;
} }
} }
/** Probably we dont even need Input Handling in this stage */ /** Probably we dont even need Input Handling in this stage */
@@ -79,7 +79,7 @@ PD_UI7_API bool Context::BeginMenu(const ID &id, UI7MenuFlags flags,
if (!pCurrent->pIsOpen) { if (!pCurrent->pIsOpen) {
pCurrent = nullptr; pCurrent = nullptr;
} }
return pCurrent != nullptr; return pCurrent;
} }
PD_UI7_API void Context::EndMenu() { PD_UI7_API void Context::EndMenu() {
@@ -151,11 +151,11 @@ PD_UI7_API void Context::Update() {
} }
pCurrentMenus.clear(); pCurrentMenus.clear();
pIO->Update(); pIO->Update();
pIO->FDL->pPool.Sort();
} }
PD_UI7_API void Context::AboutMenu(bool *show) { PD_UI7_API void Context::AboutMenu(bool *show) {
if (BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) { if (auto m = BeginMenu("About UI7", UI7MenuFlags_Scrolling, show)) {
auto m = pCurrent;
m->Label("Palladium UI7 " + GetVersion()); m->Label("Palladium UI7 " + GetVersion());
m->Separator(); m->Separator();
m->Label("(c) 2023-2025 René Amthor"); m->Label("(c) 2023-2025 René Amthor");
@@ -177,8 +177,7 @@ PD_UI7_API void Context::AboutMenu(bool *show) {
} }
PD_UI7_API void Context::MetricsMenu(bool *show) { PD_UI7_API void Context::MetricsMenu(bool *show) {
if (BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling, show)) { if (auto m = BeginMenu("UI7 Metrics", UI7MenuFlags_Scrolling, show)) {
auto m = pCurrent;
m->Label("Palladium - UI7 " + GetVersion()); m->Label("Palladium - UI7 " + GetVersion());
m->Separator(); m->Separator();
m->Label( m->Label(
@@ -209,7 +208,7 @@ PD_UI7_API void Context::MetricsMenu(bool *show) {
} }
m->SeparatorText("Palladium Info"); m->SeparatorText("Palladium Info");
m->Label("Renderer: " + PD::Gfx::pGfx->pName); m->Label("Renderer: " + PD::Gfx::pGfx->pName);
if (m->BeginTreeNode("Input: " + PD::Hid::pHid->pName)) { if (m->BeginTreeNode(std::string("Input: " + PD::Hid::pHid->pName))) {
if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasKeyboard) { if (PD::Hid::GetFlags() & PD::HidDriver::Flags_HasKeyboard) {
m->Label("- Keyboard Supported"); m->Label("- Keyboard Supported");
} }
@@ -272,7 +271,7 @@ PD_UI7_API void Context::MetricsMenu(bool *show) {
} }
// Well this are Li Drawlists now and they do not count their stats (yet) // Well this are Li Drawlists now and they do not count their stats (yet)
/*if (m->BeginTreeNode("DrawLists (" + /*if (m->BeginTreeNode("DrawLists (" +
std::to_string(pIO->DrawListRegestry.Size()) + ")")) { std::to_string(pIO->DrawListRegestry.size()) + ")")) {
for (auto &it : pIO->DrawListRegestry) { for (auto &it : pIO->DrawListRegestry) {
if (m->BeginTreeNode(it.First.GetName())) { if (m->BeginTreeNode(it.First.GetName())) {
m->Label("Vertices: " + std::to_string(it.Second->NumVertices)); m->Label("Vertices: " + std::to_string(it.Second->NumVertices));
@@ -303,9 +302,7 @@ PD_UI7_API void Context::MetricsMenu(bool *show) {
} }
PD_UI7_API void UI7::Context::StyleEditor(bool *show) { PD_UI7_API void UI7::Context::StyleEditor(bool *show) {
if (this->BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) { if (auto m = BeginMenu("UI7 Style Editor", UI7MenuFlags_Scrolling, show)) {
auto m = pCurrent;
m->Label("Palladium - UI7 " + GetVersion() + " Style Editor"); m->Label("Palladium - UI7 " + GetVersion() + " Style Editor");
m->Separator(); m->Separator();
m->DragData("MenuPadding", (float *)&pIO->MenuPadding, 2, 0.f, 100.f); m->DragData("MenuPadding", (float *)&pIO->MenuPadding, 2, 0.f, 100.f);
@@ -326,27 +323,27 @@ PD_UI7_API void UI7::Context::StyleEditor(bool *show) {
UI7::Theme::Flashbang(*pIO->Theme.get()); UI7::Theme::Flashbang(*pIO->Theme.get());
} }
/// Small trick to print without prefix /// Small trick to print without prefix
#define ts(x) m->ColorEdit(std::string(#x).substr(9), &pIO->Theme->GetRef(x)); #define ts(x) m->ColorEdit(std::string(#x).substr(9), pIO->Theme->GetRef(x));
#define ts2(x) \ #define ts2(x) \
m->DragData(std::string(#x).substr(9), (u8 *)&pIO->Theme->GetRef(x), 4, \ m->DragData(std::string(#x).substr(9), (u8 *)&pIO->Theme->GetRef(x), 4, \
(u8)0, (u8)255); (u8)0, (u8)255);
ts2(UI7Color_Background); ts(UI7Color_Background);
ts2(UI7Color_Border); ts(UI7Color_Border);
ts2(UI7Color_Button); ts(UI7Color_Button);
ts2(UI7Color_ButtonDead); ts(UI7Color_ButtonDead);
ts2(UI7Color_ButtonActive); ts(UI7Color_ButtonActive);
ts2(UI7Color_ButtonHovered); ts(UI7Color_ButtonHovered);
ts2(UI7Color_Text); ts(UI7Color_Text);
ts2(UI7Color_TextDead); ts(UI7Color_TextDead);
ts2(UI7Color_Header); ts(UI7Color_Header);
ts2(UI7Color_HeaderDead); ts(UI7Color_HeaderDead);
ts2(UI7Color_Selector); ts(UI7Color_Selector);
ts2(UI7Color_Checkmark); ts(UI7Color_Checkmark);
ts2(UI7Color_FrameBackground); ts(UI7Color_FrameBackground);
ts2(UI7Color_FrameBackgroundHovered); ts(UI7Color_FrameBackgroundHovered);
ts2(UI7Color_Progressbar); ts(UI7Color_Progressbar);
ts2(UI7Color_ListEven); ts(UI7Color_ListEven);
ts2(UI7Color_ListOdd); ts(UI7Color_ListOdd);
this->EndMenu(); this->EndMenu();
} }
} }
+20 -16
View File
@@ -21,12 +21,18 @@ int TheScale = 1;
bool AboutOderSo = true; bool AboutOderSo = true;
int main() { int main() {
void *PD_INIT_DATA = nullptr; void* PD_INIT_DATA = nullptr;
#ifndef __3DS__ #ifndef __3DS__
/** Setup Window and Context */ /** Setup Window and Context */
glfwInit(); glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
#ifdef __APPLE__
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, 0);
#else
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
#endif
glfwWindowHint(GLFW_SAMPLES, 8); glfwWindowHint(GLFW_SAMPLES, 8);
auto win = glfwCreateWindow(1280, 720, "Test", nullptr, nullptr); auto win = glfwCreateWindow(1280, 720, "Test", nullptr, nullptr);
glfwMakeContextCurrent(win); glfwMakeContextCurrent(win);
@@ -36,9 +42,9 @@ int main() {
osSetSpeedupEnable(true); osSetSpeedupEnable(true);
gfxInitDefault(); gfxInitDefault();
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 2); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 2);
C3D_RenderTarget *Top = C3D_RenderTarget* Top =
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTarget *Bottom = C3D_RenderTarget* Bottom =
C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetOutput(Top, GFX_TOP, GFX_LEFT, DisplayTransferFlags); C3D_RenderTargetSetOutput(Top, GFX_TOP, GFX_LEFT, DisplayTransferFlags);
C3D_RenderTargetSetOutput(Bottom, GFX_BOTTOM, GFX_LEFT, DisplayTransferFlags); C3D_RenderTargetSetOutput(Bottom, GFX_BOTTOM, GFX_LEFT, DisplayTransferFlags);
@@ -80,8 +86,9 @@ int main() {
int wx, wy; int wx, wy;
glfwGetWindowSize(win, &wx, &wy); glfwGetWindowSize(win, &wx, &wy);
PD::Gfx::pGfx->ViewPort = PD::ivec2(wx, wy); PD::Gfx::pGfx->ViewPort = PD::ivec2(wx, wy);
ui7->GetIO()->CurrentViewPort = PD::ivec4(0, 0, wx, wy);
glViewport(0, 0, wx, wy); glViewport(0, 0, wx, wy);
glClearColor(0, 0, 0, 0); glClearColor(0.1, 0.1, 0.1, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
// ui7->pIO->GetViewPort(VpTop)->pSize = PD::ivec4(0, 0, wx, wy); // ui7->pIO->GetViewPort(VpTop)->pSize = PD::ivec4(0, 0, wx, wy);
#endif #endif
@@ -102,15 +109,14 @@ int main() {
/** Draw text */ /** Draw text */
List->DrawText( List->DrawText(
20, 20,
"Test String oder So\nPalladium 0.5.0\n" + "Test String oder So\nPalladium 0.6.0\n" +
std::format("{}\nMousePos: {}", std::format("{}\nMousePos: {}",
PD::Strings::FormatNanos( PD::Strings::FormatNanos(
PD::OS::GetTraceRef("REN")->GetLastDiff()), PD::OS::GetTraceRef("REN")->GetLastDiff()),
PD::Hid::MousePos()) + PD::Hid::MousePos()) +
"\nUI7 Version: " + PD::UI7::GetVersion(), "\nUI7 Version: " + PD::UI7::GetVersion(),
0xff000000); 0xff000000);
if (ui7->BeginMenu("Test")) { if (auto menu = ui7->BeginMenu("Test")) {
auto menu = ui7->pCurrent;
menu->Label("Hello"); menu->Label("Hello");
menu->Label("World!"); menu->Label("World!");
menu->Checkbox("About Menu", AboutOderSo); menu->Checkbox("About Menu", AboutOderSo);
@@ -125,17 +131,16 @@ 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);
menu->Slider("Value 2", &v);
ui7->EndMenu(); ui7->EndMenu();
} }
if (ui7->BeginMenu("Yet another Window")) { if (auto menu = ui7->BeginMenu("Yet another Window")) {
auto menu = ui7->pCurrent;
menu->Label(std::format("this->Pos: {}", menu->pLayout->GetPosition())); menu->Label(std::format("this->Pos: {}", menu->pLayout->GetPosition()));
menu->Label(std::format("Vertices: {}", PD::Gfx::pGfx->VertexCounter)); menu->Label(std::format("Vertices: {}", PD::Gfx::pGfx->VertexCounter));
menu->Label(std::format("Indices: {}", PD::Gfx::pGfx->IndexCounter)); menu->Label(std::format("Indices: {}", PD::Gfx::pGfx->IndexCounter));
ui7->EndMenu(); ui7->EndMenu();
} }
if (ui7->BeginMenu("#Debug (UI7)")) { if (auto menu = ui7->BeginMenu("#Debug (UI7)")) {
auto menu = ui7->pCurrent;
menu->Label(std::format("Framerate: {:.1f} [{:.2f}]", ui7->pIO->Framerate, menu->Label(std::format("Framerate: {:.1f} [{:.2f}]", ui7->pIO->Framerate,
ui7->pIO->Delta)); ui7->pIO->Delta));
menu->SeparatorText("Input"); menu->SeparatorText("Input");
@@ -144,13 +149,12 @@ int main() {
menu->Label(std::format("FocusedMenuRect: {}", menu->Label(std::format("FocusedMenuRect: {}",
ui7->pIO->InputHandler->FocusedMenuRect)); ui7->pIO->InputHandler->FocusedMenuRect));
menu->SeparatorText("Menu Order"); menu->SeparatorText("Menu Order");
for (auto &it : ui7->pDFO) { for (auto& it : ui7->pDFO) {
menu->Label(std::format("{}", ui7->pMenus[it]->pID.GetName())); menu->Label(std::format("{}", ui7->pMenus[it]->pID.GetName()));
} }
ui7->EndMenu(); ui7->EndMenu();
} }
if (ui7->BeginMenu("NoDebug")) { if (auto m = ui7->BeginMenu("NoDebug")) {
auto m = ui7->pCurrent;
if (m->BeginTreeNode("Test")) { if (m->BeginTreeNode("Test")) {
m->Label("Hello World!"); m->Label("Hello World!");
if (m->BeginTreeNode("AnotherNode")) { if (m->BeginTreeNode("AnotherNode")) {
@@ -176,8 +180,8 @@ int main() {
#endif #endif
PD::TT::Beg("REN"); PD::TT::Beg("REN");
PD::Gfx::NewFrame(); PD::Gfx::NewFrame();
PD::Gfx::RenderDrawData(List->pDrawList); PD::Gfx::RenderDrawData(List->Data());
PD::Gfx::RenderDrawData(ui7->GetDrawData()->pDrawList); PD::Gfx::RenderDrawData(ui7->GetDrawData()->Data());
/** Clear The List */ /** Clear The List */
List->Clear(); List->Clear();
PD::TT::End("REN"); PD::TT::End("REN");