Compare commits
88
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39e91b588f
|
||
|
|
7bb1406365
|
||
|
|
438584e4f2
|
||
|
|
acc4fd11eb
|
||
|
|
72bb76dcbc
|
||
|
|
272b66f7f0
|
||
|
|
6637a3692b
|
||
|
|
feeb3b1ba8
|
||
|
|
5a56bf3986
|
||
|
|
1dfc538ae3
|
||
|
|
36c05a9138
|
||
|
|
a8d841c63c
|
||
|
|
8983371806
|
||
|
|
2b4c4bacd6
|
||
|
|
859a4c96ae
|
||
|
|
0e0d576954
|
||
|
|
4a29cb4330
|
||
|
|
e0b86ee3f6
|
||
|
|
b121001db7
|
||
|
|
2059772ad1
|
||
|
|
81aa08485b
|
||
|
|
ecadf0a44c
|
||
|
|
6dfc04378a
|
||
|
|
e3ffcbb596
|
||
|
|
469cd535fd
|
||
|
|
b594e09bdb
|
||
|
|
41b25e4476
|
||
|
|
25607b865c
|
||
|
|
1bf103c894
|
||
|
|
11a480136b
|
||
|
|
e6fcfe0650
|
||
|
|
a8a80cfa47
|
||
|
|
b7f1037b18
|
||
|
|
de51a35734
|
||
|
|
13152a317a
|
||
|
|
5dd5907c43
|
||
|
|
673e53935a
|
||
|
|
dda8258064
|
||
|
|
0c55291f9c
|
||
|
|
c5f6f0cb33
|
||
|
|
391eea100a
|
||
|
|
d70a9970e9
|
||
|
|
0f044538cc
|
||
|
|
546940aa77
|
||
|
|
dc365bc658
|
||
|
|
1ccc7075fa
|
||
|
|
b069f10841
|
||
|
|
bf3eef8d28
|
||
|
|
6298d4c816
|
||
|
|
212ba0c617
|
||
|
|
b4a7260cf2
|
||
|
|
5cf9ff0109
|
||
|
|
69b5e74d91
|
||
|
|
9b69d78118
|
||
|
|
e573523511
|
||
|
|
1317599475
|
||
|
|
1876ab9365
|
||
|
|
ce2dc94121
|
||
|
|
bef8ced350
|
||
|
|
dd038883a0
|
||
|
|
7ad2b8b0c5
|
||
|
|
63fb09189d
|
||
|
|
306ddfed53
|
||
|
|
c2b0fa01db
|
||
|
|
594cf5cca4
|
||
|
|
191bca26d5
|
||
|
|
85a92f8371
|
||
|
|
f3d326c237
|
||
|
|
fda39b3d36
|
||
|
|
8e09025c40
|
||
|
|
2a57b7c08c
|
||
|
|
9d0565f60c
|
||
|
|
4691d158a9
|
||
|
|
57c376a822
|
||
|
|
d72c447875
|
||
|
|
518015afb1
|
||
|
|
e6a60e90d1
|
||
|
|
9d63a17700
|
||
|
|
fd498c5ea2
|
||
|
|
0cc886315d
|
||
|
|
1b9876f64b
|
||
|
|
cd904ea544
|
||
|
|
e43cb41377
|
||
|
|
b2d3d203a2
|
||
|
|
f1a63fe383
|
||
|
|
0501a4f87c
|
||
|
|
3d8b57ead6
|
||
|
|
ac37ce9e12
|
@@ -1,4 +1,5 @@
|
|||||||
CompileFlags:
|
CompileFlags:
|
||||||
|
CompilationDatabase: build/default-release
|
||||||
Add: []
|
Add: []
|
||||||
|
|
||||||
Completion:
|
Completion:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
build*/
|
build*/
|
||||||
.cache
|
.cache
|
||||||
.vscode
|
.vscode
|
||||||
|
.DS_Store
|
||||||
+46
-3
@@ -12,6 +12,7 @@ include(cmake/palladium.cmake)
|
|||||||
option(PD_BUILD_TESTS "Sets if TestApp and TestBench get build" OFF)
|
option(PD_BUILD_TESTS "Sets if TestApp and TestBench get build" OFF)
|
||||||
option(PD_BUILD_SHARED "Build Shared Library" OFF)
|
option(PD_BUILD_SHARED "Build Shared Library" OFF)
|
||||||
option(PD_BUILD_TOOLS "Build Palladium Tools" OFF)
|
option(PD_BUILD_TOOLS "Build Palladium Tools" OFF)
|
||||||
|
option(PD_INCLUDE_STB_IMAGE "Inlude stb image symbols in palladium" ON)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
||||||
add_compile_options(-Wno-psabi)
|
add_compile_options(-Wno-psabi)
|
||||||
@@ -37,14 +38,46 @@ set(PD_SOURCES
|
|||||||
source/core/timer.cpp
|
source/core/timer.cpp
|
||||||
source/core/timetrace.cpp
|
source/core/timetrace.cpp
|
||||||
|
|
||||||
|
# Image
|
||||||
|
source/image/convert.cpp
|
||||||
|
source/image/image.cpp
|
||||||
|
|
||||||
# Drivers
|
# Drivers
|
||||||
source/drivers/os.cpp
|
source/drivers/os.cpp
|
||||||
source/drivers/gfx.cpp
|
source/drivers/gfx.cpp
|
||||||
|
source/drivers/hid.cpp
|
||||||
|
|
||||||
# Lithium
|
# Lithium
|
||||||
source/lithium/pools.cpp
|
source/lithium/command.cpp
|
||||||
source/lithium/math.cpp
|
|
||||||
source/lithium/drawlist.cpp
|
source/lithium/drawlist.cpp
|
||||||
|
source/lithium/font.cpp
|
||||||
|
source/lithium/math.cpp
|
||||||
|
source/lithium/pools.cpp
|
||||||
|
|
||||||
|
# UI7
|
||||||
|
source/ui7/io.cpp
|
||||||
|
source/ui7/layout.cpp
|
||||||
|
source/ui7/menu.cpp
|
||||||
|
source/ui7/theme.cpp
|
||||||
|
source/ui7/ui7.cpp
|
||||||
|
source/ui7/container/button.cpp
|
||||||
|
source/ui7/container/checkbox.cpp
|
||||||
|
source/ui7/container/coloredit.cpp
|
||||||
|
source/ui7/container/container.cpp
|
||||||
|
source/ui7/container/dragdata.cpp
|
||||||
|
source/ui7/container/dynobj.cpp
|
||||||
|
source/ui7/container/image.cpp
|
||||||
|
source/ui7/container/label.cpp
|
||||||
|
source/ui7/container/slider.cpp
|
||||||
|
|
||||||
|
# Ultra
|
||||||
|
source/ultra/canvas.cpp
|
||||||
|
source/ultra/layout.cpp
|
||||||
|
source/ultra/elems/element.cpp
|
||||||
|
source/ultra/elems/rect.cpp
|
||||||
|
source/ultra/elems/text.cpp
|
||||||
|
source/ultra/elems/image.cpp
|
||||||
|
source/ultra/elems/button.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(${PD_BUILD_SHARED})
|
if(${PD_BUILD_SHARED})
|
||||||
@@ -55,7 +88,15 @@ else()
|
|||||||
target_compile_definitions(palladium PUBLIC PD_BUILD_STATIC)
|
target_compile_definitions(palladium PUBLIC PD_BUILD_STATIC)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_compile_definitions(palladium PUBLIC PD_DEBUG)
|
target_link_libraries(palladium
|
||||||
|
PUBLIC stb
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(palladium
|
||||||
|
PUBLIC
|
||||||
|
PD_DEBUG
|
||||||
|
$<$<OR:$<BOOL:${PD_INCLUDE_STB_IMAGE}>,$<BOOL:${PD_BUILD_SHARED}>>:PD_INCLUDE_STB_IMAGE> # Always on in shared build
|
||||||
|
)
|
||||||
target_compile_options(palladium
|
target_compile_options(palladium
|
||||||
PUBLIC $<$<CXX_COMPILER_ID:GNU,Clang>:
|
PUBLIC $<$<CXX_COMPILER_ID:GNU,Clang>:
|
||||||
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
|
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
|
||||||
@@ -138,4 +179,6 @@ add_custom_target(pd-clang-format
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(backends)
|
add_subdirectory(backends)
|
||||||
|
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests)
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"version": 10,
|
||||||
|
"cmakeMinimumRequired": {
|
||||||
|
"major": 3,
|
||||||
|
"minor": 22,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"cmake/presets/default.json",
|
||||||
|
"cmake/presets/3ds.json",
|
||||||
|
"cmake/presets/switch.json",
|
||||||
|
"cmake/presets/msvc.json"
|
||||||
|
]
|
||||||
|
}
|
||||||
+28
-30
@@ -7,6 +7,9 @@ option(PD_ENABLE_OPENGL3 "Enable OpenGL 3.3 (On Supported Hardware)" ON)
|
|||||||
option(PD_ENABLE_DIRECTX9 "Enable DirectX9 Support" ON)
|
option(PD_ENABLE_DIRECTX9 "Enable DirectX9 Support" ON)
|
||||||
option(PD_ENABLE_CITRO3D "Enable Citro3D Support (3DS)" OFF)
|
option(PD_ENABLE_CITRO3D "Enable Citro3D Support (3DS)" OFF)
|
||||||
option(PD_ENABLE_VULKAN "Not implemented yet" OFF)
|
option(PD_ENABLE_VULKAN "Not implemented yet" OFF)
|
||||||
|
option(PD_ENABLE_HID_GLFW "Enable GLFW Input Driver" ON)
|
||||||
|
option(PD_ENABLE_HID_NX "Enable NX Input Driver" OFF)
|
||||||
|
option(PD_ENABLE_HID3DS "Enable 3ds Input Driver" OFF)
|
||||||
|
|
||||||
if(NOT WIN32) # cause we are not on windows...
|
if(NOT WIN32) # cause we are not on windows...
|
||||||
set(PD_ENABLE_DIRECTX9 OFF)
|
set(PD_ENABLE_DIRECTX9 OFF)
|
||||||
@@ -17,11 +20,16 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
|||||||
set(PD_ENABLE_OPENGL3 OFF)
|
set(PD_ENABLE_OPENGL3 OFF)
|
||||||
set(PD_ENABLE_VULKAN OFF)
|
set(PD_ENABLE_VULKAN OFF)
|
||||||
set(PD_ENABLE_CITRO3D ON)
|
set(PD_ENABLE_CITRO3D ON)
|
||||||
|
set(PD_ENABLE_HID_GLFW OFF)
|
||||||
|
set(PD_ENABLE_HID_NX OFF)
|
||||||
|
set(PD_ENABLE_HID3DS ON)
|
||||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
|
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
|
||||||
set(PD_ENABLE_OPENGL2 OFF)
|
set(PD_ENABLE_OPENGL2 OFF)
|
||||||
set(PD_ENABLE_OPENGL3 ON)
|
set(PD_ENABLE_OPENGL3 ON)
|
||||||
set(PD_ENABLE_VULKAN OFF)
|
set(PD_ENABLE_VULKAN OFF)
|
||||||
set(PD_ENABLE_CITRO3D OFF)
|
set(PD_ENABLE_CITRO3D OFF)
|
||||||
|
set(PD_ENABLE_HID_NX ON) # Best case for Nintendo Switch
|
||||||
|
set(PD_ENABLE_HID_GLFW ON) # Technically supported but not recommended
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(pd-system STATIC
|
add_library(pd-system STATIC
|
||||||
@@ -30,12 +38,17 @@ add_library(pd-system STATIC
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl3.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl3.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_directx9.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_directx9.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_citro3d.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_citro3d.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_3ds.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_glfw.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/source/hid_nx.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(pd-system
|
target_include_directories(pd-system
|
||||||
PUBLIC
|
PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
|
# Why is this not a default include (same problem as with the __SWITCH__ define)
|
||||||
|
$<$<STREQUAL:${CMAKE_SYSTEM_NAME},NintendoSwitch>:${DEVKITPRO}/portlibs/switch/include>
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(palladium
|
target_compile_options(palladium
|
||||||
@@ -52,41 +65,26 @@ target_compile_definitions(pd-system
|
|||||||
$<$<BOOL:${PD_ENABLE_VULKAN}>:PD_ENABLE_VULKAN>
|
$<$<BOOL:${PD_ENABLE_VULKAN}>:PD_ENABLE_VULKAN>
|
||||||
$<$<BOOL:${PD_ENABLE_DIRECTX9}>:PD_ENABLE_DIRECTX9>
|
$<$<BOOL:${PD_ENABLE_DIRECTX9}>:PD_ENABLE_DIRECTX9>
|
||||||
$<$<BOOL:${PD_ENABLE_CITRO3D}>:PD_ENABLE_CITRO3D>
|
$<$<BOOL:${PD_ENABLE_CITRO3D}>:PD_ENABLE_CITRO3D>
|
||||||
|
$<$<BOOL:${PD_ENABLE_HID_GLFW}>:PD_ENABLE_HID_GLFW>
|
||||||
|
$<$<BOOL:${PD_ENABLE_HID_NX}>:PD_ENABLE_HID_NX>
|
||||||
|
$<$<BOOL:${PD_ENABLE_HID3DS}>:PD_ENABLE_HID3DS>
|
||||||
)
|
)
|
||||||
|
|
||||||
# Palladium
|
# Palladium
|
||||||
target_link_libraries(pd-system PUBLIC palladium::palladium)
|
target_link_libraries(pd-system PUBLIC palladium::palladium)
|
||||||
|
|
||||||
# glad (if we have any OpenGL version included)
|
|
||||||
if(PD_ENABLE_OPENGL2 OR PD_ENABLE_OPENGL3)
|
|
||||||
target_link_libraries(pd-system
|
|
||||||
PUBLIC glad
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# DirectX9
|
# Depandant Lib includes (i love this cmake feature)
|
||||||
if(PD_ENABLE_DIRECTX9)
|
target_link_libraries(pd-system PUBLIC
|
||||||
target_link_libraries(pd-system
|
$<$<BOOL:${PD_ENABLE_DIRECTX9}>:d3d9 d3dcompiler> # DirectX9
|
||||||
PUBLIC
|
$<$<BOOL:${PD_ENABLE_CITRO3D}>:pica::pica citro3d ctru> # 3ds
|
||||||
d3d9
|
$<$<BOOL:${PD_ENABLE_OPENGL3}>:spirv-helper> # OpenGL3
|
||||||
d3dcompiler
|
# Include Glad if we have any OpenGL Usage
|
||||||
)
|
$<$<OR:$<BOOL:${PD_ENABLE_OPENGL2}>,$<BOOL:${PD_ENABLE_OPENGL3}>>:glad>
|
||||||
endif()
|
$<$<BOOL:${PD_ENABLE_HID_NX}>:nx> # Hid NX requirement
|
||||||
|
# Hid GLFW requirement
|
||||||
|
$<$<BOOL:${PD_ENABLE_HID_GLFW}>:
|
||||||
|
$<$<STREQUAL:${CMAKE_SYSTEM_NAME},NintendoSwitch>:glfw3>
|
||||||
|
$<$<NOT:$<STREQUAL:${CMAKE_SYSTEM_NAME},NintendoSwitch>>:glfw>>
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS")
|
|
||||||
target_link_libraries(pd-system
|
|
||||||
PUBLIC
|
|
||||||
pica::pica
|
|
||||||
citro3d
|
|
||||||
ctru
|
|
||||||
)
|
)
|
||||||
else()
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch")
|
|
||||||
target_include_directories(pd-system
|
|
||||||
PUBLIC $ENV{DEVKITPRO}/portlibs/switch/include
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
target_link_libraries(pd-system
|
|
||||||
PUBLIC spirv-helper
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class GfxCitro3D : public GfxDriverBase<GfxCitro3DConfig> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
|
void UploadPools() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class GfxDirectX9 : public GfxDriverBase<GfxDirectX9Config> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
|
void UploadPools() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
|
void UploadPools() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void pSetupShaderAttribs(u32 shader);
|
void pSetupShaderAttribs(u32 shader);
|
||||||
@@ -35,6 +36,7 @@ class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
|
|||||||
u32 IBO = 0;
|
u32 IBO = 0;
|
||||||
int pLocTex = 0;
|
int pLocTex = 0;
|
||||||
int pLocAlfa = 0;
|
int pLocAlfa = 0;
|
||||||
|
int pLocIsSDF = 0;
|
||||||
int pLocProjection = 0;
|
int pLocProjection = 0;
|
||||||
static const char* pVertCode;
|
static const char* pVertCode;
|
||||||
static const char* pFragCode;
|
static const char* pFragCode;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
|
|||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
TextureFilter filter = TextureFilter::Linear) override;
|
TextureFilter filter = TextureFilter::Linear) override;
|
||||||
void DeleteTexture(const Li::Texture& tex) override;
|
void DeleteTexture(const Li::Texture& tex) override;
|
||||||
|
void UploadPools() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 pShader = 0;
|
u32 pShader = 0;
|
||||||
@@ -35,6 +36,7 @@ class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
|
|||||||
u32 VAO = 0;
|
u32 VAO = 0;
|
||||||
int pLocTex = 0;
|
int pLocTex = 0;
|
||||||
int pLocAlfa = 0;
|
int pLocAlfa = 0;
|
||||||
|
int pLocIsSDF = 0;
|
||||||
int pLocProjection = 0;
|
int pLocProjection = 0;
|
||||||
};
|
};
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/drivers/hid.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
class Hid3DS : public HidDriver {
|
||||||
|
public:
|
||||||
|
Hid3DS();
|
||||||
|
~Hid3DS();
|
||||||
|
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
Impl* impl;
|
||||||
|
};
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/drivers/hid.hpp>
|
||||||
|
|
||||||
|
typedef struct GLFWwindow GLFWwindow;
|
||||||
|
typedef struct GLFWgamepadstate GLFWgamepadstate;
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
class HidGlfw : public HidDriver {
|
||||||
|
public:
|
||||||
|
HidGlfw(GLFWwindow* window);
|
||||||
|
~HidGlfw();
|
||||||
|
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void HandleAxisKey(GLFWgamepadstate s, int iK, int eA, bool negative);
|
||||||
|
struct Impl;
|
||||||
|
Impl* impl;
|
||||||
|
};
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/drivers/hid.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
class HidNX : public HidDriver {
|
||||||
|
public:
|
||||||
|
HidNX();
|
||||||
|
~HidNX();
|
||||||
|
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
Impl* impl;
|
||||||
|
};
|
||||||
|
} // namespace PD
|
||||||
@@ -11,7 +11,7 @@ namespace Shaders {
|
|||||||
const unsigned int VertexShader[] = { 0x7230203, 0x10000, 0x8000B, 0x2B, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0xB000F, 0x0, 0x4, 0x6E69616D, 0x0, 0xD, 0x19, 0x24, 0x25, 0x27, 0x29, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x60005, 0xB, 0x505F6C67, 0x65567265, 0x78657472, 0x0, 0x60006, 0xB, 0x0, 0x505F6C67, 0x7469736F, 0x6E6F69, 0x70006, 0xB, 0x1, 0x505F6C67, 0x746E696F, 0x657A6953, 0x0, 0x70006, 0xB, 0x2, 0x435F6C67, 0x4470696C, 0x61747369, 0x65636E, 0x70006, 0xB, 0x3, 0x435F6C67, 0x446C6C75, 0x61747369, 0x65636E, 0x30005, 0xD, 0x0, 0x30005, 0x11, 0x4F4255, 0x60006, 0x11, 0x0, 0x6A6F7270, 0x69746365, 0x6E6F, 0x30005, 0x13, 0x6F6275, 0x30005, 0x19, 0x736F70, 0x30005, 0x24, 0x56556F, 0x30005, 0x25, 0x7675, 0x40005, 0x27, 0x6C6F436F, 0x726F, 0x40005, 0x29, 0x6F6C6F63, 0x72, 0x30047, 0xB, 0x2, 0x50048, 0xB, 0x0, 0xB, 0x0, 0x50048, 0xB, 0x1, 0xB, 0x1, 0x50048, 0xB, 0x2, 0xB, 0x3, 0x50048, 0xB, 0x3, 0xB, 0x4, 0x30047, 0x11, 0x2, 0x40048, 0x11, 0x0, 0x5, 0x50048, 0x11, 0x0, 0x7, 0x10, 0x50048, 0x11, 0x0, 0x23, 0x0, 0x40047, 0x13, 0x21, 0x0, 0x40047, 0x13, 0x22, 0x0, 0x40047, 0x19, 0x1E, 0x0, 0x40047, 0x24, 0x1E, 0x0, 0x40047, 0x25, 0x1E, 0x1, 0x40047, 0x27, 0x1E, 0x1, 0x40047, 0x29, 0x1E, 0x2, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40015, 0x8, 0x20, 0x0, 0x4002B, 0x8, 0x9, 0x1, 0x4001C, 0xA, 0x6, 0x9, 0x6001E, 0xB, 0x7, 0x6, 0xA, 0xA, 0x40020, 0xC, 0x3, 0xB, 0x4003B, 0xC, 0xD, 0x3, 0x40015, 0xE, 0x20, 0x1, 0x4002B, 0xE, 0xF, 0x0, 0x40018, 0x10, 0x7, 0x4, 0x3001E, 0x11, 0x10, 0x40020, 0x12, 0x2, 0x11, 0x4003B, 0x12, 0x13, 0x2, 0x40020, 0x14, 0x2, 0x10, 0x40017, 0x17, 0x6, 0x2, 0x40020, 0x18, 0x1, 0x17, 0x4003B, 0x18, 0x19, 0x1, 0x4002B, 0x6, 0x1B, 0x0, 0x4002B, 0x6, 0x1C, 0x3F800000, 0x40020, 0x21, 0x3, 0x7, 0x40020, 0x23, 0x3, 0x17, 0x4003B, 0x23, 0x24, 0x3, 0x4003B, 0x18, 0x25, 0x1, 0x4003B, 0x21, 0x27, 0x3, 0x40020, 0x28, 0x1, 0x7, 0x4003B, 0x28, 0x29, 0x1, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x50041, 0x14, 0x15, 0x13, 0xF, 0x4003D, 0x10, 0x16, 0x15, 0x4003D, 0x17, 0x1A, 0x19, 0x50051, 0x6, 0x1D, 0x1A, 0x0, 0x50051, 0x6, 0x1E, 0x1A, 0x1, 0x70050, 0x7, 0x1F, 0x1D, 0x1E, 0x1B, 0x1C, 0x50091, 0x7, 0x20, 0x16, 0x1F, 0x50041, 0x21, 0x22, 0xD, 0xF, 0x3003E, 0x22, 0x20, 0x4003D, 0x17, 0x26, 0x25, 0x3003E, 0x24, 0x26, 0x4003D, 0x7, 0x2A, 0x29, 0x3003E, 0x27, 0x2A, 0x100FD, 0x10038, };
|
const unsigned int VertexShader[] = { 0x7230203, 0x10000, 0x8000B, 0x2B, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0xB000F, 0x0, 0x4, 0x6E69616D, 0x0, 0xD, 0x19, 0x24, 0x25, 0x27, 0x29, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x60005, 0xB, 0x505F6C67, 0x65567265, 0x78657472, 0x0, 0x60006, 0xB, 0x0, 0x505F6C67, 0x7469736F, 0x6E6F69, 0x70006, 0xB, 0x1, 0x505F6C67, 0x746E696F, 0x657A6953, 0x0, 0x70006, 0xB, 0x2, 0x435F6C67, 0x4470696C, 0x61747369, 0x65636E, 0x70006, 0xB, 0x3, 0x435F6C67, 0x446C6C75, 0x61747369, 0x65636E, 0x30005, 0xD, 0x0, 0x30005, 0x11, 0x4F4255, 0x60006, 0x11, 0x0, 0x6A6F7270, 0x69746365, 0x6E6F, 0x30005, 0x13, 0x6F6275, 0x30005, 0x19, 0x736F70, 0x30005, 0x24, 0x56556F, 0x30005, 0x25, 0x7675, 0x40005, 0x27, 0x6C6F436F, 0x726F, 0x40005, 0x29, 0x6F6C6F63, 0x72, 0x30047, 0xB, 0x2, 0x50048, 0xB, 0x0, 0xB, 0x0, 0x50048, 0xB, 0x1, 0xB, 0x1, 0x50048, 0xB, 0x2, 0xB, 0x3, 0x50048, 0xB, 0x3, 0xB, 0x4, 0x30047, 0x11, 0x2, 0x40048, 0x11, 0x0, 0x5, 0x50048, 0x11, 0x0, 0x7, 0x10, 0x50048, 0x11, 0x0, 0x23, 0x0, 0x40047, 0x13, 0x21, 0x0, 0x40047, 0x13, 0x22, 0x0, 0x40047, 0x19, 0x1E, 0x0, 0x40047, 0x24, 0x1E, 0x0, 0x40047, 0x25, 0x1E, 0x1, 0x40047, 0x27, 0x1E, 0x1, 0x40047, 0x29, 0x1E, 0x2, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40015, 0x8, 0x20, 0x0, 0x4002B, 0x8, 0x9, 0x1, 0x4001C, 0xA, 0x6, 0x9, 0x6001E, 0xB, 0x7, 0x6, 0xA, 0xA, 0x40020, 0xC, 0x3, 0xB, 0x4003B, 0xC, 0xD, 0x3, 0x40015, 0xE, 0x20, 0x1, 0x4002B, 0xE, 0xF, 0x0, 0x40018, 0x10, 0x7, 0x4, 0x3001E, 0x11, 0x10, 0x40020, 0x12, 0x2, 0x11, 0x4003B, 0x12, 0x13, 0x2, 0x40020, 0x14, 0x2, 0x10, 0x40017, 0x17, 0x6, 0x2, 0x40020, 0x18, 0x1, 0x17, 0x4003B, 0x18, 0x19, 0x1, 0x4002B, 0x6, 0x1B, 0x0, 0x4002B, 0x6, 0x1C, 0x3F800000, 0x40020, 0x21, 0x3, 0x7, 0x40020, 0x23, 0x3, 0x17, 0x4003B, 0x23, 0x24, 0x3, 0x4003B, 0x18, 0x25, 0x1, 0x4003B, 0x21, 0x27, 0x3, 0x40020, 0x28, 0x1, 0x7, 0x4003B, 0x28, 0x29, 0x1, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x50041, 0x14, 0x15, 0x13, 0xF, 0x4003D, 0x10, 0x16, 0x15, 0x4003D, 0x17, 0x1A, 0x19, 0x50051, 0x6, 0x1D, 0x1A, 0x0, 0x50051, 0x6, 0x1E, 0x1A, 0x1, 0x70050, 0x7, 0x1F, 0x1D, 0x1E, 0x1B, 0x1C, 0x50091, 0x7, 0x20, 0x16, 0x1F, 0x50041, 0x21, 0x22, 0xD, 0xF, 0x3003E, 0x22, 0x20, 0x4003D, 0x17, 0x26, 0x25, 0x3003E, 0x24, 0x26, 0x4003D, 0x7, 0x2A, 0x29, 0x3003E, 0x27, 0x2A, 0x100FD, 0x10038, };
|
||||||
// clang-format on
|
// clang-format on
|
||||||
// clang-format off
|
// clang-format off
|
||||||
const unsigned int FragmentShader[] = { 0x7230203, 0x10000, 0x8000B, 0x39, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0x8000F, 0x0, 0x4, 0x6E69616D, 0x0, 0x11, 0x22, 0x24, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x30005, 0x9, 0x6374, 0x30005, 0xD, 0x786574, 0x30005, 0x11, 0x56556F, 0x50005, 0x16, 0x68737550, 0x61746144, 0x0, 0x50006, 0x16, 0x0, 0x61666C61, 0x0, 0x40005, 0x18, 0x68737570, 0x0, 0x50005, 0x22, 0x67617246, 0x6F6C6F43, 0x72, 0x40005, 0x24, 0x6C6F436F, 0x726F, 0x40047, 0xD, 0x21, 0x0, 0x40047, 0xD, 0x22, 0x0, 0x40047, 0x11, 0x1E, 0x0, 0x30047, 0x16, 0x2, 0x50048, 0x16, 0x0, 0x23, 0x0, 0x40047, 0x24, 0x1E, 0x1, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40020, 0x8, 0x7, 0x7, 0x90019, 0xA, 0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3001B, 0xB, 0xA, 0x40020, 0xC, 0x0, 0xB, 0x4003B, 0xC, 0xD, 0x0, 0x40017, 0xF, 0x6, 0x2, 0x40020, 0x10, 0x1, 0xF, 0x4003B, 0x10, 0x11, 0x1, 0x4002B, 0x6, 0x13, 0x0, 0x40015, 0x15, 0x20, 0x1, 0x3001E, 0x16, 0x15, 0x40020, 0x17, 0x9, 0x16, 0x4003B, 0x17, 0x18, 0x9, 0x4002B, 0x15, 0x19, 0x0, 0x40020, 0x1A, 0x9, 0x15, 0x20014, 0x1D, 0x40020, 0x21, 0x3, 0x7, 0x4003B, 0x21, 0x22, 0x3, 0x40020, 0x23, 0x1, 0x7, 0x4003B, 0x23, 0x24, 0x1, 0x40017, 0x25, 0x6, 0x3, 0x40015, 0x28, 0x20, 0x0, 0x4002B, 0x28, 0x29, 0x3, 0x40020, 0x2A, 0x7, 0x6, 0x40020, 0x2D, 0x1, 0x6, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x4003B, 0x8, 0x9, 0x7, 0x4003D, 0xB, 0xE, 0xD, 0x4003D, 0xF, 0x12, 0x11, 0x70058, 0x7, 0x14, 0xE, 0x12, 0x2, 0x13, 0x3003E, 0x9, 0x14, 0x50041, 0x1A, 0x1B, 0x18, 0x19, 0x4003D, 0x15, 0x1C, 0x1B, 0x500AB, 0x1D, 0x1E, 0x1C, 0x19, 0x300F7, 0x20, 0x0, 0x400FA, 0x1E, 0x1F, 0x35, 0x200F8, 0x1F, 0x4003D, 0x7, 0x26, 0x24, 0x8004F, 0x25, 0x27, 0x26, 0x26, 0x0, 0x1, 0x2, 0x50041, 0x2A, 0x2B, 0x9, 0x29, 0x4003D, 0x6, 0x2C, 0x2B, 0x50041, 0x2D, 0x2E, 0x24, 0x29, 0x4003D, 0x6, 0x2F, 0x2E, 0x50085, 0x6, 0x30, 0x2C, 0x2F, 0x50051, 0x6, 0x31, 0x27, 0x0, 0x50051, 0x6, 0x32, 0x27, 0x1, 0x50051, 0x6, 0x33, 0x27, 0x2, 0x70050, 0x7, 0x34, 0x31, 0x32, 0x33, 0x30, 0x3003E, 0x22, 0x34, 0x200F9, 0x20, 0x200F8, 0x35, 0x4003D, 0x7, 0x36, 0x9, 0x4003D, 0x7, 0x37, 0x24, 0x50085, 0x7, 0x38, 0x36, 0x37, 0x3003E, 0x22, 0x38, 0x200F9, 0x20, 0x200F8, 0x20, 0x100FD, 0x10038, };
|
const unsigned int FragmentShader[] = { 0x7230203, 0x10000, 0x8000B, 0x50, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0x8000F, 0x0, 0x4, 0x6E69616D, 0x0, 0x11, 0x2C, 0x2E, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x30005, 0x9, 0x6374, 0x30005, 0xD, 0x786574, 0x30005, 0x11, 0x56556F, 0x50005, 0x16, 0x68737550, 0x61746144, 0x0, 0x50006, 0x16, 0x0, 0x61666C61, 0x0, 0x50006, 0x16, 0x1, 0x735F7369, 0x6664, 0x40005, 0x18, 0x68737570, 0x0, 0x40005, 0x23, 0x68706C61, 0x61, 0x50005, 0x2C, 0x67617246, 0x6F6C6F43, 0x72, 0x40005, 0x2E, 0x6C6F436F, 0x726F, 0x40047, 0xD, 0x21, 0x0, 0x40047, 0xD, 0x22, 0x0, 0x40047, 0x11, 0x1E, 0x0, 0x30047, 0x16, 0x2, 0x50048, 0x16, 0x0, 0x23, 0x0, 0x50048, 0x16, 0x1, 0x23, 0x4, 0x40047, 0x2E, 0x1E, 0x1, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40020, 0x8, 0x7, 0x7, 0x90019, 0xA, 0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3001B, 0xB, 0xA, 0x40020, 0xC, 0x0, 0xB, 0x4003B, 0xC, 0xD, 0x0, 0x40017, 0xF, 0x6, 0x2, 0x40020, 0x10, 0x1, 0xF, 0x4003B, 0x10, 0x11, 0x1, 0x4002B, 0x6, 0x13, 0x0, 0x40015, 0x15, 0x20, 0x1, 0x4001E, 0x16, 0x15, 0x15, 0x40020, 0x17, 0x9, 0x16, 0x4003B, 0x17, 0x18, 0x9, 0x4002B, 0x15, 0x19, 0x1, 0x40020, 0x1A, 0x9, 0x15, 0x4002B, 0x15, 0x1D, 0x0, 0x20014, 0x1E, 0x40020, 0x22, 0x7, 0x6, 0x4002B, 0x6, 0x24, 0x3EE66666, 0x4002B, 0x6, 0x25, 0x3F0CCCCD, 0x40015, 0x26, 0x20, 0x0, 0x4002B, 0x26, 0x27, 0x3, 0x40020, 0x2B, 0x3, 0x7, 0x4003B, 0x2B, 0x2C, 0x3, 0x40020, 0x2D, 0x1, 0x7, 0x4003B, 0x2D, 0x2E, 0x1, 0x40017, 0x2F, 0x6, 0x3, 0x40020, 0x33, 0x1, 0x6, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x4003B, 0x8, 0x9, 0x7, 0x4003B, 0x22, 0x23, 0x7, 0x4003D, 0xB, 0xE, 0xD, 0x4003D, 0xF, 0x12, 0x11, 0x70058, 0x7, 0x14, 0xE, 0x12, 0x2, 0x13, 0x3003E, 0x9, 0x14, 0x50041, 0x1A, 0x1B, 0x18, 0x19, 0x4003D, 0x15, 0x1C, 0x1B, 0x500AB, 0x1E, 0x1F, 0x1C, 0x1D, 0x300F7, 0x21, 0x0, 0x400FA, 0x1F, 0x20, 0x3B, 0x200F8, 0x20, 0x50041, 0x22, 0x28, 0x9, 0x27, 0x4003D, 0x6, 0x29, 0x28, 0x8000C, 0x6, 0x2A, 0x1, 0x31, 0x24, 0x25, 0x29, 0x3003E, 0x23, 0x2A, 0x4003D, 0x7, 0x30, 0x2E, 0x8004F, 0x2F, 0x31, 0x30, 0x30, 0x0, 0x1, 0x2, 0x4003D, 0x6, 0x32, 0x23, 0x50041, 0x33, 0x34, 0x2E, 0x27, 0x4003D, 0x6, 0x35, 0x34, 0x50085, 0x6, 0x36, 0x32, 0x35, 0x50051, 0x6, 0x37, 0x31, 0x0, 0x50051, 0x6, 0x38, 0x31, 0x1, 0x50051, 0x6, 0x39, 0x31, 0x2, 0x70050, 0x7, 0x3A, 0x37, 0x38, 0x39, 0x36, 0x3003E, 0x2C, 0x3A, 0x200F9, 0x21, 0x200F8, 0x3B, 0x50041, 0x1A, 0x3C, 0x18, 0x1D, 0x4003D, 0x15, 0x3D, 0x3C, 0x500AB, 0x1E, 0x3E, 0x3D, 0x1D, 0x300F7, 0x40, 0x0, 0x400FA, 0x3E, 0x3F, 0x4C, 0x200F8, 0x3F, 0x4003D, 0x7, 0x41, 0x2E, 0x8004F, 0x2F, 0x42, 0x41, 0x41, 0x0, 0x1, 0x2, 0x50041, 0x22, 0x43, 0x9, 0x27, 0x4003D, 0x6, 0x44, 0x43, 0x50041, 0x33, 0x45, 0x2E, 0x27, 0x4003D, 0x6, 0x46, 0x45, 0x50085, 0x6, 0x47, 0x44, 0x46, 0x50051, 0x6, 0x48, 0x42, 0x0, 0x50051, 0x6, 0x49, 0x42, 0x1, 0x50051, 0x6, 0x4A, 0x42, 0x2, 0x70050, 0x7, 0x4B, 0x48, 0x49, 0x4A, 0x47, 0x3003E, 0x2C, 0x4B, 0x200F9, 0x40, 0x200F8, 0x4C, 0x4003D, 0x7, 0x4D, 0x9, 0x4003D, 0x7, 0x4E, 0x2E, 0x50085, 0x7, 0x4F, 0x4D, 0x4E, 0x3003E, 0x2C, 0x4F, 0x200F9, 0x40, 0x200F8, 0x40, 0x200F9, 0x21, 0x200F8, 0x21, 0x100FD, 0x10038, };
|
||||||
// clang-format on
|
// clang-format on
|
||||||
} // namespace Shaders
|
} // namespace Shaders
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// Gfx
|
||||||
#include <pd_system/gfx_citro3d.hpp>
|
#include <pd_system/gfx_citro3d.hpp>
|
||||||
#include <pd_system/gfx_directx9.hpp>
|
#include <pd_system/gfx_directx9.hpp>
|
||||||
#include <pd_system/gfx_opengl2.hpp>
|
#include <pd_system/gfx_opengl2.hpp>
|
||||||
#include <pd_system/gfx_opengl3.hpp>
|
#include <pd_system/gfx_opengl3.hpp>
|
||||||
|
|
||||||
|
// Hid
|
||||||
|
#include <pd_system/hid_3ds.hpp>
|
||||||
|
#include <pd_system/hid_glfw.hpp>
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ struct GfxCitro3D::Impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupPixelStage() {
|
void SetupPixelStage(bool sdf) {
|
||||||
shaderProgramUse(&pShader);
|
shaderProgramUse(&pShader);
|
||||||
C3D_BindProgram(&pShader);
|
C3D_BindProgram(&pShader);
|
||||||
C3D_SetAttrInfo(&pAttr);
|
C3D_SetAttrInfo(&pAttr);
|
||||||
@@ -92,6 +92,26 @@ struct GfxCitro3D::Impl {
|
|||||||
if (!CurrentTex) return;
|
if (!CurrentTex) return;
|
||||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||||
C3D_TexEnvInit(env);
|
C3D_TexEnvInit(env);
|
||||||
|
C3D_TexEnv* env1 = C3D_GetTexEnv(1);
|
||||||
|
C3D_TexEnvInit(env1);
|
||||||
|
|
||||||
|
if (sdf) {
|
||||||
|
C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR);
|
||||||
|
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
|
||||||
|
|
||||||
|
C3D_TexEnvColor(env, 0x60606060);
|
||||||
|
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_CONSTANT);
|
||||||
|
C3D_TexEnvOpAlpha(env, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA);
|
||||||
|
C3D_TexEnvFunc(env, C3D_Alpha, GPU_SUBTRACT);
|
||||||
|
C3D_TexEnvScale(env, C3D_Alpha, GPU_TEVSCALE_4);
|
||||||
|
|
||||||
|
C3D_TexEnvSrc(env1, C3D_RGB, GPU_PREVIOUS);
|
||||||
|
C3D_TexEnvFunc(env1, C3D_RGB, GPU_REPLACE);
|
||||||
|
|
||||||
|
C3D_TexEnvSrc(env1, C3D_Alpha, GPU_PREVIOUS, GPU_PRIMARY_COLOR);
|
||||||
|
C3D_TexEnvOpAlpha(env, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA);
|
||||||
|
C3D_TexEnvFunc(env1, C3D_Alpha, GPU_MODULATE);
|
||||||
|
} else {
|
||||||
switch (CurrentTex->fmt) {
|
switch (CurrentTex->fmt) {
|
||||||
case GPU_A4:
|
case GPU_A4:
|
||||||
case GPU_A8:
|
case GPU_A8:
|
||||||
@@ -113,12 +133,14 @@ struct GfxCitro3D::Impl {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void GfxCitro3D::SysInit() {
|
void GfxCitro3D::SysInit() {
|
||||||
if (impl) return;
|
if (impl) return;
|
||||||
PDLOG("GfxCitro3D::SysInit();");
|
PDLOG("GfxCitro3D::SysInit();");
|
||||||
impl = new Impl();
|
impl = new Impl();
|
||||||
|
Flags |= PDGfxBackendFlags_FlipUV_Y;
|
||||||
impl->pShaderRaw = Pica::AssembleCode(LIShaderCTR);
|
impl->pShaderRaw = Pica::AssembleCode(LIShaderCTR);
|
||||||
impl->pCode = DVLB_ParseFile((uint32_t*)impl->pShaderRaw.data(),
|
impl->pCode = DVLB_ParseFile((uint32_t*)impl->pShaderRaw.data(),
|
||||||
impl->pShaderRaw.size());
|
impl->pShaderRaw.size());
|
||||||
@@ -145,15 +167,12 @@ void GfxCitro3D::SysDeinit() {
|
|||||||
void GfxCitro3D::Submit(size_t count, size_t start) {
|
void GfxCitro3D::Submit(size_t count, size_t start) {
|
||||||
if (!impl) return;
|
if (!impl) return;
|
||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
impl->SetupPixelStage(); // needs to be called after
|
impl->SetupPixelStage(CurrentTexIsSDF); // needs to be called after
|
||||||
C3D_Mtx proj;
|
C3D_Mtx proj;
|
||||||
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
||||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, &proj);
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, &proj);
|
||||||
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection,
|
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection,
|
||||||
// (C3D_Mtx*)&Projection);
|
// (C3D_Mtx*)&Projection);
|
||||||
auto buf = C3D_GetBufInfo();
|
|
||||||
BufInfo_Init(buf);
|
|
||||||
BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210);
|
|
||||||
C3D_DrawElements(GPU_TRIANGLES, count, C3D_UNSIGNED_SHORT,
|
C3D_DrawElements(GPU_TRIANGLES, count, C3D_UNSIGNED_SHORT,
|
||||||
GetIndexBufPtr(start));
|
GetIndexBufPtr(start));
|
||||||
impl->CurrentTex = nullptr;
|
impl->CurrentTex = nullptr;
|
||||||
@@ -174,6 +193,13 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
int h, TextureFormat type,
|
int h, TextureFormat type,
|
||||||
TextureFilter filter) {
|
TextureFilter filter) {
|
||||||
if (!impl || w > 1024 || h > 1024) return Li::Texture();
|
if (!impl || w > 1024 || h > 1024) return Li::Texture();
|
||||||
|
if (pixels.size() !=
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type))) {
|
||||||
|
PDERR("Failed to load Texture due to Size mismatch: {} != {}",
|
||||||
|
pixels.size(),
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type)));
|
||||||
|
return Li::Texture();
|
||||||
|
}
|
||||||
// Don't check here as check done before
|
// Don't check here as check done before
|
||||||
PD::Li::Texture res;
|
PD::Li::Texture res;
|
||||||
int bpp = impl->TextureFormat2Bpp(type);
|
int bpp = impl->TextureFormat2Bpp(type);
|
||||||
@@ -232,11 +258,17 @@ void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {
|
|||||||
C3D_TexDelete(t);
|
C3D_TexDelete(t);
|
||||||
delete t;
|
delete t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxCitro3D::UploadPools() {
|
||||||
|
auto buf = C3D_GetBufInfo();
|
||||||
|
BufInfo_Init(buf);
|
||||||
|
BufInfo_Add(buf, GetVertexBufPtr(0), sizeof(Li::Vertex), 3, 0x210);
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
void GfxCitro3D::SysInit() {
|
void GfxCitro3D::SysInit() {
|
||||||
PDLOG(
|
PDERR(
|
||||||
"GfxCitro3D::SysInit: Citro3D Driver is not included in "
|
"GfxCitro3D::SysInit: Citro3D Driver is not included in "
|
||||||
"palladium-system");
|
"palladium-system");
|
||||||
}
|
}
|
||||||
@@ -250,5 +282,6 @@ Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {}
|
void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {}
|
||||||
|
void GfxCitro3D::UploadPools() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -30,14 +30,15 @@ VS_OUT main(VS_IN input) {
|
|||||||
VS_OUT o;
|
VS_OUT o;
|
||||||
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
|
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
|
||||||
o.uv = input.uv;
|
o.uv = input.uv;
|
||||||
o.col = input.col;
|
o.col = input.col.bgra;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
static const char* g_psCode = R"(
|
static const char* g_psCode = R"(
|
||||||
sampler2D tex : register(s0);
|
sampler2D tex : register(s0);
|
||||||
float alfa;
|
float alfa : register(c1);
|
||||||
|
float is_sdf : register(c2);
|
||||||
|
|
||||||
struct PS_IN {
|
struct PS_IN {
|
||||||
float2 uv : TEXCOORD0;
|
float2 uv : TEXCOORD0;
|
||||||
@@ -46,7 +47,10 @@ struct PS_IN {
|
|||||||
|
|
||||||
float4 main(PS_IN input) : COLOR0 {
|
float4 main(PS_IN input) : COLOR0 {
|
||||||
float4 tc = tex2D(tex, input.uv);
|
float4 tc = tex2D(tex, input.uv);
|
||||||
if (alfa > 0.5)
|
if (is_sdf > 0.5) {
|
||||||
|
float alpha = smoothstep(0.45, 0.55, tc.a);
|
||||||
|
return float4(input.col.rgb, alpha * input.col.a);
|
||||||
|
} else if (alfa > 0.5)
|
||||||
return float4(input.col.rgb, tc.a * input.col.a);
|
return float4(input.col.rgb, tc.a * input.col.a);
|
||||||
else
|
else
|
||||||
return tc * input.col;
|
return tc * input.col;
|
||||||
@@ -86,7 +90,7 @@ void GfxDirectX9::SysInit() {
|
|||||||
HRESULT hr = D3DCompile(g_vsCode, strlen(g_vsCode), nullptr, nullptr,
|
HRESULT hr = D3DCompile(g_vsCode, strlen(g_vsCode), nullptr, nullptr,
|
||||||
nullptr, "main", "vs_2_0", 0, 0, &vsBlob, &errBlob);
|
nullptr, "main", "vs_2_0", 0, 0, &vsBlob, &errBlob);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
PDLOG("Vertex Shader compile error: {}",
|
PDERR("Vertex Shader compile error: {}",
|
||||||
errBlob ? (char*)errBlob->GetBufferPointer() : "");
|
errBlob ? (char*)errBlob->GetBufferPointer() : "");
|
||||||
} else {
|
} else {
|
||||||
impl->Device->CreateVertexShader((DWORD*)vsBlob->GetBufferPointer(),
|
impl->Device->CreateVertexShader((DWORD*)vsBlob->GetBufferPointer(),
|
||||||
@@ -109,7 +113,7 @@ void GfxDirectX9::SysInit() {
|
|||||||
if (psBlob) psBlob->Release();
|
if (psBlob) psBlob->Release();
|
||||||
if (errBlob) errBlob->Release();
|
if (errBlob) errBlob->Release();
|
||||||
} else {
|
} else {
|
||||||
PDLOG(
|
PDERR(
|
||||||
"GfxDirectX9::SysInit Error: pDevice is not set!\nYOu need to include "
|
"GfxDirectX9::SysInit Error: pDevice is not set!\nYOu need to include "
|
||||||
"your D3D9 Device as "
|
"your D3D9 Device as "
|
||||||
"folowing:\nPD::Gfx::UseDriver<PD::GfxDirectX9>(D3D9Device);");
|
"folowing:\nPD::Gfx::UseDriver<PD::GfxDirectX9>(D3D9Device);");
|
||||||
@@ -132,44 +136,8 @@ void GfxDirectX9::Submit(size_t count, size_t start) {
|
|||||||
if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return;
|
if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return;
|
||||||
|
|
||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
impl->Device->SetVertexShaderConstantF(
|
|
||||||
0, reinterpret_cast<const float*>(&Projection), 4);
|
|
||||||
|
|
||||||
if (!impl->VBO || impl->VertexBufferSize != GetVertexPoolSize()) {
|
impl->Device->SetVertexShaderConstantF(0, Projection.Ptr(), 4);
|
||||||
if (impl->VBO) {
|
|
||||||
impl->VBO->Release();
|
|
||||||
impl->VBO = nullptr;
|
|
||||||
impl->VertexBufferSize = 0;
|
|
||||||
}
|
|
||||||
if (impl->Device->CreateVertexBuffer(
|
|
||||||
GetVertexPoolSize() * sizeof(Li::Vertex),
|
|
||||||
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT,
|
|
||||||
&impl->VBO, nullptr) < 0)
|
|
||||||
return;
|
|
||||||
impl->VertexBufferSize = GetVertexPoolSize();
|
|
||||||
}
|
|
||||||
if (!impl->IBO || impl->IndexBufferSize != GetIndexPoolSize()) {
|
|
||||||
if (impl->IBO) {
|
|
||||||
impl->IBO->Release();
|
|
||||||
impl->IBO = nullptr;
|
|
||||||
impl->IndexBufferSize = 0;
|
|
||||||
}
|
|
||||||
if (impl->Device->CreateIndexBuffer(GetVertexPoolSize() * sizeof(u16),
|
|
||||||
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
|
|
||||||
D3DFMT_INDEX16, D3DPOOL_DEFAULT,
|
|
||||||
&impl->IBO, nullptr) < 0)
|
|
||||||
return;
|
|
||||||
impl->IndexBufferSize = GetIndexPoolSize();
|
|
||||||
}
|
|
||||||
void* vptr;
|
|
||||||
impl->VBO->Lock(0, 0, &vptr, D3DLOCK_DISCARD);
|
|
||||||
memcpy(vptr, GetVertexBufPtr(0), CurrentVertex * sizeof(PD::Li::Vertex));
|
|
||||||
impl->VBO->Unlock();
|
|
||||||
|
|
||||||
void* iptr;
|
|
||||||
impl->IBO->Lock(0, 0, &iptr, D3DLOCK_DISCARD);
|
|
||||||
memcpy(iptr, GetIndexBufPtr(0), CurrentIndex * sizeof(u16));
|
|
||||||
impl->IBO->Unlock();
|
|
||||||
|
|
||||||
impl->Device->SetStreamSource(0, impl->VBO, 0, sizeof(PD::Li::Vertex));
|
impl->Device->SetStreamSource(0, impl->VBO, 0, sizeof(PD::Li::Vertex));
|
||||||
impl->Device->SetIndices(impl->IBO);
|
impl->Device->SetIndices(impl->IBO);
|
||||||
@@ -177,8 +145,8 @@ void GfxDirectX9::Submit(size_t count, size_t start) {
|
|||||||
impl->Device->SetVertexShader(impl->VS);
|
impl->Device->SetVertexShader(impl->VS);
|
||||||
impl->Device->SetPixelShader(impl->FS);
|
impl->Device->SetPixelShader(impl->FS);
|
||||||
|
|
||||||
impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, CurrentVertex,
|
impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,
|
||||||
start, count / 3);
|
GetVertexPoolSize(), start, count / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxDirectX9::BindTexture(TextureID id) {
|
void GfxDirectX9::BindTexture(TextureID id) {
|
||||||
@@ -195,20 +163,35 @@ void GfxDirectX9::BindTexture(TextureID id) {
|
|||||||
|
|
||||||
float v = a8 ? 1.0f : 0.0f;
|
float v = a8 ? 1.0f : 0.0f;
|
||||||
impl->Device->SetPixelShaderConstantF(0, &v, 1);
|
impl->Device->SetPixelShaderConstantF(0, &v, 1);
|
||||||
|
|
||||||
|
float sdf = CurrentTexIsSDF ? 1.0f : 0.0f;
|
||||||
|
impl->Device->SetPixelShaderConstantF(1, &sdf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxDirectX9::SysReset() {
|
void GfxDirectX9::SysReset() {
|
||||||
if (!impl || !impl->Device) return;
|
if (!impl || !impl->Device) return;
|
||||||
|
|
||||||
|
impl->Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||||
impl->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
impl->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||||
impl->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
impl->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||||
impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||||
|
|
||||||
|
impl->Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||||
|
impl->Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||||
|
impl->Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||||
int h, TextureFormat type,
|
int h, TextureFormat type,
|
||||||
TextureFilter filter) {
|
TextureFilter filter) {
|
||||||
if (!impl || !impl->Device) return Li::Texture();
|
if (!impl || !impl->Device) return Li::Texture();
|
||||||
|
if (pixels.size() !=
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type))) {
|
||||||
|
PDERR("Failed to load Texture due to Size mismatch: {} != {}",
|
||||||
|
pixels.size(),
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type)));
|
||||||
|
return Li::Texture();
|
||||||
|
}
|
||||||
IDirect3DTexture9* tex = nullptr;
|
IDirect3DTexture9* tex = nullptr;
|
||||||
D3DFORMAT fmt = D3DFMT_A8R8G8B8;
|
D3DFORMAT fmt = D3DFMT_A8R8G8B8;
|
||||||
if (type == TextureFormat::RGB24)
|
if (type == TextureFormat::RGB24)
|
||||||
@@ -272,11 +255,41 @@ void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {
|
|||||||
IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID();
|
IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID();
|
||||||
t->Release();
|
t->Release();
|
||||||
}
|
}
|
||||||
|
void GfxDirectX9::UploadPools() {
|
||||||
|
if (!impl || !impl->Device) return;
|
||||||
|
|
||||||
|
if (!impl->VBO || impl->VertexBufferSize != GetVertexPoolSize()) {
|
||||||
|
if (impl->VBO) impl->VBO->Release();
|
||||||
|
impl->Device->CreateVertexBuffer(GetVertexPoolSize() * sizeof(Li::Vertex),
|
||||||
|
D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED,
|
||||||
|
&impl->VBO, nullptr);
|
||||||
|
impl->VertexBufferSize = GetVertexPoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!impl->IBO || impl->IndexBufferSize != GetIndexPoolSize()) {
|
||||||
|
if (impl->IBO) impl->IBO->Release();
|
||||||
|
impl->Device->CreateIndexBuffer(GetIndexPoolSize() * sizeof(u16),
|
||||||
|
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
|
||||||
|
D3DPOOL_MANAGED, &impl->IBO, nullptr);
|
||||||
|
impl->IndexBufferSize = GetIndexPoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vptr;
|
||||||
|
impl->VBO->Lock(0, 0, &vptr, 0);
|
||||||
|
memcpy(vptr, GetVertexBufPtr(0),
|
||||||
|
GetVertexPoolSize() * sizeof(PD::Li::Vertex));
|
||||||
|
impl->VBO->Unlock();
|
||||||
|
|
||||||
|
void* iptr;
|
||||||
|
impl->IBO->Lock(0, 0, &iptr, 0);
|
||||||
|
memcpy(iptr, GetIndexBufPtr(0), GetIndexPoolSize() * sizeof(u16));
|
||||||
|
impl->IBO->Unlock();
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
void GfxDirectX9::SysInit() {
|
void GfxDirectX9::SysInit() {
|
||||||
PDLOG(
|
PDERR(
|
||||||
"GfxDirectX9::SysInit: DirectX9 Driver is not included in "
|
"GfxDirectX9::SysInit: DirectX9 Driver is not included in "
|
||||||
"palladium-system");
|
"palladium-system");
|
||||||
}
|
}
|
||||||
@@ -290,5 +303,6 @@ Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {}
|
void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {}
|
||||||
|
void GfxDirectX9::UploadPools() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -38,10 +38,15 @@ const char* GfxOpenGL2::pFragCode = R"(
|
|||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
uniform bool alfa;
|
uniform bool alfa;
|
||||||
|
uniform bool is_sdf;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 tc = texture2D(tex, oUV);
|
vec4 tc = texture2D(tex, oUV);
|
||||||
if (alfa) {
|
if (is_sdf) {
|
||||||
|
float dist = tc.a;
|
||||||
|
float alpha = smoothstep(0.45, 0.55, dist);
|
||||||
|
gl_FragColor = vec4(oColor.rgb, alpha * oColor.a);
|
||||||
|
} else if (alfa) {
|
||||||
gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
||||||
} else {
|
} else {
|
||||||
gl_FragColor = tc * oColor;
|
gl_FragColor = tc * oColor;
|
||||||
@@ -78,14 +83,11 @@ void GfxOpenGL2::SysInit() {
|
|||||||
pSetupShaderAttribs(pShader);
|
pSetupShaderAttribs(pShader);
|
||||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||||
pLocAlfa = glGetUniformLocation(pShader, "alfa");
|
pLocAlfa = glGetUniformLocation(pShader, "alfa");
|
||||||
|
pLocIsSDF = glGetUniformLocation(pShader, "is_sdf");
|
||||||
pLocProjection = glGetUniformLocation(pShader, "projection");
|
pLocProjection = glGetUniformLocation(pShader, "projection");
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
PDLOG(
|
|
||||||
"GfxOpenGL2::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
|
|
||||||
"{}\n pLocProjection = {}\n VBO = {}\n IBO = {}",
|
|
||||||
pShader, pLocTex, pLocAlfa, pLocProjection, VBO, IBO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGL2::SysDeinit() {
|
void GfxOpenGL2::SysDeinit() {
|
||||||
@@ -98,19 +100,14 @@ void GfxOpenGL2::Submit(size_t count, size_t start) {
|
|||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
glUseProgram(pShader);
|
glUseProgram(pShader);
|
||||||
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
|
||||||
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
|
|
||||||
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
pSetupShaderAttribs(pShader);
|
pSetupShaderAttribs(pShader);
|
||||||
GLint ibo = 0;
|
|
||||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo);
|
|
||||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
||||||
reinterpret_cast<void*>(start * sizeof(u16)));
|
reinterpret_cast<void*>(start * sizeof(u16)));
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
BindTexture(0);
|
BindTexture(0);
|
||||||
@@ -123,6 +120,7 @@ void GfxOpenGL2::BindTexture(TextureID id) {
|
|||||||
GLint fmt = 0;
|
GLint fmt = 0;
|
||||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
||||||
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
||||||
|
glUniform1i(pLocIsSDF, CurrentTexIsSDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGL2::SysReset() {
|
void GfxOpenGL2::SysReset() {
|
||||||
@@ -133,6 +131,13 @@ void GfxOpenGL2::SysReset() {
|
|||||||
Li::Texture GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
Li::Texture GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||||
int h, TextureFormat type,
|
int h, TextureFormat type,
|
||||||
TextureFilter filter) {
|
TextureFilter filter) {
|
||||||
|
if (pixels.size() !=
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type))) {
|
||||||
|
PDERR("Failed to load Texture due to Size mismatch: {} != {}",
|
||||||
|
pixels.size(),
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type)));
|
||||||
|
return Li::Texture();
|
||||||
|
}
|
||||||
GLuint texID;
|
GLuint texID;
|
||||||
glGenTextures(1, &texID);
|
glGenTextures(1, &texID);
|
||||||
glBindTexture(GL_TEXTURE_2D, texID);
|
glBindTexture(GL_TEXTURE_2D, texID);
|
||||||
@@ -168,11 +173,21 @@ void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {
|
|||||||
GLuint tex_ = tex.GetID();
|
GLuint tex_ = tex.GetID();
|
||||||
glDeleteTextures(1, &tex_);
|
glDeleteTextures(1, &tex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxOpenGL2::UploadPools() {
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex),
|
||||||
|
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16),
|
||||||
|
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
void GfxOpenGL2::SysInit() {
|
void GfxOpenGL2::SysInit() {
|
||||||
PDLOG(
|
PDERR(
|
||||||
"GfxOpenGL2::SysInit: OpenGL2 Driver is not included in "
|
"GfxOpenGL2::SysInit: OpenGL2 Driver is not included in "
|
||||||
"palladium-system");
|
"palladium-system");
|
||||||
}
|
}
|
||||||
@@ -187,5 +202,6 @@ Li::Texture GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
}
|
}
|
||||||
void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {}
|
void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {}
|
||||||
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {}
|
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {}
|
||||||
|
void GfxOpenGL2::UploadPools() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -47,15 +47,12 @@ void GfxOpenGL3::SysInit() {
|
|||||||
|
|
||||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||||
pLocAlfa = glGetUniformLocation(pShader, "push.alfa");
|
pLocAlfa = glGetUniformLocation(pShader, "push.alfa");
|
||||||
|
pLocIsSDF = glGetUniformLocation(pShader, "push.is_sdf");
|
||||||
pLocProjection = glGetUniformLocation(pShader, "ubo.projection");
|
pLocProjection = glGetUniformLocation(pShader, "ubo.projection");
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
PDLOG(
|
|
||||||
"GfxOpenGL3::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
|
|
||||||
"{}\n pLocProjection = {}\n VBO = {}\n IBO = {}, VAO = {}",
|
|
||||||
pShader, pLocTex, pLocAlfa, pLocProjection, VBO, IBO, VAO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGL3::SysDeinit() {
|
void GfxOpenGL3::SysDeinit() {
|
||||||
@@ -69,20 +66,12 @@ void GfxOpenGL3::Submit(size_t count, size_t start) {
|
|||||||
BindTexture(CurrentTex);
|
BindTexture(CurrentTex);
|
||||||
glUseProgram(pShader);
|
glUseProgram(pShader);
|
||||||
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||||
|
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
|
||||||
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(u16),
|
|
||||||
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
|
||||||
reinterpret_cast<void*>(start * sizeof(u16)));
|
reinterpret_cast<void*>(start * sizeof(u16)));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
BindTexture(0);
|
BindTexture(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +81,8 @@ void GfxOpenGL3::BindTexture(TextureID id) {
|
|||||||
glUniform1i(pLocTex, 0);
|
glUniform1i(pLocTex, 0);
|
||||||
GLint fmt = 0;
|
GLint fmt = 0;
|
||||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
||||||
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
glUniform1i(pLocAlfa, fmt == GL_R8);
|
||||||
|
glUniform1i(pLocIsSDF, CurrentTexIsSDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGL3::SysReset() {
|
void GfxOpenGL3::SysReset() {
|
||||||
@@ -103,19 +93,36 @@ void GfxOpenGL3::SysReset() {
|
|||||||
Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||||
int h, TextureFormat type,
|
int h, TextureFormat type,
|
||||||
TextureFilter filter) {
|
TextureFilter filter) {
|
||||||
|
if (pixels.size() !=
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type))) {
|
||||||
|
PDERR("Failed to load Texture due to Size mismatch: {} != {}",
|
||||||
|
pixels.size(),
|
||||||
|
static_cast<size_t>(w * h * Li::TextureFormat2Bpp(type)));
|
||||||
|
return Li::Texture();
|
||||||
|
}
|
||||||
GLuint texID;
|
GLuint texID;
|
||||||
glGenTextures(1, &texID);
|
glGenTextures(1, &texID);
|
||||||
glBindTexture(GL_TEXTURE_2D, texID);
|
glBindTexture(GL_TEXTURE_2D, texID);
|
||||||
|
|
||||||
// Set base format (Always using RGBA as base)
|
// Set base format (Always using RGBA as base)
|
||||||
GLenum fmt = GL_RGBA;
|
GLenum fmt = GL_RGBA;
|
||||||
|
GLenum ifmt = GL_RGBA8;
|
||||||
if (type == TextureFormat::RGB24) {
|
if (type == TextureFormat::RGB24) {
|
||||||
|
ifmt = GL_RGB8;
|
||||||
fmt = GL_RGB;
|
fmt = GL_RGB;
|
||||||
} else if (type == TextureFormat::A8) {
|
} else if (type == TextureFormat::A8) {
|
||||||
fmt = GL_ALPHA;
|
ifmt = GL_R8;
|
||||||
|
fmt = GL_RED;
|
||||||
}
|
}
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
|
glTexImage2D(GL_TEXTURE_2D, 0, ifmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
|
||||||
pixels.data());
|
pixels.data());
|
||||||
|
|
||||||
|
if (type == TextureFormat::A8) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||||
|
}
|
||||||
if (filter == TextureFilter::Linear) {
|
if (filter == TextureFilter::Linear) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
@@ -138,11 +145,25 @@ void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {
|
|||||||
GLuint tex_ = tex.GetID();
|
GLuint tex_ = tex.GetID();
|
||||||
glDeleteTextures(1, &tex_);
|
glDeleteTextures(1, &tex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxOpenGL3::UploadPools() {
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, GetVertexPoolSize() * sizeof(PD::Li::Vertex),
|
||||||
|
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, GetIndexPoolSize() * sizeof(u16),
|
||||||
|
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#else
|
#else
|
||||||
namespace PD {
|
namespace PD {
|
||||||
void GfxOpenGL3::SysInit() {
|
void GfxOpenGL3::SysInit() {
|
||||||
PDLOG(
|
PDERR(
|
||||||
"GfxOpenGL3::SysInit: OpenGL3 Driver is not included in "
|
"GfxOpenGL3::SysInit: OpenGL3 Driver is not included in "
|
||||||
"palladium-system");
|
"palladium-system");
|
||||||
}
|
}
|
||||||
@@ -156,5 +177,6 @@ Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {}
|
void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {}
|
||||||
|
void GfxOpenGL3::UploadPools() {}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#include <pd_system/hid_3ds.hpp>
|
||||||
|
#if defined(PD_ENABLE_HID3DS) && defined(__3DS__)
|
||||||
|
#include <3ds.h>
|
||||||
|
namespace PD {
|
||||||
|
struct Hid3DS::Impl {
|
||||||
|
std::string* Text;
|
||||||
|
bool InTextMode = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Hid3DS::Hid3DS() : HidDriver("Hid3DS") {
|
||||||
|
impl = new Impl;
|
||||||
|
|
||||||
|
pFlags |= PDHidBackendFlags_HasGamepad;
|
||||||
|
pFlags |= PDHidBackendFlags_HasTouch;
|
||||||
|
|
||||||
|
pGamepad[KEY_A] = HidInternal::Gamepad::A;
|
||||||
|
pGamepad[KEY_B] = HidInternal::Gamepad::B;
|
||||||
|
pGamepad[KEY_X] = HidInternal::Gamepad::X;
|
||||||
|
pGamepad[KEY_Y] = HidInternal::Gamepad::Y;
|
||||||
|
pGamepad[KEY_START] = HidInternal::Gamepad::Start;
|
||||||
|
pGamepad[KEY_SELECT] = HidInternal::Gamepad::Select;
|
||||||
|
pGamepad[KEY_L] = HidInternal::Gamepad::L;
|
||||||
|
pGamepad[KEY_R] = HidInternal::Gamepad::R;
|
||||||
|
pGamepad[KEY_DUP] = HidInternal::Gamepad::DUp;
|
||||||
|
pGamepad[KEY_DDOWN] = HidInternal::Gamepad::DDown;
|
||||||
|
pGamepad[KEY_DLEFT] = HidInternal::Gamepad::DLeft;
|
||||||
|
pGamepad[KEY_DRIGHT] = HidInternal::Gamepad::DRight;
|
||||||
|
pGamepad[KEY_CPAD_UP] = HidInternal::Gamepad::CPUp;
|
||||||
|
pGamepad[KEY_CPAD_DOWN] = HidInternal::Gamepad::CPDown;
|
||||||
|
pGamepad[KEY_CPAD_LEFT] = HidInternal::Gamepad::CPLeft;
|
||||||
|
pGamepad[KEY_CPAD_RIGHT] = HidInternal::Gamepad::CPRight;
|
||||||
|
pGamepad[KEY_CSTICK_UP] = HidInternal::Gamepad::CSUp;
|
||||||
|
pGamepad[KEY_CSTICK_DOWN] = HidInternal::Gamepad::CSDown;
|
||||||
|
pGamepad[KEY_CSTICK_LEFT] = HidInternal::Gamepad::CSLeft;
|
||||||
|
pGamepad[KEY_CSTICK_RIGHT] = HidInternal::Gamepad::CSRight;
|
||||||
|
pGamepad[KEY_ZL] = HidInternal::Gamepad::ZL;
|
||||||
|
pGamepad[KEY_ZR] = HidInternal::Gamepad::ZR;
|
||||||
|
pGamepad[KEY_TOUCH] = HidInternal::Gamepad::Touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hid3DS::~Hid3DS() { delete impl; }
|
||||||
|
|
||||||
|
void Hid3DS::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
hidScanInput();
|
||||||
|
u32 kd = hidKeysDown();
|
||||||
|
u32 kh = hidKeysHeld();
|
||||||
|
u32 ku = hidKeysUp();
|
||||||
|
|
||||||
|
for (const auto& b : pGamepad) {
|
||||||
|
if (b.first & kd) {
|
||||||
|
pGamepadEvents[0][Event::Down] |= b.second;
|
||||||
|
}
|
||||||
|
if (b.first & kh) {
|
||||||
|
pGamepadEvents[0][Event::Held] |= b.second;
|
||||||
|
}
|
||||||
|
if (b.first & ku) {
|
||||||
|
pGamepadEvents[0][Event::Up] |= b.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (pLocked) {
|
||||||
|
SwapTab();
|
||||||
|
}*/
|
||||||
|
touchPosition t;
|
||||||
|
hidTouchRead(&t);
|
||||||
|
pMouse[0] = fvec2(t.px, t.py);
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#else
|
||||||
|
struct GLFWgamepadstate {};
|
||||||
|
namespace PD {
|
||||||
|
|
||||||
|
Hid3DS::Hid3DS() : HidDriver("Hid3DS") {}
|
||||||
|
|
||||||
|
Hid3DS::~Hid3DS() {}
|
||||||
|
|
||||||
|
void Hid3DS::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
#include <pd_system/hid_glfw.hpp>
|
||||||
|
#ifdef PD_ENABLE_HID_GLFW
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
struct HidGlfw::Impl {
|
||||||
|
GLFWwindow* Win;
|
||||||
|
int PrevState;
|
||||||
|
std::unordered_map<int, int> PrevStates;
|
||||||
|
std::unordered_map<int, int> GPPrevStates;
|
||||||
|
GLFWcharfun OldTextCB;
|
||||||
|
std::string* Text;
|
||||||
|
bool InTextMode = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int KEY_BASE = GLFW_GAMEPAD_BUTTON_LAST;
|
||||||
|
constexpr int KEY_LSTICK_LEFT = KEY_BASE + 1;
|
||||||
|
constexpr int KEY_LSTICK_RIGHT = KEY_BASE + 2;
|
||||||
|
constexpr int KEY_LSTICK_UP = KEY_BASE + 3;
|
||||||
|
constexpr int KEY_LSTICK_DOWN = KEY_BASE + 4;
|
||||||
|
constexpr int KEY_RSTICK_LEFT = KEY_BASE + 5;
|
||||||
|
constexpr int KEY_RSTICK_RIGHT = KEY_BASE + 6;
|
||||||
|
constexpr int KEY_RSTICK_UP = KEY_BASE + 7;
|
||||||
|
constexpr int KEY_RSTICK_DOWN = KEY_BASE + 8;
|
||||||
|
constexpr int KEY_LEFT_TRIGGER = KEY_BASE + 9;
|
||||||
|
constexpr int KEY_RIGHT_TRIGGER = KEY_BASE + 10;
|
||||||
|
constexpr int KEY_LAST = KEY_RIGHT_TRIGGER;
|
||||||
|
|
||||||
|
HidGlfw::HidGlfw(GLFWwindow* win) : HidDriver("HidGlfw") {
|
||||||
|
impl = new Impl;
|
||||||
|
impl->Win = win;
|
||||||
|
|
||||||
|
pFlags |= PDHidBackendFlags_HasMouse;
|
||||||
|
pFlags |= PDHidBackendFlags_HasKeyboard;
|
||||||
|
if (glfwJoystickPresent(GLFW_JOYSTICK_1)) {
|
||||||
|
pFlags |= PDHidBackendFlags_HasGamepad;
|
||||||
|
}
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_A] = HidInternal::Gamepad::A;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_B] = HidInternal::Gamepad::B;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_X] = HidInternal::Gamepad::X;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_Y] = HidInternal::Gamepad::Y;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_START] = HidInternal::Gamepad::Start;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_BACK] = HidInternal::Gamepad::Select;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_LEFT] = HidInternal::Gamepad::DLeft;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_RIGHT] = HidInternal::Gamepad::DRight;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_UP] = HidInternal::Gamepad::DUp;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_DPAD_DOWN] = HidInternal::Gamepad::DDown;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_LEFT_BUMPER] = HidInternal::Gamepad::L;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER] = HidInternal::Gamepad::R;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_LEFT_THUMB] = HidInternal::Gamepad::LStick;
|
||||||
|
pGamepad[GLFW_GAMEPAD_BUTTON_RIGHT_THUMB] = HidInternal::Gamepad::RStick;
|
||||||
|
pGamepad[KEY_LEFT_TRIGGER] = HidInternal::Gamepad::ZL;
|
||||||
|
pGamepad[KEY_RIGHT_TRIGGER] = HidInternal::Gamepad::ZR;
|
||||||
|
pGamepad[KEY_LSTICK_LEFT] = HidInternal::Gamepad::CPLeft;
|
||||||
|
pGamepad[KEY_LSTICK_RIGHT] = HidInternal::Gamepad::CPRight;
|
||||||
|
pGamepad[KEY_LSTICK_UP] = HidInternal::Gamepad::CPUp;
|
||||||
|
pGamepad[KEY_LSTICK_DOWN] = HidInternal::Gamepad::CPDown;
|
||||||
|
pGamepad[KEY_RSTICK_LEFT] = HidInternal::Gamepad::CSLeft;
|
||||||
|
pGamepad[KEY_RSTICK_RIGHT] = HidInternal::Gamepad::CSRight;
|
||||||
|
pGamepad[KEY_RSTICK_UP] = HidInternal::Gamepad::CSUp;
|
||||||
|
pGamepad[KEY_RSTICK_DOWN] = HidInternal::Gamepad::CSDown;
|
||||||
|
for (int i = 0; i <= KEY_LAST; i++) {
|
||||||
|
impl->GPPrevStates[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HidGlfw::~HidGlfw() { delete impl; }
|
||||||
|
|
||||||
|
void HidGlfw::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
GLFWgamepadstate gpstate;
|
||||||
|
int gps = glfwGetGamepadState(GLFW_JOYSTICK_1, &gpstate);
|
||||||
|
if (gps == GLFW_TRUE) {
|
||||||
|
HandleAxisKey(gpstate, KEY_LEFT_TRIGGER, GLFW_GAMEPAD_AXIS_LEFT_TRIGGER,
|
||||||
|
false);
|
||||||
|
HandleAxisKey(gpstate, KEY_RIGHT_TRIGGER, GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER,
|
||||||
|
false);
|
||||||
|
HandleAxisKey(gpstate, KEY_LSTICK_LEFT, GLFW_GAMEPAD_AXIS_LEFT_X, true);
|
||||||
|
HandleAxisKey(gpstate, KEY_LSTICK_RIGHT, GLFW_GAMEPAD_AXIS_LEFT_X, false);
|
||||||
|
HandleAxisKey(gpstate, KEY_LSTICK_UP, GLFW_GAMEPAD_AXIS_LEFT_Y, true);
|
||||||
|
HandleAxisKey(gpstate, KEY_LSTICK_DOWN, GLFW_GAMEPAD_AXIS_LEFT_Y, false);
|
||||||
|
HandleAxisKey(gpstate, KEY_RSTICK_LEFT, GLFW_GAMEPAD_AXIS_RIGHT_X, true);
|
||||||
|
HandleAxisKey(gpstate, KEY_RSTICK_RIGHT, GLFW_GAMEPAD_AXIS_RIGHT_X, false);
|
||||||
|
HandleAxisKey(gpstate, KEY_RSTICK_UP, GLFW_GAMEPAD_AXIS_RIGHT_Y, true);
|
||||||
|
HandleAxisKey(gpstate, KEY_RSTICK_DOWN, GLFW_GAMEPAD_AXIS_RIGHT_Y, false);
|
||||||
|
pLStick[0].x = gpstate.axes[GLFW_GAMEPAD_AXIS_LEFT_X];
|
||||||
|
pLStick[0].y = gpstate.axes[GLFW_GAMEPAD_AXIS_LEFT_Y];
|
||||||
|
pRStick[0].x = gpstate.axes[GLFW_GAMEPAD_AXIS_RIGHT_X];
|
||||||
|
pRStick[0].y = gpstate.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y];
|
||||||
|
for (int i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) {
|
||||||
|
if (gpstate.buttons[i] == GLFW_PRESS) {
|
||||||
|
if (impl->GPPrevStates[i] == GLFW_RELEASE) {
|
||||||
|
pGamepadEvents[0][Event::Down] |= pGamepad[i];
|
||||||
|
}
|
||||||
|
pGamepadEvents[0][Event::Held] |= pGamepad[i];
|
||||||
|
} else if (gpstate.buttons[i] == GLFW_RELEASE &&
|
||||||
|
impl->GPPrevStates[i] == GLFW_PRESS) {
|
||||||
|
pGamepadEvents[0][Event::Up] |= pGamepad[i];
|
||||||
|
}
|
||||||
|
impl->GPPrevStates[i] = gpstate.buttons[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int state = glfwGetMouseButton(impl->Win, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
|
if (state == GLFW_PRESS) {
|
||||||
|
if (impl->PrevState == GLFW_RELEASE) {
|
||||||
|
pGamepadEvents[0][Event::Down] |= HidInternal::Touch;
|
||||||
|
}
|
||||||
|
pGamepadEvents[0][Event::Held] |= HidInternal::Touch;
|
||||||
|
} else if (state == GLFW_RELEASE && impl->PrevState == GLFW_PRESS) {
|
||||||
|
pGamepadEvents[0][Event::Up] |= HidInternal::Touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl->PrevState = state;
|
||||||
|
// if (pLocked) {
|
||||||
|
// SwapTab();
|
||||||
|
// }
|
||||||
|
double x, y;
|
||||||
|
glfwGetCursorPos(impl->Win, &x, &y);
|
||||||
|
pMouse[0] = fvec2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HidGlfw::HandleAxisKey(GLFWgamepadstate s, int iK, int eA, bool negative) {
|
||||||
|
if (s.axes[eA] <= 1.f && s.axes[eA] >= -1.f) {
|
||||||
|
if (s.axes[eA] > 0.05f && !negative) {
|
||||||
|
if (impl->GPPrevStates[iK] == GLFW_RELEASE) {
|
||||||
|
pGamepadEvents[0][Event::Down] |= pGamepad[iK];
|
||||||
|
}
|
||||||
|
pGamepadEvents[0][Event::Held] |= pGamepad[iK];
|
||||||
|
}
|
||||||
|
if (s.axes[eA] < -0.05f && negative) {
|
||||||
|
if (impl->GPPrevStates[iK] == GLFW_RELEASE) {
|
||||||
|
pGamepadEvents[0][Event::Down] |= pGamepad[iK];
|
||||||
|
}
|
||||||
|
pGamepadEvents[0][Event::Held] |= pGamepad[iK];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl->GPPrevStates[iK] = (s.axes[eA] <= -0.05 && s.axes[eA] >= 0.05 &&
|
||||||
|
s.axes[eA] >= -1.f && s.axes[eA] <= 1);
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#else
|
||||||
|
struct GLFWgamepadstate {};
|
||||||
|
namespace PD {
|
||||||
|
|
||||||
|
HidGlfw::HidGlfw(GLFWwindow* win) : HidDriver("HidGlfw") {}
|
||||||
|
|
||||||
|
HidGlfw::~HidGlfw() {}
|
||||||
|
|
||||||
|
void HidGlfw::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
}
|
||||||
|
void HidGlfw::HandleAxisKey(GLFWgamepadstate s, int iK, int eA, bool negative) {
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
#include <pd_system/hid_nx.hpp>
|
||||||
|
|
||||||
|
#ifdef PD_ENABLE_HID_NX
|
||||||
|
#include <switch.h>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
struct HidNX::Impl {
|
||||||
|
PadState Pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
HidNX::HidNX() : HidDriver("HidNX") { impl = new Impl; }
|
||||||
|
|
||||||
|
HidNX::~HidNX() { delete impl; }
|
||||||
|
|
||||||
|
void HidNX::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#else
|
||||||
|
namespace PD {
|
||||||
|
|
||||||
|
HidNX::HidNX() : HidDriver("HidNX") {}
|
||||||
|
|
||||||
|
HidNX::~HidNX() {}
|
||||||
|
|
||||||
|
void HidNX::Update() {
|
||||||
|
HidDriver::Update(); // clear stats
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"version": 10,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "3ds-debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"displayName": "Nintendo 3DS Debug",
|
||||||
|
"binaryDir": "${sourceDir}/build/3ds-debug",
|
||||||
|
"toolchainFile": "/opt/devkitPro/cmake/3DS.cmake",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "3ds-release",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"displayName": "Nintendo 3DS Release",
|
||||||
|
"binaryDir": "${sourceDir}/build/3ds-release",
|
||||||
|
"toolchainFile": "/opt/devkitPro/cmake/3DS.cmake",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "3ds-release",
|
||||||
|
"configurePreset": "3ds-release"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "3ds-debug",
|
||||||
|
"configurePreset": "3ds-debug"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"version": 10,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "default-debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"displayName": "Default Debug",
|
||||||
|
"binaryDir": "${sourceDir}/build/default-debug",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "default-release",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"displayName": "Default Release",
|
||||||
|
"binaryDir": "${sourceDir}/build/default-release",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "default-release",
|
||||||
|
"configurePreset": "default-release"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "default-debug",
|
||||||
|
"configurePreset": "default-debug"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"version": 10,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "msvc",
|
||||||
|
"cmakeExecutable": "C:\\Program Files\\CMake\\bin\\cmake.exe",
|
||||||
|
"displayName": "MSVC",
|
||||||
|
"generator": "Visual Studio 17 2022",
|
||||||
|
"binaryDir": "${sourceDir}/build/msvc-build"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "msvc-release",
|
||||||
|
"configuration": "Release",
|
||||||
|
"configurePreset": "msvc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "msvc-debug",
|
||||||
|
"configuration": "Debug",
|
||||||
|
"configurePreset": "msvc"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"version": 10,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "switch-debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"displayName": "Nintendo Switch Debug",
|
||||||
|
"binaryDir": "${sourceDir}/build/switch-debug",
|
||||||
|
"toolchainFile": "/opt/devkitPro/cmake/Switch.cmake",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"SPV_EXCLUDE_GLSLANG": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "switch-release",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"displayName": "Nintendo Switch Release",
|
||||||
|
"binaryDir": "${sourceDir}/build/switch-release",
|
||||||
|
"toolchainFile": "/opt/devkitPro/cmake/Switch.cmake",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release",
|
||||||
|
"SPV_EXCLUDE_GLSLANG": "ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "switch-release",
|
||||||
|
"configurePreset": "switch-release"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "switch-debug",
|
||||||
|
"configurePreset": "switch-debug"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -25,4 +25,6 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include <pd/core/core.hpp>
|
#include <pd/core/core.hpp>
|
||||||
#include <pd/drivers/drivers.hpp>
|
#include <pd/drivers/drivers.hpp>
|
||||||
|
#include <pd/image/image.hpp>
|
||||||
#include <pd/lithium/lithium.hpp>
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
#include <pd/ui7/ui7.hpp>
|
||||||
+48
-2
@@ -23,6 +23,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(__GNUG__) && !defined(_MSC_VER)
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@@ -39,6 +43,12 @@ SOFTWARE.
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
|
enum class LogLevel {
|
||||||
|
None,
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
[[noreturn]] inline void Throw(const std::string& msg) {
|
[[noreturn]] inline void Throw(const std::string& msg) {
|
||||||
throw std::runtime_error(msg);
|
throw std::runtime_error(msg);
|
||||||
}
|
}
|
||||||
@@ -47,17 +57,53 @@ using u16 = unsigned short;
|
|||||||
using u32 = unsigned int;
|
using u32 = unsigned int;
|
||||||
using u64 = unsigned long long;
|
using u64 = unsigned long long;
|
||||||
using ptr = uintptr_t;
|
using ptr = uintptr_t;
|
||||||
PD_API void Log(const std::string& txt);
|
PD_API void LogFilter(LogLevel minimum);
|
||||||
|
PD_API void Log(const std::string& txt, LogLevel lvl = LogLevel::Info);
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void Log(std::format_string<Args...> fmt, Args&&... args) {
|
void Log(std::format_string<Args...> fmt, Args&&... args) {
|
||||||
std::string msg = std::format(fmt, std::forward<Args>(args)...);
|
std::string msg = std::format(fmt, std::forward<Args>(args)...);
|
||||||
Log(msg);
|
Log(msg, LogLevel::Info);
|
||||||
|
}
|
||||||
|
template <typename... Args>
|
||||||
|
void Log(LogLevel lvl, std::format_string<Args...> fmt, Args&&... args) {
|
||||||
|
std::string msg = std::format(fmt, std::forward<Args>(args)...);
|
||||||
|
Log(msg, lvl);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
std::string TypeName() {
|
||||||
|
#ifdef __RTTI
|
||||||
|
#if defined(__GNUG__) && !defined(_MSC_VER)
|
||||||
|
int res = 0;
|
||||||
|
std::unique_ptr<char, void (*)(void*)> up{
|
||||||
|
abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &res), std::free};
|
||||||
|
return (res == 0) ? up.get() : typeid(T).name();
|
||||||
|
#else
|
||||||
|
return typeid(T).name(); // no demangler available :/
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define PDPRETTYFUNC __PRETTY_FUNCTION__
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define PDPRETTYFUNC __FUNCSIG__
|
||||||
|
#else
|
||||||
|
#define PDPRETTYFUNC __FUNCTION__
|
||||||
|
#endif
|
||||||
#ifdef PD_DEBUG
|
#ifdef PD_DEBUG
|
||||||
#define PDLOG(fmt, ...) \
|
#define PDLOG(fmt, ...) \
|
||||||
PD::Log("[{}:{}]: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
|
PD::Log("[{}:{}]: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
|
||||||
|
#define PDWARN(fmt, ...) \
|
||||||
|
PD::Log(PD::LogLevel::Warning, "[{}:{}]: " fmt, __FILE__, __LINE__, \
|
||||||
|
##__VA_ARGS__)
|
||||||
|
#define PDERR(fmt, ...) \
|
||||||
|
PD::Log(PD::LogLevel::Error, "[{}:{}]: " fmt, __FILE__, __LINE__, \
|
||||||
|
##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define PDLOG(fmt, ...)
|
#define PDLOG(fmt, ...)
|
||||||
|
#define PDWARN(fmt, ...)
|
||||||
|
#define PDERR(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
@@ -71,6 +71,12 @@ class PD_API Color {
|
|||||||
*/
|
*/
|
||||||
constexpr Color(const std::string_view& hex) { Hex(hex); }
|
constexpr Color(const std::string_view& hex) { Hex(hex); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for Hex Input (is abel to run at compile time xD)
|
||||||
|
* @param hex Hex String in `#ffffff` or `#ffffffff` format
|
||||||
|
*/
|
||||||
|
constexpr Color(const char* hex) { Hex(std::string_view{hex}); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Color Object by Hex String (at compile time btw)
|
* 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
|
||||||
@@ -115,6 +121,20 @@ class PD_API Color {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lerp
|
||||||
|
* @param v Target color
|
||||||
|
* @param t interpolation factor
|
||||||
|
* @return Class Reference
|
||||||
|
*/
|
||||||
|
constexpr Color& Lerp(const Color& v, float t) {
|
||||||
|
a = static_cast<u8>(a + (v.a - a) * t);
|
||||||
|
b = static_cast<u8>(b + (v.b - b) * t);
|
||||||
|
g = static_cast<u8>(g + (v.g - g) * t);
|
||||||
|
r = static_cast<u8>(r + (v.r - r) * t);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get 32Bit Color Value
|
* Get 32Bit Color Value
|
||||||
* @return 32Bit Color Value (ABGR iirc)
|
* @return 32Bit Color Value (ABGR iirc)
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <pd/common.hpp>
|
#include <pd/common.hpp>
|
||||||
namespace PD {
|
namespace PD {
|
||||||
|
// lets take use of c++ 20 concepts
|
||||||
|
// https://en.cppreference.com/w/cpp/language/constraints.html
|
||||||
|
template <typename T>
|
||||||
|
concept Resettable = requires(T& v) { v.Reset(); };
|
||||||
|
|
||||||
template <typename T, typename Alloc = std::allocator<T>>
|
template <typename T, typename Alloc = std::allocator<T>>
|
||||||
class Pool {
|
class Pool {
|
||||||
public:
|
public:
|
||||||
@@ -13,6 +18,9 @@ class Pool {
|
|||||||
Pool() = default;
|
Pool() = default;
|
||||||
~Pool() {
|
~Pool() {
|
||||||
if (pData) {
|
if (pData) {
|
||||||
|
for (size_t i = 0; i < pCap; i++) {
|
||||||
|
std::allocator_traits<Alloc>::destroy(pAlloc, &pData[i]);
|
||||||
|
}
|
||||||
pAlloc.deallocate(pData, pCap);
|
pAlloc.deallocate(pData, pCap);
|
||||||
pData = nullptr;
|
pData = nullptr;
|
||||||
}
|
}
|
||||||
@@ -47,6 +55,11 @@ class Pool {
|
|||||||
*e = elem;
|
*e = elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Put(size_t idx, const T& elem) {
|
||||||
|
if (idx >= pCap) ExpandIf(idx);
|
||||||
|
pData[idx] = elem;
|
||||||
|
}
|
||||||
|
|
||||||
void ExpandIf(size_t req) {
|
void ExpandIf(size_t req) {
|
||||||
if ((pPos + req) <= pCap) return;
|
if ((pPos + req) <= pCap) return;
|
||||||
size_t ncap = std::max(pCap * 2, pPos + req);
|
size_t ncap = std::max(pCap * 2, pPos + req);
|
||||||
@@ -56,6 +69,9 @@ class Pool {
|
|||||||
std::allocator_traits<Alloc>::construct(
|
std::allocator_traits<Alloc>::construct(
|
||||||
pAlloc, &nu[i], std::move_if_noexcept(pData[i]));
|
pAlloc, &nu[i], std::move_if_noexcept(pData[i]));
|
||||||
}
|
}
|
||||||
|
for (size_t i = 0; i < pCap; i++) {
|
||||||
|
std::allocator_traits<Alloc>::destroy(pAlloc, &pData[i]);
|
||||||
|
}
|
||||||
pAlloc.deallocate(pData, pCap);
|
pAlloc.deallocate(pData, pCap);
|
||||||
}
|
}
|
||||||
for (size_t i = pPos; i < ncap; i++) {
|
for (size_t i = pPos; i < ncap; i++) {
|
||||||
@@ -76,6 +92,49 @@ class Pool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetFast() {
|
||||||
|
if constexpr (Resettable<T>) {
|
||||||
|
for (size_t i = 0; i < pPos; i++) {
|
||||||
|
pData[i].Reset();
|
||||||
|
}
|
||||||
|
} else if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||||
|
PDWARN(
|
||||||
|
"ResetFast should only be executed with a non destructible type or a "
|
||||||
|
"class/struct that has a Reset func! {} is not "
|
||||||
|
"trivially_destructible and has no reset func.",
|
||||||
|
TypeName<T>());
|
||||||
|
}
|
||||||
|
pPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** THE ILLEGAL RESET FUNC */
|
||||||
|
void NoReset() { pPos = 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the data of another pool
|
||||||
|
*/
|
||||||
|
void AppendCopy(const Pool& v) {
|
||||||
|
if (!v.size()) return;
|
||||||
|
ExpandIf(v.size());
|
||||||
|
for (size_t i = 0; i < v.size(); i++) {
|
||||||
|
pData[pPos + i] = v.pData[i];
|
||||||
|
}
|
||||||
|
pPos += v.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the data of another pool
|
||||||
|
*/
|
||||||
|
void AppendMove(Pool& v) {
|
||||||
|
if (!v.size()) return;
|
||||||
|
ExpandIf(v.size());
|
||||||
|
for (size_t i = 0; i < v.size(); i++) {
|
||||||
|
pData[pPos + i] = std::move(v.pData[i]);
|
||||||
|
}
|
||||||
|
pPos += v.size();
|
||||||
|
v.ResetFast();
|
||||||
|
}
|
||||||
|
|
||||||
size_t size() const { return pPos; }
|
size_t size() const { return pPos; }
|
||||||
size_t capacity() const { return pCap; }
|
size_t capacity() const { return pCap; }
|
||||||
T& at(size_t idx) { return pData[idx]; }
|
T& at(size_t idx) { return pData[idx]; }
|
||||||
@@ -89,7 +148,16 @@ class Pool {
|
|||||||
const T& operator[](size_t idx) const { return at(idx); }
|
const T& operator[](size_t idx) const { return at(idx); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pool(size_t size) : pCap(size), pPos(0) { pData = pAlloc.allocate(size); }
|
Pool(size_t size) : pCap(size), pPos(0) {
|
||||||
|
pPos = 0;
|
||||||
|
pCap = size;
|
||||||
|
pData = pAlloc.allocate(size);
|
||||||
|
for (size_t i = 0; i < pCap; i++) {
|
||||||
|
std::allocator_traits<Alloc>::construct(pAlloc, &pData[i]);
|
||||||
|
}
|
||||||
|
PDLOG("Pool::Init({})", size);
|
||||||
|
}
|
||||||
|
|
||||||
size_t pCap = 0;
|
size_t pCap = 0;
|
||||||
size_t pPos = 0;
|
size_t pPos = 0;
|
||||||
Alloc pAlloc;
|
Alloc pAlloc;
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class U8Iterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PeekNext32(u32& ret) {
|
bool PeekNext32(u32& ret) {
|
||||||
// if ((ptr + 1) == 0 || *(ptr + 1) == 0) return false;
|
if (ptr == nullptr || *(ptr + 1) == 0) return false;
|
||||||
u8 c = *ptr;
|
u8 c = *ptr;
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
ret = c;
|
ret = c;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <pd/common.hpp>
|
#include <pd/common.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -202,14 +203,15 @@ class Res {
|
|||||||
/** Trace ID */
|
/** Trace ID */
|
||||||
std::string id;
|
std::string id;
|
||||||
/** Start time */
|
/** Start time */
|
||||||
u64 start;
|
u64 start = 0;
|
||||||
/** End Time */
|
/** End Time */
|
||||||
u64 end;
|
u64 end = 0;
|
||||||
/** Last Diff */
|
/** Last Diff */
|
||||||
u64 diff;
|
u64 diff = 0;
|
||||||
/** Protocol */
|
/** Protocol */
|
||||||
TimeStats protocol;
|
TimeStats protocol;
|
||||||
};
|
};
|
||||||
|
using TraceMap = std::map<std::string, TT::Res>;
|
||||||
/**
|
/**
|
||||||
* Begin a Trace
|
* Begin a Trace
|
||||||
* @param id Name of the Trace
|
* @param id Name of the Trace
|
||||||
@@ -220,6 +222,9 @@ PD_API void Beg(const std::string& id);
|
|||||||
* @param id Name of the Trace
|
* @param id Name of the Trace
|
||||||
*/
|
*/
|
||||||
PD_API void End(const std::string& id);
|
PD_API void End(const std::string& id);
|
||||||
|
PD_API TraceMap& GetTraceMap();
|
||||||
|
PD_API TT::Res& GetTraceRef(const std::string& id);
|
||||||
|
PD_API bool TraceExist(const std::string& id);
|
||||||
/**
|
/**
|
||||||
* Collect Start end end of the trace by tracking
|
* Collect Start end end of the trace by tracking
|
||||||
* when the Scope object goes out of scope
|
* when the Scope object goes out of scope
|
||||||
|
|||||||
+23
-23
@@ -23,7 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This file is generated by lazyvec 2.0.0
|
// This file is generated by lazyvec 2.1.0
|
||||||
|
|
||||||
#include <pd/common.hpp>
|
#include <pd/common.hpp>
|
||||||
|
|
||||||
@@ -54,117 +54,117 @@ class vec2 {
|
|||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator+=(T1 v) {
|
constexpr vec2<T>& operator+=(T1 v) {
|
||||||
x += (T)v;
|
x += (T)v;
|
||||||
y += (T)v;
|
y += (T)v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator+=(const vec2<T1>& v) {
|
constexpr vec2<T>& operator+=(const vec2<T1>& v) {
|
||||||
x += (T)v.x;
|
x += (T)v.x;
|
||||||
y += (T)v.y;
|
y += (T)v.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator+(T1 v) const {
|
constexpr vec2<T> operator+(T1 v) const {
|
||||||
return vec2<T>(x + (T)v, y + (T)v);
|
return vec2<T>(x + (T)v, y + (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator+(const vec2<T1>& v) const {
|
constexpr vec2<T> operator+(const vec2<T1>& v) const {
|
||||||
return vec2<T>(x + (T)v.x, y + (T)v.y);
|
return vec2<T>(x + (T)v.x, y + (T)v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator-=(T1 v) {
|
constexpr vec2<T>& operator-=(T1 v) {
|
||||||
x -= (T)v;
|
x -= (T)v;
|
||||||
y -= (T)v;
|
y -= (T)v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator-=(const vec2<T1>& v) {
|
constexpr vec2<T>& operator-=(const vec2<T1>& v) {
|
||||||
x -= (T)v.x;
|
x -= (T)v.x;
|
||||||
y -= (T)v.y;
|
y -= (T)v.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator-(T1 v) const {
|
constexpr vec2<T> operator-(T1 v) const {
|
||||||
return vec2<T>(x - (T)v, y - (T)v);
|
return vec2<T>(x - (T)v, y - (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator-(const vec2<T1>& v) const {
|
constexpr vec2<T> operator-(const vec2<T1>& v) const {
|
||||||
return vec2<T>(x - (T)v.x, y - (T)v.y);
|
return vec2<T>(x - (T)v.x, y - (T)v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator*=(T1 v) {
|
constexpr vec2<T>& operator*=(T1 v) {
|
||||||
x *= (T)v;
|
x *= (T)v;
|
||||||
y *= (T)v;
|
y *= (T)v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator*=(const vec2<T1>& v) {
|
constexpr vec2<T>& operator*=(const vec2<T1>& v) {
|
||||||
x *= (T)v.x;
|
x *= (T)v.x;
|
||||||
y *= (T)v.y;
|
y *= (T)v.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator*(T1 v) const {
|
constexpr vec2<T> operator*(T1 v) const {
|
||||||
return vec2<T>(x * (T)v, y * (T)v);
|
return vec2<T>(x * (T)v, y * (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator*(const vec2<T1>& v) const {
|
constexpr vec2<T> operator*(const vec2<T1>& v) const {
|
||||||
return vec2<T>(x * (T)v.x, y * (T)v.y);
|
return vec2<T>(x * (T)v.x, y * (T)v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator/=(T1 v) {
|
constexpr vec2<T>& operator/=(T1 v) {
|
||||||
x /= (T)v;
|
x /= (T)v;
|
||||||
y /= (T)v;
|
y /= (T)v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T>& operator/=(const vec2<T1>& v) {
|
constexpr vec2<T>& operator/=(const vec2<T1>& v) {
|
||||||
x /= (T)v.x;
|
x /= (T)v.x;
|
||||||
y /= (T)v.y;
|
y /= (T)v.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator/(T1 v) const {
|
constexpr vec2<T> operator/(T1 v) const {
|
||||||
return vec2<T>(x / (T)v, y / (T)v);
|
return vec2<T>(x / (T)v, y / (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec2<T> operator/(const vec2<T1>& v) const {
|
constexpr vec2<T> operator/(const vec2<T1>& v) const {
|
||||||
return vec2<T>(x / (T)v.x, y / (T)v.y);
|
return vec2<T>(x / (T)v.x, y / (T)v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic Operations
|
// Generic Operations
|
||||||
|
|
||||||
vec2 operator-() const { return vec2(-x, -y); }
|
constexpr vec2 operator-() const { return vec2(-x, -y); }
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
bool operator==(const vec2<T1>& v) const {
|
constexpr bool operator==(const vec2<T1>& v) const {
|
||||||
return x == (T)v.x && y == (T)v.y;
|
return x == (T)v.x && y == (T)v.y;
|
||||||
}
|
}
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
bool operator!=(const vec2<T1>& v) const {
|
constexpr bool operator!=(const vec2<T1>& v) const {
|
||||||
return !(*this == v);
|
return !(*this == v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
double Len() const { return std::sqrt(SqLen()); }
|
double Len() const { return std::sqrt(SqLen()); }
|
||||||
double SqLen() const { return x * x + y * y; }
|
constexpr double SqLen() const { return x * x + y * y; }
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
double Distance(const vec2<T1>& v) const {
|
double Distance(const vec2<T1>& v) const {
|
||||||
@@ -180,12 +180,12 @@ class vec2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
T Dot(const vec2<T1>& v) const {
|
constexpr T Dot(const vec2<T1>& v) const {
|
||||||
return x * (T)v.x + y * (T)v.y;
|
return x * (T)v.x + y * (T)v.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap Functions
|
// Swap Functions
|
||||||
void SwapXY() {
|
constexpr void SwapXY() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = y;
|
x = y;
|
||||||
y = t;
|
y = t;
|
||||||
|
|||||||
+26
-26
@@ -23,7 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This file is generated by lazyvec 2.0.0
|
// This file is generated by lazyvec 2.1.0
|
||||||
|
|
||||||
#include <pd/common.hpp>
|
#include <pd/common.hpp>
|
||||||
// Extended includes (rename if you use other filenames/paths)
|
// Extended includes (rename if you use other filenames/paths)
|
||||||
@@ -69,7 +69,7 @@ class vec3 {
|
|||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator+=(T1 v) {
|
constexpr vec3<T>& operator+=(T1 v) {
|
||||||
x += (T)v;
|
x += (T)v;
|
||||||
y += (T)v;
|
y += (T)v;
|
||||||
z += (T)v;
|
z += (T)v;
|
||||||
@@ -77,7 +77,7 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator+=(const vec3<T1>& v) {
|
constexpr vec3<T>& operator+=(const vec3<T1>& v) {
|
||||||
x += (T)v.x;
|
x += (T)v.x;
|
||||||
y += (T)v.y;
|
y += (T)v.y;
|
||||||
z += (T)v.z;
|
z += (T)v.z;
|
||||||
@@ -85,17 +85,17 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator+(T1 v) const {
|
constexpr vec3<T> operator+(T1 v) const {
|
||||||
return vec3<T>(x + (T)v, y + (T)v, z + (T)v);
|
return vec3<T>(x + (T)v, y + (T)v, z + (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator+(const vec3<T1>& v) const {
|
constexpr vec3<T> operator+(const vec3<T1>& v) const {
|
||||||
return vec3<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z);
|
return vec3<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator-=(T1 v) {
|
constexpr vec3<T>& operator-=(T1 v) {
|
||||||
x -= (T)v;
|
x -= (T)v;
|
||||||
y -= (T)v;
|
y -= (T)v;
|
||||||
z -= (T)v;
|
z -= (T)v;
|
||||||
@@ -103,7 +103,7 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator-=(const vec3<T1>& v) {
|
constexpr vec3<T>& operator-=(const vec3<T1>& v) {
|
||||||
x -= (T)v.x;
|
x -= (T)v.x;
|
||||||
y -= (T)v.y;
|
y -= (T)v.y;
|
||||||
z -= (T)v.z;
|
z -= (T)v.z;
|
||||||
@@ -111,17 +111,17 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator-(T1 v) const {
|
constexpr vec3<T> operator-(T1 v) const {
|
||||||
return vec3<T>(x - (T)v, y - (T)v, z - (T)v);
|
return vec3<T>(x - (T)v, y - (T)v, z - (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator-(const vec3<T1>& v) const {
|
constexpr vec3<T> operator-(const vec3<T1>& v) const {
|
||||||
return vec3<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z);
|
return vec3<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator*=(T1 v) {
|
constexpr vec3<T>& operator*=(T1 v) {
|
||||||
x *= (T)v;
|
x *= (T)v;
|
||||||
y *= (T)v;
|
y *= (T)v;
|
||||||
z *= (T)v;
|
z *= (T)v;
|
||||||
@@ -129,7 +129,7 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator*=(const vec3<T1>& v) {
|
constexpr vec3<T>& operator*=(const vec3<T1>& v) {
|
||||||
x *= (T)v.x;
|
x *= (T)v.x;
|
||||||
y *= (T)v.y;
|
y *= (T)v.y;
|
||||||
z *= (T)v.z;
|
z *= (T)v.z;
|
||||||
@@ -137,17 +137,17 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator*(T1 v) const {
|
constexpr vec3<T> operator*(T1 v) const {
|
||||||
return vec3<T>(x * (T)v, y * (T)v, z * (T)v);
|
return vec3<T>(x * (T)v, y * (T)v, z * (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator*(const vec3<T1>& v) const {
|
constexpr vec3<T> operator*(const vec3<T1>& v) const {
|
||||||
return vec3<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z);
|
return vec3<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator/=(T1 v) {
|
constexpr vec3<T>& operator/=(T1 v) {
|
||||||
x /= (T)v;
|
x /= (T)v;
|
||||||
y /= (T)v;
|
y /= (T)v;
|
||||||
z /= (T)v;
|
z /= (T)v;
|
||||||
@@ -155,7 +155,7 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T>& operator/=(const vec3<T1>& v) {
|
constexpr vec3<T>& operator/=(const vec3<T1>& v) {
|
||||||
x /= (T)v.x;
|
x /= (T)v.x;
|
||||||
y /= (T)v.y;
|
y /= (T)v.y;
|
||||||
z /= (T)v.z;
|
z /= (T)v.z;
|
||||||
@@ -163,31 +163,31 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator/(T1 v) const {
|
constexpr vec3<T> operator/(T1 v) const {
|
||||||
return vec3<T>(x / (T)v, y / (T)v, z / (T)v);
|
return vec3<T>(x / (T)v, y / (T)v, z / (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> operator/(const vec3<T1>& v) const {
|
constexpr vec3<T> operator/(const vec3<T1>& v) const {
|
||||||
return vec3<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z);
|
return vec3<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic Operations
|
// Generic Operations
|
||||||
|
|
||||||
vec3 operator-() const { return vec3(-x, -y, -z); }
|
constexpr vec3 operator-() const { return vec3(-x, -y, -z); }
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
bool operator==(const vec3<T1>& v) const {
|
constexpr bool operator==(const vec3<T1>& v) const {
|
||||||
return x == (T)v.x && y == (T)v.y && z == (T)v.z;
|
return x == (T)v.x && y == (T)v.y && z == (T)v.z;
|
||||||
}
|
}
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
bool operator!=(const vec3<T1>& v) const {
|
constexpr bool operator!=(const vec3<T1>& v) const {
|
||||||
return !(*this == v);
|
return !(*this == v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
double Len() const { return std::sqrt(SqLen()); }
|
double Len() const { return std::sqrt(SqLen()); }
|
||||||
double SqLen() const { return x * x + y * y + z * z; }
|
constexpr double SqLen() const { return x * x + y * y + z * z; }
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
double Distance(const vec3<T1>& v) const {
|
double Distance(const vec3<T1>& v) const {
|
||||||
@@ -203,27 +203,27 @@ class vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
T Dot(const vec3<T1>& v) const {
|
constexpr T Dot(const vec3<T1>& v) const {
|
||||||
return x * (T)v.x + y * (T)v.y + z * (T)v.z;
|
return x * (T)v.x + y * (T)v.y + z * (T)v.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec3<T> Cross(const vec3<T1>& v) const {
|
constexpr vec3<T> Cross(const vec3<T1>& v) const {
|
||||||
return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap Functions
|
// Swap Functions
|
||||||
void SwapXY() {
|
constexpr void SwapXY() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = y;
|
x = y;
|
||||||
y = t;
|
y = t;
|
||||||
}
|
}
|
||||||
void SwapXZ() {
|
constexpr void SwapXZ() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = z;
|
x = z;
|
||||||
z = t;
|
z = t;
|
||||||
}
|
}
|
||||||
void SwapYZ() {
|
constexpr void SwapYZ() {
|
||||||
T t = y;
|
T t = y;
|
||||||
y = z;
|
y = z;
|
||||||
z = t;
|
z = t;
|
||||||
|
|||||||
+28
-28
@@ -23,7 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This file is generated by lazyvec 2.0.0
|
// This file is generated by lazyvec 2.1.0
|
||||||
|
|
||||||
#include <pd/common.hpp>
|
#include <pd/common.hpp>
|
||||||
// Extended includes (rename if you use other filenames/paths)
|
// Extended includes (rename if you use other filenames/paths)
|
||||||
@@ -84,7 +84,7 @@ class vec4 {
|
|||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator+=(T1 v) {
|
constexpr vec4<T>& operator+=(T1 v) {
|
||||||
x += (T)v;
|
x += (T)v;
|
||||||
y += (T)v;
|
y += (T)v;
|
||||||
z += (T)v;
|
z += (T)v;
|
||||||
@@ -93,7 +93,7 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator+=(const vec4<T1>& v) {
|
constexpr vec4<T>& operator+=(const vec4<T1>& v) {
|
||||||
x += (T)v.x;
|
x += (T)v.x;
|
||||||
y += (T)v.y;
|
y += (T)v.y;
|
||||||
z += (T)v.z;
|
z += (T)v.z;
|
||||||
@@ -102,17 +102,17 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator+(T1 v) const {
|
constexpr vec4<T> operator+(T1 v) const {
|
||||||
return vec4<T>(x + (T)v, y + (T)v, z + (T)v, w + (T)v);
|
return vec4<T>(x + (T)v, y + (T)v, z + (T)v, w + (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator+(const vec4<T1>& v) const {
|
constexpr vec4<T> operator+(const vec4<T1>& v) const {
|
||||||
return vec4<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z, w + (T)v.w);
|
return vec4<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z, w + (T)v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator-=(T1 v) {
|
constexpr vec4<T>& operator-=(T1 v) {
|
||||||
x -= (T)v;
|
x -= (T)v;
|
||||||
y -= (T)v;
|
y -= (T)v;
|
||||||
z -= (T)v;
|
z -= (T)v;
|
||||||
@@ -121,7 +121,7 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator-=(const vec4<T1>& v) {
|
constexpr vec4<T>& operator-=(const vec4<T1>& v) {
|
||||||
x -= (T)v.x;
|
x -= (T)v.x;
|
||||||
y -= (T)v.y;
|
y -= (T)v.y;
|
||||||
z -= (T)v.z;
|
z -= (T)v.z;
|
||||||
@@ -130,17 +130,17 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator-(T1 v) const {
|
constexpr vec4<T> operator-(T1 v) const {
|
||||||
return vec4<T>(x - (T)v, y - (T)v, z - (T)v, w - (T)v);
|
return vec4<T>(x - (T)v, y - (T)v, z - (T)v, w - (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator-(const vec4<T1>& v) const {
|
constexpr vec4<T> operator-(const vec4<T1>& v) const {
|
||||||
return vec4<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z, w - (T)v.w);
|
return vec4<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z, w - (T)v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator*=(T1 v) {
|
constexpr vec4<T>& operator*=(T1 v) {
|
||||||
x *= (T)v;
|
x *= (T)v;
|
||||||
y *= (T)v;
|
y *= (T)v;
|
||||||
z *= (T)v;
|
z *= (T)v;
|
||||||
@@ -149,7 +149,7 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator*=(const vec4<T1>& v) {
|
constexpr vec4<T>& operator*=(const vec4<T1>& v) {
|
||||||
x *= (T)v.x;
|
x *= (T)v.x;
|
||||||
y *= (T)v.y;
|
y *= (T)v.y;
|
||||||
z *= (T)v.z;
|
z *= (T)v.z;
|
||||||
@@ -158,17 +158,17 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator*(T1 v) const {
|
constexpr vec4<T> operator*(T1 v) const {
|
||||||
return vec4<T>(x * (T)v, y * (T)v, z * (T)v, w * (T)v);
|
return vec4<T>(x * (T)v, y * (T)v, z * (T)v, w * (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator*(const vec4<T1>& v) const {
|
constexpr vec4<T> operator*(const vec4<T1>& v) const {
|
||||||
return vec4<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z, w * (T)v.w);
|
return vec4<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z, w * (T)v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator/=(T1 v) {
|
constexpr vec4<T>& operator/=(T1 v) {
|
||||||
x /= (T)v;
|
x /= (T)v;
|
||||||
y /= (T)v;
|
y /= (T)v;
|
||||||
z /= (T)v;
|
z /= (T)v;
|
||||||
@@ -177,7 +177,7 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T>& operator/=(const vec4<T1>& v) {
|
constexpr vec4<T>& operator/=(const vec4<T1>& v) {
|
||||||
x /= (T)v.x;
|
x /= (T)v.x;
|
||||||
y /= (T)v.y;
|
y /= (T)v.y;
|
||||||
z /= (T)v.z;
|
z /= (T)v.z;
|
||||||
@@ -186,31 +186,31 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator/(T1 v) const {
|
constexpr vec4<T> operator/(T1 v) const {
|
||||||
return vec4<T>(x / (T)v, y / (T)v, z / (T)v, w / (T)v);
|
return vec4<T>(x / (T)v, y / (T)v, z / (T)v, w / (T)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
vec4<T> operator/(const vec4<T1>& v) const {
|
constexpr vec4<T> operator/(const vec4<T1>& v) const {
|
||||||
return vec4<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z, w / (T)v.w);
|
return vec4<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z, w / (T)v.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic Operations
|
// Generic Operations
|
||||||
|
|
||||||
vec4 operator-() const { return vec4(-x, -y, -z, -w); }
|
constexpr vec4 operator-() const { return vec4(-x, -y, -z, -w); }
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
bool operator==(const vec4<T1>& v) const {
|
constexpr bool operator==(const vec4<T1>& v) const {
|
||||||
return x == (T)v.x && y == (T)v.y && z == (T)v.z && w == (T)v.w;
|
return x == (T)v.x && y == (T)v.y && z == (T)v.z && w == (T)v.w;
|
||||||
}
|
}
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
bool operator!=(const vec4<T1>& v) const {
|
constexpr bool operator!=(const vec4<T1>& v) const {
|
||||||
return !(*this == v);
|
return !(*this == v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
double Len() const { return std::sqrt(SqLen()); }
|
double Len() const { return std::sqrt(SqLen()); }
|
||||||
double SqLen() const { return x * x + y * y + z * z + w * w; }
|
constexpr double SqLen() const { return x * x + y * y + z * z + w * w; }
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
double Distance(const vec4<T1>& v) const {
|
double Distance(const vec4<T1>& v) const {
|
||||||
@@ -226,37 +226,37 @@ class vec4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
T Dot(const vec4<T1>& v) const {
|
constexpr T Dot(const vec4<T1>& v) const {
|
||||||
return x * (T)v.x + y * (T)v.y + z * (T)v.z + w * (T)v.w;
|
return x * (T)v.x + y * (T)v.y + z * (T)v.z + w * (T)v.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap Functions
|
// Swap Functions
|
||||||
void SwapXY() {
|
constexpr void SwapXY() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = y;
|
x = y;
|
||||||
y = t;
|
y = t;
|
||||||
}
|
}
|
||||||
void SwapXZ() {
|
constexpr void SwapXZ() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = z;
|
x = z;
|
||||||
z = t;
|
z = t;
|
||||||
}
|
}
|
||||||
void SwapXW() {
|
constexpr void SwapXW() {
|
||||||
T t = x;
|
T t = x;
|
||||||
x = w;
|
x = w;
|
||||||
w = t;
|
w = t;
|
||||||
}
|
}
|
||||||
void SwapYZ() {
|
constexpr void SwapYZ() {
|
||||||
T t = y;
|
T t = y;
|
||||||
y = z;
|
y = z;
|
||||||
z = t;
|
z = t;
|
||||||
}
|
}
|
||||||
void SwapYW() {
|
constexpr void SwapYW() {
|
||||||
T t = y;
|
T t = y;
|
||||||
y = w;
|
y = w;
|
||||||
w = t;
|
w = t;
|
||||||
}
|
}
|
||||||
void SwapZW() {
|
constexpr void SwapZW() {
|
||||||
T t = z;
|
T t = z;
|
||||||
z = w;
|
z = w;
|
||||||
w = t;
|
w = t;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <pd/drivers/gfx.hpp>
|
#include <pd/drivers/gfx.hpp>
|
||||||
|
#include <pd/drivers/hid.hpp>
|
||||||
#include <pd/drivers/os.hpp>
|
#include <pd/drivers/os.hpp>
|
||||||
|
|||||||
+172
-32
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
#include <pd/core/mat.hpp>
|
#include <pd/core/mat.hpp>
|
||||||
#include <pd/drivers/interface.hpp>
|
#include <pd/drivers/interface.hpp>
|
||||||
#include <pd/lithium/command.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
|
#include <pd/lithium/pools.hpp>
|
||||||
#include <pd/lithium/texture.hpp>
|
#include <pd/lithium/texture.hpp>
|
||||||
|
|
||||||
using PDBackendFlags = PD::u32;
|
using PDGfxBackendFlags = PD::u32;
|
||||||
enum PDBackendFlags_ {
|
enum PDGfxBackendFlags_ {
|
||||||
PDBackendFlags_None = 0,
|
PDGfxBackendFlags_None = 0,
|
||||||
PDBackendFlags_FlipUV_Y = 1 << 0, // Essential for font loading
|
PDGfxBackendFlags_FlipUV_Y = 1 << 0, // Essential for font loading
|
||||||
PDBackendFlags_WindingCW = 1 << 0, // Use CW instead of CCW winding
|
PDGfxBackendFlags_WindingCW = 1 << 0, // Use CW instead of CCW winding
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -37,15 +38,33 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
return Li::Texture();
|
return Li::Texture();
|
||||||
}
|
}
|
||||||
virtual void DeleteTexture(const Li::Texture& tex) {}
|
virtual void DeleteTexture(const Li::Texture& tex) {}
|
||||||
virtual void Draw(const Pool<Li::Command>& commands) {}
|
virtual void Draw(const Li::Drawlist& commands) {}
|
||||||
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
|
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
|
||||||
|
PDGfxBackendFlags GetFlags() { return Flags; }
|
||||||
|
|
||||||
|
size_t GetNumVertices() const { return CountVertices; }
|
||||||
|
size_t GetNumIndices() const { return CountIndices; }
|
||||||
|
size_t GetNumDrawcalls() const { return CountDrawcalls; }
|
||||||
|
size_t GetNumCommands() const { return CountCommands; }
|
||||||
|
|
||||||
|
// Global Pool Interface
|
||||||
|
virtual size_t AllocateVertices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual size_t AllocateIndices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual bool ExpandVertices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual bool ExpandIndices(size_t count, PD::ptr accessor) = 0;
|
||||||
|
virtual void PutVertex(size_t loc, const Li::Vertex& vtx,
|
||||||
|
PD::ptr accessor) = 0;
|
||||||
|
virtual void PutIndex(size_t loc, u16 idx, PD::ptr accessor) = 0;
|
||||||
|
virtual const Li::Vertex& GetVertex(size_t loc) const = 0;
|
||||||
|
virtual const u16& GetIndex(size_t loc) const = 0;
|
||||||
|
virtual void ResetPools() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void SysDeinit() {}
|
virtual void SysDeinit() {}
|
||||||
virtual void SysInit() {}
|
virtual void SysInit() {}
|
||||||
virtual void SysReset() {}
|
virtual void SysReset() {}
|
||||||
virtual void Submit(size_t count, size_t start) {}
|
virtual void Submit(size_t count, size_t start) {}
|
||||||
virtual void ResetPools() = 0;
|
virtual void UploadPools() {} // not every driver requires it
|
||||||
void RegisterTexture(const Li::Texture& tex);
|
void RegisterTexture(const Li::Texture& tex);
|
||||||
void UnregisterTexture(const Li::Texture& tex);
|
void UnregisterTexture(const Li::Texture& tex);
|
||||||
|
|
||||||
@@ -56,11 +75,16 @@ class PD_API GfxDriver : public DriverInterface {
|
|||||||
size_t CountIndices = 0;
|
size_t CountIndices = 0;
|
||||||
size_t CurrentIndex = 0;
|
size_t CurrentIndex = 0;
|
||||||
size_t CurrentVertex = 0;
|
size_t CurrentVertex = 0;
|
||||||
|
size_t pCountDrawcalls = 0;
|
||||||
|
size_t pCountCommands = 0;
|
||||||
|
// State Variables oder so
|
||||||
TextureID CurrentTex = 0;
|
TextureID CurrentTex = 0;
|
||||||
|
bool CurrentTexIsSDF = false;
|
||||||
Mat4 Projection;
|
Mat4 Projection;
|
||||||
ivec2 ViewPort;
|
ivec2 ViewPort;
|
||||||
std::unordered_map<TextureID, Li::Texture> pTextureRegestry;
|
std::unordered_map<TextureID, Li::Texture> pTextureRegestry;
|
||||||
Li::Texture pWhite;
|
Li::Texture pWhite;
|
||||||
|
PDGfxBackendFlags Flags = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DefaultGfxConfig {
|
struct DefaultGfxConfig {
|
||||||
@@ -87,50 +111,128 @@ class GfxDriverBase : public GfxDriver {
|
|||||||
pWhite = LoadTexture(img, 16, 16);
|
pWhite = LoadTexture(img, 16, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(const Pool<Li::Command>& commands) override {
|
void Draw(const Li::Drawlist& dl) override {
|
||||||
CountCommands += commands.size();
|
const auto& commands = dl.Data();
|
||||||
|
if (commands.size() == 0) return;
|
||||||
|
pCountCommands += commands.size();
|
||||||
|
|
||||||
|
size_t vtotal = dl.GetNumVertices();
|
||||||
|
size_t itotal = dl.GetNumIndices();
|
||||||
|
|
||||||
|
size_t start_vtx = pVtxPool.size();
|
||||||
|
pVtxPool.Allocate(vtotal);
|
||||||
|
CurrentVertex += vtotal;
|
||||||
|
|
||||||
|
size_t start_idx = pIdxPool.size();
|
||||||
|
pIdxPool.Allocate(itotal);
|
||||||
|
CurrentIndex += itotal;
|
||||||
|
|
||||||
|
size_t current_vtx = start_vtx;
|
||||||
|
size_t current_idx = start_idx;
|
||||||
|
|
||||||
|
const auto& vpool = Li::GetVertexPool();
|
||||||
|
const auto& ipool = Li::GetIndexPool();
|
||||||
|
/** Build Pools */
|
||||||
|
for (size_t i = 0; i < commands.size(); i++) {
|
||||||
|
const auto& cmd = commands[i];
|
||||||
|
if (cmd.VertexCount > 0) {
|
||||||
|
std::memcpy(pVtxPool.begin() + current_vtx,
|
||||||
|
vpool.begin() + cmd.FirstVertex,
|
||||||
|
cmd.VertexCount * sizeof(Li::Vertex));
|
||||||
|
}
|
||||||
|
for (size_t idx = 0; idx < cmd.IndexCount; idx++) {
|
||||||
|
u16 local_idx = ipool[cmd.FirstIndex + idx];
|
||||||
|
pIdxPool[current_idx + idx] = static_cast<u16>(current_vtx + local_idx);
|
||||||
|
}
|
||||||
|
current_vtx += cmd.VertexCount;
|
||||||
|
current_idx += cmd.IndexCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadPools();
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
size_t ioff = start_idx;
|
||||||
|
|
||||||
while (index < commands.size()) {
|
while (index < commands.size()) {
|
||||||
CurrentTex = commands[index].Tex;
|
CurrentTex = commands[index].Tex;
|
||||||
|
CurrentTexIsSDF = commands[index].SDF;
|
||||||
if (!CurrentTex) {
|
if (!CurrentTex) {
|
||||||
CurrentTex = pWhite.GetID();
|
CurrentTex = pWhite.GetID();
|
||||||
}
|
}
|
||||||
size_t startidx = CurrentIndex;
|
size_t num_indices = 0;
|
||||||
while (index < commands.size() &&
|
while (index < commands.size() &&
|
||||||
|
CurrentTexIsSDF == commands[index].SDF &&
|
||||||
(CurrentTex == commands[index].Tex ||
|
(CurrentTex == commands[index].Tex ||
|
||||||
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0))) {
|
(CurrentTex == pWhite.GetID() && commands[index].Tex == 0))) {
|
||||||
const auto& c = commands[index];
|
num_indices += commands[index].IndexCount;
|
||||||
CountVertices += c.VertexCount;
|
|
||||||
CountIndices += c.IndexCount;
|
|
||||||
auto pIdx = pIdxPool.Allocate(c.IndexCount);
|
|
||||||
auto pVtx = pVtxPool.Allocate(c.VertexCount);
|
|
||||||
for (size_t i = 0; i < c.IndexCount; i++) {
|
|
||||||
pIdx[i] = CurrentVertex + c.FirstIndex[i];
|
|
||||||
}
|
|
||||||
CurrentIndex += c.IndexCount;
|
|
||||||
CurrentVertex += c.VertexCount;
|
|
||||||
for (size_t i = 0; i < c.VertexCount; i++) {
|
|
||||||
pVtx[i] = c.FirstVertex[i];
|
|
||||||
}
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
Submit(CurrentIndex - startidx, startidx);
|
if (num_indices > 0) {
|
||||||
|
Submit(num_indices, ioff);
|
||||||
|
ioff += num_indices;
|
||||||
|
pCountDrawcalls++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AllocateVertices(size_t count, PD::ptr accessor) override {
|
||||||
|
pVertexAccessor = accessor;
|
||||||
|
size_t loc = pVtxPool.size();
|
||||||
|
pVtxPool.Allocate(count);
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AllocateIndices(size_t count, PD::ptr accessor) override {
|
||||||
|
pIndexAccessor = accessor;
|
||||||
|
size_t loc = pIdxPool.size();
|
||||||
|
pIdxPool.Allocate(count);
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExpandVertices(size_t count, PD::ptr accessor) override {
|
||||||
|
if (pVertexAccessor != accessor) return false;
|
||||||
|
pVtxPool.Allocate(count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExpandIndices(size_t count, PD::ptr accessor) override {
|
||||||
|
if (pIndexAccessor != accessor) return false;
|
||||||
|
pIdxPool.Allocate(count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutVertex(size_t loc, const Li::Vertex& vtx, PD::ptr accessor) override {
|
||||||
|
if (pVertexAccessor != accessor) return;
|
||||||
|
pVtxPool.Put(loc, vtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutIndex(size_t loc, u16 idx, PD::ptr accessor) override {
|
||||||
|
if (pIndexAccessor != accessor) return;
|
||||||
|
pIdxPool.Put(loc, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Li::Vertex& GetVertex(size_t loc) const override {
|
||||||
|
return pVtxPool[loc];
|
||||||
|
}
|
||||||
|
|
||||||
|
const u16& GetIndex(size_t loc) const override { return pIdxPool[loc]; }
|
||||||
|
|
||||||
|
void ResetPools() override {
|
||||||
|
pVtxPool.NoReset();
|
||||||
|
pIdxPool.NoReset();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
u16* GetIndexBufPtr(size_t start) { return &pIdxPool[start]; }
|
u16* GetIndexBufPtr(size_t start) { return &pIdxPool[start]; }
|
||||||
Li::Vertex* GetVertexBufPtr(size_t start) { return &pVtxPool[start]; }
|
Li::Vertex* GetVertexBufPtr(size_t start) { return &pVtxPool[start]; }
|
||||||
size_t GetVertexPoolSize() const { return pVtxPool.size(); }
|
size_t GetVertexPoolSize() const { return pVtxPool.size(); }
|
||||||
size_t GetIndexPoolSize() const { return pIdxPool.size(); }
|
size_t GetIndexPoolSize() const { return pIdxPool.size(); }
|
||||||
void ResetPools() override {
|
|
||||||
pVtxPool.Reset();
|
|
||||||
pIdxPool.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VtxPool pVtxPool;
|
VtxPool pVtxPool;
|
||||||
IdxPool pIdxPool;
|
IdxPool pIdxPool;
|
||||||
|
PD::ptr pVertexAccessor = 0;
|
||||||
|
PD::ptr pIndexAccessor = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PD_API Gfx {
|
class PD_API Gfx {
|
||||||
@@ -149,9 +251,7 @@ class PD_API Gfx {
|
|||||||
static void SetViewPort(const ivec2& vp) { driver->SetViewPort(vp); }
|
static void SetViewPort(const ivec2& vp) { driver->SetViewPort(vp); }
|
||||||
static void SetViewPort(int w, int h) { driver->SetViewPort(w, h); }
|
static void SetViewPort(int w, int h) { driver->SetViewPort(w, h); }
|
||||||
static void Reset() { driver->Reset(); }
|
static void Reset() { driver->Reset(); }
|
||||||
static void Draw(const Pool<Li::Command>& commands) {
|
static void Draw(const Li::Drawlist& dl) { driver->Draw(dl); }
|
||||||
driver->Draw(commands);
|
|
||||||
}
|
|
||||||
static Li::Texture LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
static Li::Texture LoadTexture(const std::vector<PD::u8>& pixels, int w,
|
||||||
int h,
|
int h,
|
||||||
TextureFormat type = TextureFormat::RGBA32,
|
TextureFormat type = TextureFormat::RGBA32,
|
||||||
@@ -165,8 +265,48 @@ class PD_API Gfx {
|
|||||||
return driver->GetWhiteTexture();
|
return driver->GetWhiteTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PDGfxBackendFlags GetFlags() { return driver->GetFlags(); }
|
||||||
|
|
||||||
static const char* GetDriverName() { return driver->GetName(); }
|
static const char* GetDriverName() { return driver->GetName(); }
|
||||||
|
|
||||||
|
static size_t GetNumVertices() { return driver->GetNumVertices(); }
|
||||||
|
static size_t GetNumIndices() { return driver->GetNumIndices(); }
|
||||||
|
static size_t GetNumDrawcalls() { return driver->GetNumDrawcalls(); }
|
||||||
|
static size_t GetNumCommands() { return driver->GetNumCommands(); }
|
||||||
|
|
||||||
|
// Gloabal Pool Interface
|
||||||
|
static size_t AllocateVertices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->AllocateVertices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t AllocateIndices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->AllocateIndices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ExpandVertices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->ExpandVertices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ExpandIndices(size_t count, PD::ptr accessor) {
|
||||||
|
return driver->ExpandIndices(count, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PutVertex(size_t loc, const Li::Vertex& vtx, PD::ptr accessor) {
|
||||||
|
driver->PutVertex(loc, vtx, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PutIndex(size_t loc, u16 idx, PD::ptr accessor) {
|
||||||
|
driver->PutIndex(loc, idx, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Li::Vertex& GetVertex(size_t loc) {
|
||||||
|
return driver->GetVertex(loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u16& GetIndex(size_t loc) { return driver->GetIndex(loc); }
|
||||||
|
|
||||||
|
static void NewFrame() { driver->ResetPools(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<GfxDriver> driver;
|
static std::unique_ptr<GfxDriver> driver;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/drivers/interface.hpp>
|
||||||
|
|
||||||
|
using PDHidBackendFlags = PD::u32;
|
||||||
|
enum PDHidBackendFlags_ {
|
||||||
|
PDHidBackendFlags_None = 0,
|
||||||
|
PDHidBackendFlags_HasTouch = 1 << 1,
|
||||||
|
PDHidBackendFlags_HasGamepad = 1 << 2,
|
||||||
|
PDHidBackendFlags_HasMouse = 1 << 3,
|
||||||
|
PDHidBackendFlags_HasKeyboard = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace HidInternal {
|
||||||
|
class Keyboard {
|
||||||
|
public:
|
||||||
|
Keyboard() = default;
|
||||||
|
virtual ~Keyboard() = default;
|
||||||
|
using Key = u128;
|
||||||
|
constexpr static Key No = 0;
|
||||||
|
constexpr static Key Escape = Key::Flag(0);
|
||||||
|
constexpr static Key Q = Key::Flag(1);
|
||||||
|
constexpr static Key W = Key::Flag(2);
|
||||||
|
constexpr static Key E = Key::Flag(3);
|
||||||
|
constexpr static Key R = Key::Flag(4);
|
||||||
|
constexpr static Key T = Key::Flag(5);
|
||||||
|
constexpr static Key Z = Key::Flag(6);
|
||||||
|
constexpr static Key U = Key::Flag(7);
|
||||||
|
constexpr static Key I = Key::Flag(8);
|
||||||
|
constexpr static Key O = Key::Flag(9);
|
||||||
|
constexpr static Key P = Key::Flag(10);
|
||||||
|
constexpr static Key A = Key::Flag(11);
|
||||||
|
constexpr static Key S = Key::Flag(12);
|
||||||
|
constexpr static Key D = Key::Flag(13);
|
||||||
|
constexpr static Key F = Key::Flag(14);
|
||||||
|
constexpr static Key G = Key::Flag(15);
|
||||||
|
constexpr static Key H = Key::Flag(16);
|
||||||
|
constexpr static Key J = Key::Flag(17);
|
||||||
|
constexpr static Key K = Key::Flag(18);
|
||||||
|
constexpr static Key L = Key::Flag(19);
|
||||||
|
constexpr static Key Y = Key::Flag(20);
|
||||||
|
constexpr static Key X = Key::Flag(21);
|
||||||
|
constexpr static Key C = Key::Flag(22);
|
||||||
|
constexpr static Key V = Key::Flag(23);
|
||||||
|
constexpr static Key B = Key::Flag(24);
|
||||||
|
constexpr static Key N = Key::Flag(25);
|
||||||
|
constexpr static Key M = Key::Flag(26);
|
||||||
|
constexpr static Key _1 = Key::Flag(27);
|
||||||
|
constexpr static Key _2 = Key::Flag(28);
|
||||||
|
constexpr static Key _3 = Key::Flag(29);
|
||||||
|
constexpr static Key _4 = Key::Flag(30);
|
||||||
|
constexpr static Key _5 = Key::Flag(31);
|
||||||
|
constexpr static Key _6 = Key::Flag(32);
|
||||||
|
constexpr static Key _7 = Key::Flag(33);
|
||||||
|
constexpr static Key _8 = Key::Flag(34);
|
||||||
|
constexpr static Key _9 = Key::Flag(35);
|
||||||
|
constexpr static Key _0 = Key::Flag(36);
|
||||||
|
constexpr static Key F1 = Key::Flag(37);
|
||||||
|
constexpr static Key F2 = Key::Flag(38);
|
||||||
|
constexpr static Key F3 = Key::Flag(39);
|
||||||
|
constexpr static Key F4 = Key::Flag(40);
|
||||||
|
constexpr static Key F5 = Key::Flag(41);
|
||||||
|
constexpr static Key F6 = Key::Flag(42);
|
||||||
|
constexpr static Key F7 = Key::Flag(43);
|
||||||
|
constexpr static Key F8 = Key::Flag(44);
|
||||||
|
constexpr static Key F9 = Key::Flag(45);
|
||||||
|
constexpr static Key F10 = Key::Flag(46);
|
||||||
|
constexpr static Key F11 = Key::Flag(47);
|
||||||
|
constexpr static Key F12 = Key::Flag(48);
|
||||||
|
constexpr static Key MouseLeft = Key::Flag(120);
|
||||||
|
};
|
||||||
|
|
||||||
|
using GamepadKey = u32;
|
||||||
|
enum Gamepad : GamepadKey {
|
||||||
|
None = 0, ///< No Key
|
||||||
|
A = 1 << 0, ///< A
|
||||||
|
B = 1 << 1, ///< B
|
||||||
|
X = 1 << 2, ///< X
|
||||||
|
Y = 1 << 3, ///< Y
|
||||||
|
Start = 1 << 4, ///< Start
|
||||||
|
Select = 1 << 5, ///< Select
|
||||||
|
L = 1 << 6, ///< L
|
||||||
|
R = 1 << 7, ///< R
|
||||||
|
DUp = 1 << 8, ///< Dpad Up
|
||||||
|
DDown = 1 << 9, ///< Dpad down
|
||||||
|
DLeft = 1 << 10, ///< Dpad left
|
||||||
|
DRight = 1 << 11, ///< Dpad right
|
||||||
|
CPUp = 1 << 12, ///< Cpad up
|
||||||
|
CPDown = 1 << 13, ///< cpad down
|
||||||
|
CPLeft = 1 << 14, ///< cpad left
|
||||||
|
CPRight = 1 << 15, ///< Cpad right
|
||||||
|
CSUp = 1 << 16, ///< Cstick up
|
||||||
|
CSDown = 1 << 17, ///< cstick down
|
||||||
|
CSLeft = 1 << 18, ///< cstick left
|
||||||
|
CSRight = 1 << 19, ///< cstick right
|
||||||
|
ZL = 1 << 20, ///< ZL
|
||||||
|
ZR = 1 << 21, ///< ZR
|
||||||
|
Touch = 1 << 22, ///< Touch
|
||||||
|
LStick = 1 << 23, ///< Left Stick
|
||||||
|
RStick = 1 << 24, ///< Right Stick
|
||||||
|
Up = DUp | CPUp, ///< DPad or CPad Up
|
||||||
|
Down = DDown | CPDown, ///< DPad or CPad Down
|
||||||
|
Left = DLeft | CPLeft, ///< DPad or CPad Left
|
||||||
|
Right = DRight | CPRight, ///< DPad or CPad Right
|
||||||
|
};
|
||||||
|
} // namespace HidInternal
|
||||||
|
// Pre interface class
|
||||||
|
class PD_API HidDriver : public DriverInterface {
|
||||||
|
public:
|
||||||
|
enum class Event {
|
||||||
|
Null, ///< Nothing happended
|
||||||
|
Down, ///< Key Pressed
|
||||||
|
Held, ///< Key held
|
||||||
|
Up, ///< Key released
|
||||||
|
};
|
||||||
|
HidDriver(std::string_view name = "HidNull");
|
||||||
|
virtual ~HidDriver();
|
||||||
|
|
||||||
|
virtual void Init() {}
|
||||||
|
virtual void Deinit() {}
|
||||||
|
virtual const fvec2& MousePos() const { return pMouse[0]; }
|
||||||
|
virtual const fvec2& MousePosLast() const { return pMouse[1]; }
|
||||||
|
virtual const fvec2& TouchPos() const { return pMouse[0]; }
|
||||||
|
virtual const fvec2& TouchPosLast() const { return pMouse[1]; }
|
||||||
|
virtual void Update();
|
||||||
|
virtual bool IsEvent(Event e, HidInternal::GamepadKey keys);
|
||||||
|
virtual bool IsEvent(Event e, HidInternal::Keyboard::Key keys);
|
||||||
|
virtual const fvec2& GetLeftStick() const { return pLStick[0]; }
|
||||||
|
virtual const fvec2& GetRightStick() const { return pRStick[0]; }
|
||||||
|
|
||||||
|
PDHidBackendFlags GetFlags() const { return pFlags; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SwapTab();
|
||||||
|
PDHidBackendFlags pFlags = PDHidBackendFlags_None;
|
||||||
|
fvec2 pMouse[2]; // Current And last pos
|
||||||
|
fvec2 pLStick[2];
|
||||||
|
fvec2 pRStick[2];
|
||||||
|
std::unordered_map<u32, u32> pGamepad;
|
||||||
|
std::unordered_map<u128, u128> pKeyboard;
|
||||||
|
std::unordered_map<Event, u32> pGamepadEvents[2];
|
||||||
|
std::unordered_map<Event, u128> pKeyboardEvents[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
class PD_API Hid {
|
||||||
|
public:
|
||||||
|
using Gamepad = HidInternal::Gamepad;
|
||||||
|
using Keyboard = HidInternal::Keyboard;
|
||||||
|
using Event = HidDriver::Event;
|
||||||
|
Hid() = default;
|
||||||
|
~Hid() = default;
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
static void UseDriver(Args&&... args) {
|
||||||
|
// assert(driver == nullptr && "OS Driver already set");
|
||||||
|
driver = std::make_unique<T>(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Init() { driver->Init(); }
|
||||||
|
static void Deinit() { driver->Deinit(); }
|
||||||
|
static const fvec2& MousePos() { return driver->MousePos(); }
|
||||||
|
static const fvec2& MousePosLast() { return driver->MousePosLast(); }
|
||||||
|
static const fvec2& TouchPos() { return driver->TouchPos(); }
|
||||||
|
static const fvec2& TouchPosLast() { return driver->TouchPosLast(); }
|
||||||
|
static void Update() { driver->Update(); }
|
||||||
|
static bool IsEvent(Event e, HidInternal::GamepadKey keys) {
|
||||||
|
return driver->IsEvent(e, keys);
|
||||||
|
}
|
||||||
|
static bool IsEvent(Event e, HidInternal::Keyboard::Key keys) {
|
||||||
|
return driver->IsEvent(e, keys);
|
||||||
|
}
|
||||||
|
static PDHidBackendFlags GetFlags() { return driver->GetFlags(); }
|
||||||
|
static const fvec2& GetLeftStick() { return driver->GetLeftStick(); }
|
||||||
|
static const fvec2& GetRightStick() { return driver->GetRightStick(); }
|
||||||
|
|
||||||
|
static const char* GetDriverName() { return driver->GetName(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::unique_ptr<HidDriver> driver;
|
||||||
|
};
|
||||||
|
} // namespace PD
|
||||||
@@ -26,6 +26,8 @@ class PD_API Os {
|
|||||||
static u64 GetTime() { return driver->GetTime(); }
|
static u64 GetTime() { return driver->GetTime(); }
|
||||||
static u64 GetTimeNano() { return driver->GetTimeNano(); }
|
static u64 GetTimeNano() { return driver->GetTimeNano(); }
|
||||||
|
|
||||||
|
static const char* GetDriverName() { return driver->GetName(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<OsDriver> driver;
|
static std::unique_ptr<OsDriver> driver;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/image/image.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
/**
|
||||||
|
* Namespace containing function to convert images
|
||||||
|
*/
|
||||||
|
namespace ImgConvert {
|
||||||
|
/**
|
||||||
|
* 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_API
|
||||||
|
void RGB24toRGBA32(std::vector<PD::u8>& out, const std::vector<u8>& in,
|
||||||
|
const int& w, const int& h);
|
||||||
|
PD_API
|
||||||
|
void RGB32toRGBA24(std::vector<u8>& out, const std::vector<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_API void Reverse32(std::vector<u8>& buf, const int& w, const int& h);
|
||||||
|
PD_API void ReverseBuf(std::vector<u8>& buf, size_t bpp, int w, int h);
|
||||||
|
} // namespace ImgConvert
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
class PD_API Image {
|
||||||
|
public:
|
||||||
|
enum class Format {
|
||||||
|
RGBA, // bpp == 4
|
||||||
|
RGB, // bpp == 3
|
||||||
|
RGB565, // bpp == 2 (not supported in laoding)
|
||||||
|
BGR, // bpp == 3
|
||||||
|
ABGR, // bpp == 4
|
||||||
|
BGRA, // bpp == 4
|
||||||
|
};
|
||||||
|
Image();
|
||||||
|
Image(const std::string& path);
|
||||||
|
Image(const std::vector<u8>& buf);
|
||||||
|
Image(const std::vector<u8>& pixels, int w, int h, int bpp = 4);
|
||||||
|
~Image();
|
||||||
|
|
||||||
|
void Load(const std::string& path);
|
||||||
|
void Load(const std::vector<u8>& buf);
|
||||||
|
void Load(const u8* buf, size_t size);
|
||||||
|
void Copy(const std::vector<u8>& pixels, int w, int h, int bpp = 4);
|
||||||
|
|
||||||
|
const int& Width() const { return pSize.x; }
|
||||||
|
const int& Height() const { return pSize.y; }
|
||||||
|
const ivec2& Size() const { return pSize; }
|
||||||
|
|
||||||
|
const std::vector<u8>& data() const { return pData; }
|
||||||
|
std::vector<u8>& data() { return pData; }
|
||||||
|
operator const std::vector<u8>&() const { return pData; }
|
||||||
|
operator std::vector<u8>&() { return pData; }
|
||||||
|
operator const ivec2&() const { return pSize; }
|
||||||
|
operator const Format&() const { return pFormat; }
|
||||||
|
|
||||||
|
void Flip(bool horizontal = true, bool vertical = true);
|
||||||
|
|
||||||
|
static int Format2Bpp(Format fmt);
|
||||||
|
static Format GuessFmtFromBpp(int bpp);
|
||||||
|
|
||||||
|
void Convert(Format dst);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<u8> pData;
|
||||||
|
ivec2 pSize;
|
||||||
|
Format pFormat = Format::RGBA;
|
||||||
|
};
|
||||||
|
} // namespace PD
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <pd/core/pool.hpp>
|
#include <pd/core/pool.hpp>
|
||||||
#include <pd/lithium/pools.hpp>
|
|
||||||
#include <pd/lithium/vertex.hpp>
|
#include <pd/lithium/vertex.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -12,45 +11,18 @@ class Command {
|
|||||||
Command() { Reset(); }
|
Command() { Reset(); }
|
||||||
~Command() {}
|
~Command() {}
|
||||||
|
|
||||||
void Reserve(size_t vtx, size_t idx) {
|
void Reserve(size_t vtx, size_t idx);
|
||||||
if (!FirstVertex)
|
void Reset();
|
||||||
FirstVertex = AllocateVertices(vtx);
|
|
||||||
else
|
|
||||||
AllocateVertices(vtx);
|
|
||||||
if (!FirstIndex)
|
|
||||||
FirstIndex = AllocateIndices(idx);
|
|
||||||
else
|
|
||||||
AllocateIndices(idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() {
|
Command& Add(const Vertex& vtx);
|
||||||
Layer = 0;
|
Command& Add(u16 idx);
|
||||||
Tex = 0;
|
Command& Add(u16 a, u16 b, u16 c);
|
||||||
FirstIndex = nullptr;
|
|
||||||
FirstVertex = nullptr;
|
|
||||||
IndexCount = 0;
|
|
||||||
VertexCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Command& Add(const Vertex& vtx) {
|
|
||||||
FirstVertex[VertexCount++] = vtx;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Command& Add(u16 idx) {
|
|
||||||
FirstIndex[IndexCount++] = VertexCount + idx;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Command& Add(u16 a, u16 b, u16 c) {
|
|
||||||
FirstIndex[IndexCount++] = VertexCount + a;
|
|
||||||
FirstIndex[IndexCount++] = VertexCount + b;
|
|
||||||
FirstIndex[IndexCount++] = VertexCount + c;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Layer = 0;
|
int Layer = 0;
|
||||||
ptr Tex = 0;
|
ptr Tex = 0;
|
||||||
Vertex* FirstVertex = nullptr;
|
bool SDF = false;
|
||||||
u16* FirstIndex = nullptr;
|
size_t FirstVertex = 0;
|
||||||
|
size_t FirstIndex = 0;
|
||||||
size_t VertexCount = 0;
|
size_t VertexCount = 0;
|
||||||
size_t IndexCount = 0;
|
size_t IndexCount = 0;
|
||||||
// Todo: implement
|
// Todo: implement
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <pd/lithium/command.hpp>
|
#include <pd/lithium/command.hpp>
|
||||||
|
#include <pd/lithium/font.hpp>
|
||||||
#include <pd/lithium/texture.hpp>
|
#include <pd/lithium/texture.hpp>
|
||||||
|
|
||||||
using LiPathRectFlags = PD::u32;
|
using LiPathRectFlags = PD::u32;
|
||||||
@@ -25,18 +26,7 @@ using LiDrawFlags = PD::u32;
|
|||||||
enum LiDrawFlags_ : PD::u32 {
|
enum LiDrawFlags_ : PD::u32 {
|
||||||
LiDrawFlags_None = 0,
|
LiDrawFlags_None = 0,
|
||||||
LiDrawFlags_Close = 1 << 0,
|
LiDrawFlags_Close = 1 << 0,
|
||||||
};
|
LiDrawFlags_AA = 1 << 1,
|
||||||
|
|
||||||
using LiTextFlags = PD::u32;
|
|
||||||
enum LiTextFlags_ : PD::u32 {
|
|
||||||
LiTextFlags_None = 0, ///< Do nothing
|
|
||||||
LiTextFlags_AlignRight = 1 << 0, ///< Align Right of position
|
|
||||||
LiTextFlags_AlignMid = 1 << 1, ///< Align in the middle of pos and box
|
|
||||||
LiTextFlags_Shaddow = 1 << 2, ///< Draws the text twice to create shaddow
|
|
||||||
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_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
|
|
||||||
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -52,9 +42,27 @@ class PD_API Drawlist {
|
|||||||
void Copy(Drawlist& other);
|
void Copy(Drawlist& other);
|
||||||
void Optimize();
|
void Optimize();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
void SetLayer(int layer) { pCurrentLayer = layer; }
|
||||||
|
void LayerUp() { pCurrentLayer++; }
|
||||||
|
void LayerDown() { pCurrentLayer--; }
|
||||||
|
int GetLayer() const { return pCurrentLayer; }
|
||||||
|
|
||||||
|
size_t GetNumVertices() const {
|
||||||
|
size_t count = 0;
|
||||||
|
for (const auto& cmd : pCommands) count += cmd.VertexCount;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetNumIndices() const {
|
||||||
|
size_t count = 0;
|
||||||
|
for (const auto& cmd : pCommands) count += cmd.IndexCount;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/** Command Allocation */
|
/** Command Allocation */
|
||||||
Command& NewCommand();
|
Command& NewCommand();
|
||||||
|
bool HasCommands() { return pCommands.size() > 0; }
|
||||||
|
Command& GetLastCommand() { return pCommands[pCommands.size() - 1]; }
|
||||||
|
|
||||||
/** Path API */
|
/** Path API */
|
||||||
void PathAdd(const fvec2& point) { pPath.Push(point); }
|
void PathAdd(const fvec2& point) { pPath.Push(point); }
|
||||||
@@ -66,8 +74,11 @@ class PD_API Drawlist {
|
|||||||
* only for special use cases
|
* only for special use cases
|
||||||
*/
|
*/
|
||||||
void PathReserve(size_t num) { pPath.ExpandIf(num); }
|
void PathReserve(size_t num) { pPath.ExpandIf(num); }
|
||||||
void PathStroke(u32 color, int t = 1, LiDrawFlags flags = LiDrawFlags_None);
|
void PathStroke(const PD::Color& color, int t = 1,
|
||||||
void PathFill(u32 color);
|
LiDrawFlags flags = LiDrawFlags_None);
|
||||||
|
void PathFill(const PD::Color& color);
|
||||||
|
void PathFillGradient(const PD::Color& a, const PD::Color& b,
|
||||||
|
float rad = 0.f);
|
||||||
void PathArcToN(const fvec2& c, float r, float amin, float amax, int s);
|
void PathArcToN(const fvec2& c, float r, float amin, float amax, int s);
|
||||||
void PathFastArcToN(const fvec2& c, float r, float amin, float amax, int s);
|
void PathFastArcToN(const fvec2& c, float r, float amin, float amax, int s);
|
||||||
void PathRect(const fvec2& tl, const fvec2& br, float r = 0.f);
|
void PathRect(const fvec2& tl, const fvec2& br, float r = 0.f);
|
||||||
@@ -78,39 +89,54 @@ class PD_API Drawlist {
|
|||||||
void BindTexture(const Texture& tex);
|
void BindTexture(const Texture& tex);
|
||||||
void UnbindTexture() { pCurrentTexture = Texture(); }
|
void UnbindTexture() { pCurrentTexture = Texture(); }
|
||||||
|
|
||||||
|
/** Font Handling */
|
||||||
|
void SetFont(Font* font) { pFont = font; }
|
||||||
|
void SetFontscale(float fontscale = 1.f) { pFontScale = fontscale; }
|
||||||
|
const float& GetFontScale() const { return pFontScale; }
|
||||||
|
|
||||||
/** Data geters */
|
/** Data geters */
|
||||||
const Pool<Command>& Data() const { return pCommands; }
|
const Pool<Command>& Data() const { return pCommands; }
|
||||||
operator const Pool<Command>&() const { return pCommands; }
|
operator const Pool<Command>&() const { return pCommands; }
|
||||||
|
|
||||||
/** Drawing functions */
|
/** Drawing functions */
|
||||||
void DrawRect(const fvec2& pos, const fvec2& size, u32 color, int t = 1);
|
void DrawRect(const fvec2& pos, const fvec2& size, const PD::Color& color,
|
||||||
void DrawRectFilled(const fvec2& pos, const fvec2& size, u32 color);
|
|
||||||
void DrawTriangle(const fvec2& a, const fvec2& b, const fvec2& c, u32 color,
|
|
||||||
int t = 1);
|
int t = 1);
|
||||||
|
void DrawRectFilled(const fvec2& pos, const fvec2& size,
|
||||||
|
const PD::Color& color);
|
||||||
|
void DrawTriangle(const fvec2& a, const fvec2& b, const fvec2& c,
|
||||||
|
const PD::Color& color, int t = 1);
|
||||||
void DrawTriangleFilled(const fvec2& a, const fvec2& b, const fvec2& c,
|
void DrawTriangleFilled(const fvec2& a, const fvec2& b, const fvec2& c,
|
||||||
u32 color);
|
const PD::Color& color);
|
||||||
void DrawCircle(const fvec2& center, float rad, u32 color, int num_segments,
|
void DrawCircle(const fvec2& center, float rad, const PD::Color& color,
|
||||||
int t = 1);
|
int num_segments, int t = 1);
|
||||||
void DrawCircleFilled(const fvec2& center, float rad, u32 color,
|
void DrawCircleFilled(const fvec2& center, float rad, const PD::Color& color,
|
||||||
int num_segments);
|
int num_segments);
|
||||||
void DrawText(const fvec2& p, const char* text, u32 color);
|
void DrawText(const fvec2& p, const char* text, const PD::Color& color);
|
||||||
void DrawTextEx(const fvec2& p, const char* text, u32 color,
|
void DrawTextEx(const fvec2& p, const char* text, const PD::Color& color,
|
||||||
LiTextFlags flags, const fvec2& box = fvec2(0.f));
|
LiTextFlags flags, const fvec2& box = fvec2(0.f));
|
||||||
|
void DrawLine(const fvec2& a, const fvec2& b, const PD::Color& color,
|
||||||
|
int thickness = 1);
|
||||||
|
|
||||||
void DrawPolyLine(const Pool<fvec2>& points, u32 color,
|
void DrawPolyLine(const Pool<fvec2>& points, const PD::Color& color,
|
||||||
LiDrawFlags flags = LiDrawFlags_None, int t = 1);
|
LiDrawFlags flags = LiDrawFlags_None, int t = 1);
|
||||||
void DrawConvexPolyFilled(const Pool<fvec2>& points, u32 color);
|
void DrawConvexPolyFilled(const Pool<fvec2>& points, const PD::Color& color);
|
||||||
|
void DrawConvexPolyFilled(const Pool<fvec2>& points, const PD::Color& a,
|
||||||
|
const PD::Color b, float rad = 0.f);
|
||||||
|
|
||||||
void PrimQuad(Command& cmd, const Rect& quad, const Rect& uv, u32 color);
|
void PrimQuad(Command& cmd, const Rect& quad, const Rect& uv,
|
||||||
|
const PD::Color& color);
|
||||||
void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
|
void PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
|
||||||
const fvec2& c, u32 color);
|
const fvec2& c, const PD::Color& color);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Texture pCurrentTexture;
|
Texture pCurrentTexture;
|
||||||
|
int pCurrentLayer = 0;
|
||||||
Pool<Command> pCommands;
|
Pool<Command> pCommands;
|
||||||
Pool<fvec2> pPath;
|
Pool<fvec2> pPath;
|
||||||
Pool<Vertex> pVertices;
|
Pool<Vertex> pVertices;
|
||||||
Pool<u16> pIndices;
|
Pool<u16> pIndices;
|
||||||
|
Font* pFont = nullptr;
|
||||||
|
float pFontScale = 1.f;
|
||||||
};
|
};
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/lithium/texture.hpp>
|
||||||
|
|
||||||
|
using LiTextFlags = PD::u32;
|
||||||
|
enum LiTextFlags_ : PD::u32 {
|
||||||
|
LiTextFlags_None = 0, ///< Do nothing
|
||||||
|
LiTextFlags_AlignRight = 1 << 0, ///< Align Right of position
|
||||||
|
LiTextFlags_AlignMid = 1 << 1, ///< Align in the middle of pos and box
|
||||||
|
LiTextFlags_Shaddow = 1 << 2, ///< Draws the text twice to create shaddow
|
||||||
|
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_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
|
||||||
|
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
|
||||||
|
};
|
||||||
|
|
||||||
|
using LiFontFlags = PD::u32;
|
||||||
|
enum LiFontFlags_ : PD::u32 {
|
||||||
|
LiFontFlags_None = 0, ///< Not special (bitmap font)
|
||||||
|
LiFontFlags_SDF = 1 << 0, ///< SDF Texture (and mode)
|
||||||
|
LiFontFlags_Monospace = 1 << 1, ///< Monospace Rendering
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Li {
|
||||||
|
class Drawlist;
|
||||||
|
class PD_API Font {
|
||||||
|
public:
|
||||||
|
struct Codepoint {
|
||||||
|
u32 pCodepoint = 0;
|
||||||
|
fvec4 SimpleUV;
|
||||||
|
size_t Tex = 0;
|
||||||
|
fvec2 Size;
|
||||||
|
fvec2 Offset;
|
||||||
|
// float Offset = 0.f;
|
||||||
|
float AdvanceX = 0.f;
|
||||||
|
bool pInvalid = false;
|
||||||
|
};
|
||||||
|
Font() {}
|
||||||
|
~Font() {}
|
||||||
|
|
||||||
|
bool IsMonospace() { return pFlags & LiFontFlags_Monospace; }
|
||||||
|
bool IsSDF() { return pFlags & LiFontFlags_SDF; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a TTF File
|
||||||
|
* @param path Path to the TTF file
|
||||||
|
* @param px_height Pixelheight of the codepoints (limit by 64)
|
||||||
|
*/
|
||||||
|
void LoadTTF(const std::string& path, int px_height = 32,
|
||||||
|
LiFontFlags flags = LiFontFlags_None);
|
||||||
|
/**
|
||||||
|
* Load a TTF File from Memory
|
||||||
|
* @param data File data
|
||||||
|
* @param px_height Pixelheight of the codepoints (limit by 64)
|
||||||
|
*/
|
||||||
|
void LoadTTF(const std::vector<u8>& data, int px_height = 32,
|
||||||
|
LiFontFlags flags = LiFontFlags_None);
|
||||||
|
/**
|
||||||
|
* Function that loads a default integrated font...
|
||||||
|
* This will only work if PD_LI_INCLUDE_FONTS was set
|
||||||
|
* on lithium build cause otherwise the font data is not included
|
||||||
|
*/
|
||||||
|
void LoadDefaultFont(int id = 0, int pixel_height = 32);
|
||||||
|
/**
|
||||||
|
* Getter for Codepoint reference
|
||||||
|
* @return codepoint dataholder reference
|
||||||
|
*/
|
||||||
|
Codepoint& GetCodepoint(u32 c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Text Bounding Box
|
||||||
|
*/
|
||||||
|
fvec2 GetTextBounds(const char* text, float scale);
|
||||||
|
/**
|
||||||
|
* Extended Draw Text Function that vreates a Command List
|
||||||
|
*/
|
||||||
|
void CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color, float scale,
|
||||||
|
const char* text, LiTextFlags flags = 0, const fvec2& box = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup Font and unload Textures
|
||||||
|
*/
|
||||||
|
void Delete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Garbage collection for TextMapSystem
|
||||||
|
*/
|
||||||
|
void CleanupTMS();
|
||||||
|
/**
|
||||||
|
* Utility function to create a font atlas
|
||||||
|
* During TTF loading (Internal and should not be called)
|
||||||
|
*/
|
||||||
|
void BakeAndPush(bool final, std::vector<u8>& font_tex, int texszs);
|
||||||
|
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 */
|
||||||
|
int PixelHeight = 0;
|
||||||
|
int DefaultPixelHeight = 32;
|
||||||
|
std::vector<TextureID> Textures;
|
||||||
|
/**
|
||||||
|
* 32Bit Codepoint Dataholder reference map
|
||||||
|
* **Now using unordered map**
|
||||||
|
*/
|
||||||
|
std::unordered_map<u32, Codepoint> CodeMap;
|
||||||
|
/** need some performance tweaks */
|
||||||
|
std::array<Codepoint, 128> pAsciiCache;
|
||||||
|
/** TMS */
|
||||||
|
struct TMELEM {
|
||||||
|
PD::u32 ID;
|
||||||
|
PD::fvec2 Size;
|
||||||
|
std::string Text;
|
||||||
|
u64 TimeStamp;
|
||||||
|
};
|
||||||
|
std::unordered_map<u32, TMELEM> pTMS;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t pCurrentTex = 0;
|
||||||
|
LiFontFlags pFlags = 0;
|
||||||
|
};
|
||||||
|
} // namespace Li
|
||||||
|
} // namespace PD
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <pd/lithium/atlas.hpp>
|
#include <pd/lithium/atlas.hpp>
|
||||||
|
#include <pd/lithium/command.hpp>
|
||||||
#include <pd/lithium/rect.hpp>
|
#include <pd/lithium/rect.hpp>
|
||||||
#include <pd/lithium/texture.hpp>
|
#include <pd/lithium/texture.hpp>
|
||||||
#include <pd/lithium/vertex.hpp>
|
#include <pd/lithium/vertex.hpp>
|
||||||
@@ -107,3 +108,15 @@ struct std::formatter<PD::Li::AtlasState> : std::formatter<std::string> {
|
|||||||
return std::format_to(ctx.out(), "{}", ret);
|
return std::format_to(ctx.out(), "{}", ret);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct std::formatter<PD::Li::Command> : std::formatter<std::string> {
|
||||||
|
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const PD::Li::Command& value, FormatContext& ctx) const {
|
||||||
|
return std::format_to(ctx.out(), "[0x{:X}, 0x{:X}] [{}, {}] 0x{:X}",
|
||||||
|
(PD::ptr)value.FirstVertex, (PD::ptr)value.FirstIndex,
|
||||||
|
value.VertexCount, value.IndexCount, value.Tex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <pd/lithium/command.hpp>
|
#include <pd/lithium/command.hpp>
|
||||||
#include <pd/lithium/drawlist.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
|
#include <pd/lithium/font.hpp>
|
||||||
#include <pd/lithium/math.hpp>
|
#include <pd/lithium/math.hpp>
|
||||||
#include <pd/lithium/pools.hpp>
|
#include <pd/lithium/pools.hpp>
|
||||||
#include <pd/lithium/vertex.hpp>
|
#include <pd/lithium/vertex.hpp>
|
||||||
@@ -10,6 +10,7 @@ PD_API bool InBounds(const fvec2& pos, const fvec2& size, const fvec4& rect);
|
|||||||
PD_API bool InBounds(const fvec2& pos, const fvec4& rect);
|
PD_API bool InBounds(const fvec2& pos, const fvec4& rect);
|
||||||
PD_API bool InBounds(const fvec2& a, const fvec2& b, const fvec2& c,
|
PD_API bool InBounds(const fvec2& a, const fvec2& b, const fvec2& c,
|
||||||
const fvec4& rect);
|
const fvec4& rect);
|
||||||
|
PD_API bool InSpace(const PD::fvec2& pos, const Rect& rect);
|
||||||
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus);
|
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus);
|
||||||
PD_API Rect PrimRect(const fvec2& pos, const fvec2& size, float angle = 0.f);
|
PD_API Rect PrimRect(const fvec2& pos, const fvec2& size, float angle = 0.f);
|
||||||
PD_API Rect PrimLine(const fvec2& a, const fvec2& b, int t = 1);
|
PD_API Rect PrimLine(const fvec2& a, const fvec2& b, int t = 1);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <pd/core/core.hpp>
|
||||||
#include <pd/lithium/vertex.hpp>
|
#include <pd/lithium/vertex.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
namespace Li {
|
||||||
PD_API Vertex* AllocateVertices(size_t count);
|
PD_API PD::Pool<Vertex>& GetVertexPool();
|
||||||
PD_API u16* AllocateIndices(size_t count);
|
PD_API PD::Pool<u16>& GetIndexPool();
|
||||||
PD_API void ResetPools();
|
PD_API void ResetPools();
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
+17
-14
@@ -29,14 +29,14 @@ namespace PD {
|
|||||||
namespace Li {
|
namespace Li {
|
||||||
class Rect {
|
class Rect {
|
||||||
public:
|
public:
|
||||||
Rect() : Top(0), Bot(0) {}
|
constexpr Rect() : Top(0), Bot(0) {}
|
||||||
~Rect() = default;
|
~Rect() = default;
|
||||||
/**
|
/**
|
||||||
* Constructor that initializes the rectangle using top and bottom positions.
|
* Constructor that initializes the rectangle using top and bottom positions.
|
||||||
* @param t Top left and right corner positions.
|
* @param t Top left and right corner positions.
|
||||||
* @param b Bottom left and right corner positions.
|
* @param b Bottom left and right corner positions.
|
||||||
*/
|
*/
|
||||||
Rect(const fvec4& t, const fvec4& b) {
|
constexpr Rect(const fvec4& t, const fvec4& b) {
|
||||||
Top = t;
|
Top = t;
|
||||||
Bot = b;
|
Bot = b;
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,8 @@ class Rect {
|
|||||||
* @param bl Bottom left corner position.
|
* @param bl Bottom left corner position.
|
||||||
* @param br Bottom right corner position.
|
* @param br Bottom right corner position.
|
||||||
*/
|
*/
|
||||||
Rect(const fvec2& tl, const fvec2& tr, const fvec2& bl, const fvec2& br) {
|
constexpr Rect(const fvec2& tl, const fvec2& tr, const fvec2& bl,
|
||||||
|
const fvec2& br) {
|
||||||
Top = fvec4(tl, tr);
|
Top = fvec4(tl, tr);
|
||||||
Bot = fvec4(bl, br);
|
Bot = fvec4(bl, br);
|
||||||
}
|
}
|
||||||
@@ -61,7 +62,7 @@ class Rect {
|
|||||||
*
|
*
|
||||||
* @param uv Vec4 UV map.
|
* @param uv Vec4 UV map.
|
||||||
*/
|
*/
|
||||||
Rect(const fvec4& uv) {
|
constexpr Rect(const fvec4& uv) {
|
||||||
Top = vec4(uv.x, uv.y, uv.z, uv.y);
|
Top = vec4(uv.x, uv.y, uv.z, uv.y);
|
||||||
Bot = vec4(uv.x, uv.w, uv.z, uv.w);
|
Bot = vec4(uv.x, uv.w, uv.z, uv.w);
|
||||||
}
|
}
|
||||||
@@ -70,29 +71,29 @@ class Rect {
|
|||||||
* Get the top-left corner position.
|
* Get the top-left corner position.
|
||||||
* @return Top-left position as vec2.
|
* @return Top-left position as vec2.
|
||||||
*/
|
*/
|
||||||
fvec2 TopLeft() const { return fvec2(Top.x, Top.y); }
|
constexpr fvec2 TopLeft() const { return fvec2(Top.x, Top.y); }
|
||||||
/**
|
/**
|
||||||
* Get the top-right corner position.
|
* Get the top-right corner position.
|
||||||
* @return Top-right position as vec2.
|
* @return Top-right position as vec2.
|
||||||
*/
|
*/
|
||||||
fvec2 TopRight() const { return fvec2(Top.z, Top.w); }
|
constexpr fvec2 TopRight() const { return fvec2(Top.z, Top.w); }
|
||||||
/**
|
/**
|
||||||
* Get the bottom-left corner position.
|
* Get the bottom-left corner position.
|
||||||
* @return Bottom-left position as vec2.
|
* @return Bottom-left position as vec2.
|
||||||
*/
|
*/
|
||||||
fvec2 BotLeft() const { return fvec2(Bot.x, Bot.y); }
|
constexpr fvec2 BotLeft() const { return fvec2(Bot.x, Bot.y); }
|
||||||
/**
|
/**
|
||||||
* Get the bottom-right corner position.
|
* Get the bottom-right corner position.
|
||||||
* @return Bottom-right position as vec2.
|
* @return Bottom-right position as vec2.
|
||||||
*/
|
*/
|
||||||
fvec2 BotRight() const { return fvec2(Bot.z, Bot.w); }
|
constexpr fvec2 BotRight() const { return fvec2(Bot.z, Bot.w); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the top-left corner position.
|
* Set the top-left corner position.
|
||||||
* @param v New top-left position.
|
* @param v New top-left position.
|
||||||
* @return Reference to the updated Rect.
|
* @return Reference to the updated Rect.
|
||||||
*/
|
*/
|
||||||
Rect& TopLeft(const fvec2& v) {
|
constexpr Rect& TopLeft(const fvec2& v) {
|
||||||
Top.x = v.x;
|
Top.x = v.x;
|
||||||
Top.y = v.y;
|
Top.y = v.y;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -103,7 +104,7 @@ class Rect {
|
|||||||
* @param v New top-right position.
|
* @param v New top-right position.
|
||||||
* @return Reference to the updated Rect.
|
* @return Reference to the updated Rect.
|
||||||
*/
|
*/
|
||||||
Rect& TopRight(const fvec2& v) {
|
constexpr Rect& TopRight(const fvec2& v) {
|
||||||
Top.z = v.x;
|
Top.z = v.x;
|
||||||
Top.w = v.y;
|
Top.w = v.y;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -114,7 +115,7 @@ class Rect {
|
|||||||
* @param v New bottom-left position.
|
* @param v New bottom-left position.
|
||||||
* @return Reference to the updated Rect.
|
* @return Reference to the updated Rect.
|
||||||
*/
|
*/
|
||||||
Rect& BotLeft(const fvec2& v) {
|
constexpr Rect& BotLeft(const fvec2& v) {
|
||||||
Bot.x = v.x;
|
Bot.x = v.x;
|
||||||
Bot.y = v.y;
|
Bot.y = v.y;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -125,15 +126,17 @@ class Rect {
|
|||||||
* @param v New bottom-right position.
|
* @param v New bottom-right position.
|
||||||
* @return Reference to the updated Rect.
|
* @return Reference to the updated Rect.
|
||||||
*/
|
*/
|
||||||
Rect& BotRight(const fvec2& v) {
|
constexpr Rect& BotRight(const fvec2& v) {
|
||||||
Bot.z = v.x;
|
Bot.z = v.x;
|
||||||
Bot.w = v.y;
|
Bot.w = v.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Rect& r) const { return Top == r.Top && Bot == r.Bot; }
|
constexpr bool operator==(const Rect& r) const {
|
||||||
|
return Top == r.Top && Bot == r.Bot;
|
||||||
|
}
|
||||||
|
|
||||||
void SwapVec2XY() {
|
constexpr void SwapVec2XY() {
|
||||||
Top.SwapXY();
|
Top.SwapXY();
|
||||||
Top.SwapZW();
|
Top.SwapZW();
|
||||||
Bot.SwapXY();
|
Bot.SwapXY();
|
||||||
|
|||||||
@@ -16,6 +16,18 @@ enum class TextureFormat {
|
|||||||
A8,
|
A8,
|
||||||
};
|
};
|
||||||
namespace Li {
|
namespace Li {
|
||||||
|
inline int TextureFormat2Bpp(TextureFormat fmt) {
|
||||||
|
switch (fmt) {
|
||||||
|
case PD::TextureFormat::A8:
|
||||||
|
return 1;
|
||||||
|
case PD::TextureFormat::RGB24:
|
||||||
|
return 3;
|
||||||
|
case PD::TextureFormat::RGBA32:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
class Texture {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
using Ptr = Texture*;
|
using Ptr = Texture*;
|
||||||
|
|||||||
@@ -9,8 +9,16 @@ class Vertex {
|
|||||||
Vertex() {}
|
Vertex() {}
|
||||||
Vertex(const fvec2& pos, const fvec2& uv, u32 color)
|
Vertex(const fvec2& pos, const fvec2& uv, u32 color)
|
||||||
: pos(pos), uv(uv), color(color) {}
|
: pos(pos), uv(uv), color(color) {}
|
||||||
|
Vertex(float x, float y, float u, float v, u32 color)
|
||||||
|
: pos(x, y), uv(u, v), color(color) {}
|
||||||
~Vertex() {}
|
~Vertex() {}
|
||||||
|
|
||||||
|
void Reset() {
|
||||||
|
pos = fvec2(0.f);
|
||||||
|
uv = fvec2(0.f);
|
||||||
|
color = 0x00000000;
|
||||||
|
}
|
||||||
|
|
||||||
fvec2 pos;
|
fvec2 pos;
|
||||||
fvec2 uv;
|
fvec2 uv;
|
||||||
u32 color = 0x00000000;
|
u32 color = 0x00000000;
|
||||||
|
|||||||
Executable
+75
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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 {
|
||||||
|
/**
|
||||||
|
* Button Object
|
||||||
|
* @note Button Press is delayed by 1 frame
|
||||||
|
* (but the visual reaction is done in the same frame)
|
||||||
|
* This only means that InPressed is responding the info in
|
||||||
|
* the next frame
|
||||||
|
*/
|
||||||
|
class PD_API Button : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Button Object constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param pos Base Position
|
||||||
|
* @param lr Reference to the Renderer
|
||||||
|
*/
|
||||||
|
Button(const std::string& label, UI7::IO& io) {
|
||||||
|
this->label = label;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~Button() = default;
|
||||||
|
|
||||||
|
/** Return true if butten is pressed*/
|
||||||
|
bool IsPressed() { return pressed; }
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
UI7Color color = UI7Color_Button; ///< current button color
|
||||||
|
std::string label; ///< Label of the Button
|
||||||
|
bool pressed = false; ///< ispressed value
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+72
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Checkbox Object
|
||||||
|
* @note The Updated input is available after
|
||||||
|
* Context::Update while the visual update is done
|
||||||
|
* during the Update
|
||||||
|
*/
|
||||||
|
class PD_API Checkbox : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor for Checkbox Object
|
||||||
|
* @param label Label of the Checkbox
|
||||||
|
* @param usr_ref Reference to the bool value to update
|
||||||
|
* @param io IO Reference
|
||||||
|
*/
|
||||||
|
Checkbox(const std::string& label, bool& usr_ref, UI7::IO& io)
|
||||||
|
: usr_ref(usr_ref) {
|
||||||
|
this->label = label;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~Checkbox() = default;
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/** Update Size if framepadding changed */
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text Size
|
||||||
|
fvec2 cbs = fvec2(18); ///< Checkbox size
|
||||||
|
UI7Color color = UI7Color_FrameBackground; ///< Checkbox background Color
|
||||||
|
std::string label; ///< Checkbox Label
|
||||||
|
bool& usr_ref; ///< User bool reference
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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>
|
||||||
|
#include <pd/ui7/layout.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Color Editor (Creating a PopUP when clicking)
|
||||||
|
*/
|
||||||
|
class PD_API ColorEdit : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param pos Base Position
|
||||||
|
* @param lr Reference to the Renderer
|
||||||
|
*/
|
||||||
|
ColorEdit(const std::string& label, u32* color, UI7::IO& io) {
|
||||||
|
// PD::Assert(color != nullptr, "Input Color Address is null!");
|
||||||
|
this->label = label;
|
||||||
|
this->color_ref = color;
|
||||||
|
this->initial_color = *color;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~ColorEdit() {
|
||||||
|
if (layout) delete layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
u32* color_ref = nullptr; ///< Color Reference
|
||||||
|
u32 initial_color; ///< Initial Color
|
||||||
|
std::string label; ///< Label of the Button
|
||||||
|
Layout* layout = nullptr; ///< Layout to open
|
||||||
|
bool is_shown = false; ///< AHow Layout Editor
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Container base class all Objects are based on
|
||||||
|
* @note this class can be used to create custom Objects as well
|
||||||
|
*/
|
||||||
|
class PD_API Container {
|
||||||
|
public:
|
||||||
|
Container() = default;
|
||||||
|
/**
|
||||||
|
* Constructor with pos and Size
|
||||||
|
* @param pos Container Position
|
||||||
|
* @param size Container Size
|
||||||
|
*/
|
||||||
|
Container(const fvec2& pos, const fvec2& size) : pos(pos), size(size) {}
|
||||||
|
/**
|
||||||
|
* Constructor by a vec4 box
|
||||||
|
* @param box Box containing top left and bottom right coords
|
||||||
|
*/
|
||||||
|
Container(const fvec4& box)
|
||||||
|
: pos(fvec2(box.x, box.y)), size(fvec2(box.z - box.x, box.w - box.y)) {}
|
||||||
|
~Container() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init Function Required by every Object that uses
|
||||||
|
* Render or Input functions
|
||||||
|
* @param io IO Reference
|
||||||
|
* @param l Drawlist Reference
|
||||||
|
*/
|
||||||
|
void Init(UI7::IO* io, Li::Drawlist* l) {
|
||||||
|
list = l;
|
||||||
|
this->io = io;
|
||||||
|
pFont = io->Font;
|
||||||
|
// this->screen = io->Ren->CurrentScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetClipRect(fvec4 clip) {
|
||||||
|
pClipRect = clip;
|
||||||
|
pCLipRectUsed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setter for Position */
|
||||||
|
void SetPos(const fvec2& pos) { this->pos = pos; }
|
||||||
|
/** Setter for Size */
|
||||||
|
void SetSize(const fvec2& size) { this->size = size; }
|
||||||
|
/** Getter for Position */
|
||||||
|
fvec2 GetPos() { return pos; }
|
||||||
|
/** Getter for Size */
|
||||||
|
fvec2 GetSize() { return size; }
|
||||||
|
Li::Font* GetFont() { return pFont; }
|
||||||
|
/**
|
||||||
|
* Get the Containers Final Position
|
||||||
|
* for Rendering and Input (if it has a parent Object)
|
||||||
|
*/
|
||||||
|
fvec2 FinalPos() {
|
||||||
|
vec2 res = pos;
|
||||||
|
if (parent) {
|
||||||
|
/// Probably should use parant->FinalPos here
|
||||||
|
res += parent->GetPos();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Setter for Parent Container */
|
||||||
|
void SetParent(Container* v) { parent = v; }
|
||||||
|
/** Getter for Parent Container */
|
||||||
|
Container* GetParent() { return parent; }
|
||||||
|
|
||||||
|
/** Check if Rendering can be skipped */
|
||||||
|
bool Skippable() const { return skippable; }
|
||||||
|
/** Check if the Object got a timeout (ID OBJ Relevant) */
|
||||||
|
bool Removable() const { return rem; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles Scrolling by scrolling pos as well as
|
||||||
|
* Time for Remove for ID Objects
|
||||||
|
* @param scrolling Scrolling Position
|
||||||
|
* @param viewport Viewport to check if the Object is skippable
|
||||||
|
*/
|
||||||
|
void HandleScrolling(fvec2 scrolling, fvec4 viewport);
|
||||||
|
/** Template function for Input Handling */
|
||||||
|
virtual void HandleInput() {}
|
||||||
|
/** Tamplate function for Object rendering */
|
||||||
|
virtual void Draw() {}
|
||||||
|
/** Template function to update internal data (if needed) */
|
||||||
|
virtual void Update() {}
|
||||||
|
/** Template as well as base func for Pool based Containers */
|
||||||
|
virtual void Reset() {
|
||||||
|
pos = 0;
|
||||||
|
size = 0;
|
||||||
|
parent = nullptr;
|
||||||
|
id = 0;
|
||||||
|
pFlags = 0;
|
||||||
|
skippable = false;
|
||||||
|
rem = false;
|
||||||
|
inp_done = false;
|
||||||
|
pSelected = false;
|
||||||
|
pPressed = false;
|
||||||
|
pPressedTwice = false;
|
||||||
|
pCLipRectUsed = false;
|
||||||
|
pClipRect = 0;
|
||||||
|
io = nullptr;
|
||||||
|
list = nullptr;
|
||||||
|
last_use = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Internal function */
|
||||||
|
void PreDraw();
|
||||||
|
/** Internal function */
|
||||||
|
void PostDraw();
|
||||||
|
|
||||||
|
/** Internal Input Handler */
|
||||||
|
void HandleInternalInput();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to unlock Input after Rendering is done in
|
||||||
|
* Menu::Update
|
||||||
|
* @note This is used if the Object got Input Handled directly after creation
|
||||||
|
* to not check for Inputs twice
|
||||||
|
*/
|
||||||
|
void UnlockInput() { inp_done = false; }
|
||||||
|
|
||||||
|
/** Get the Objects ID (if it is an ID object)*/
|
||||||
|
u32 GetID() const { return id; }
|
||||||
|
/**
|
||||||
|
* Set ID for ID Objects
|
||||||
|
* @param id Object ID (hashed prefix+objname+prefixed_counter)
|
||||||
|
*/
|
||||||
|
void SetID(u32 id) { this->id = id; }
|
||||||
|
|
||||||
|
/** Get a reference to IO */
|
||||||
|
UI7::IO* GetIO() { return io; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** used to skip Input/Render preocessing ot not*/
|
||||||
|
bool skippable = false;
|
||||||
|
/** value to check if an ID Object goes out of lifetime*/
|
||||||
|
bool rem = false;
|
||||||
|
/** Time of the last use (set by HandleScrolling)*/
|
||||||
|
u64 last_use = 0;
|
||||||
|
/** Input done or not for current frame*/
|
||||||
|
bool inp_done = false;
|
||||||
|
/** Reference to the Screen to draw the Object on*/
|
||||||
|
// Screen::Ref screen;
|
||||||
|
/** Container Position*/
|
||||||
|
fvec2 pos;
|
||||||
|
/** Container Size*/
|
||||||
|
fvec2 size;
|
||||||
|
/** Reference to the Drawlist to Draw to*/
|
||||||
|
Li::Drawlist* list = nullptr;
|
||||||
|
/** IO Reference for Renderer and Theme */
|
||||||
|
UI7::IO* io = nullptr;
|
||||||
|
/** Reference to the parent container*/
|
||||||
|
Container* parent = nullptr;
|
||||||
|
/** Object ID (0 if unused)*/
|
||||||
|
u32 id = 0;
|
||||||
|
/** Internal Flags */
|
||||||
|
u32 pFlags = 0;
|
||||||
|
/** Is Selected? */
|
||||||
|
bool pSelected = false;
|
||||||
|
/** Was Pressed */
|
||||||
|
bool pPressed = false;
|
||||||
|
/** Was Pressed Twice */
|
||||||
|
bool pPressedTwice = false;
|
||||||
|
/** ClipRect */
|
||||||
|
fvec4 pClipRect;
|
||||||
|
/** Clip Rect used */
|
||||||
|
bool pCLipRectUsed = false;
|
||||||
|
Li::Font* pFont = nullptr;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+90
@@ -0,0 +1,90 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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 {
|
||||||
|
/**
|
||||||
|
* DragData Object can take a datatype or a list
|
||||||
|
* and modifys these by moving left or right when dragging
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class PD_API DragData : public Container {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param data Data reference (Supported types can be seen in dragdata.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
|
||||||
|
*/
|
||||||
|
DragData(const std::string& label, T* data, size_t num_elms, UI7::IO& io,
|
||||||
|
T min = std::numeric_limits<T>::min(),
|
||||||
|
T max = std::numeric_limits<T>::max(), T step = 1,
|
||||||
|
int precision = 1) {
|
||||||
|
// PD::Assert(data != nullptr, "Input Data Address is null!");
|
||||||
|
this->label = label;
|
||||||
|
this->data = data;
|
||||||
|
this->elm_count = num_elms;
|
||||||
|
this->min = min;
|
||||||
|
this->max = max;
|
||||||
|
this->step = step;
|
||||||
|
this->precision = precision;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~DragData() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
std::string label; ///< Label of the Button
|
||||||
|
T* data;
|
||||||
|
size_t elm_count = 0;
|
||||||
|
T min;
|
||||||
|
T max;
|
||||||
|
T step;
|
||||||
|
int precision = 1;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+88
@@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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 <functional>
|
||||||
|
#include <pd/ui7/container/container.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Button Object
|
||||||
|
* @note Button Press is delayed by 1 frame
|
||||||
|
* (but the visual reaction is done in the same frame)
|
||||||
|
* This only means that InPressed is responding the info in
|
||||||
|
* the next frame
|
||||||
|
*/
|
||||||
|
class PD_API DynObj : public Container {
|
||||||
|
public:
|
||||||
|
DynObj() {}
|
||||||
|
/**
|
||||||
|
* Button Object constructor
|
||||||
|
* @param label Label of the Button
|
||||||
|
* @param pos Base Position
|
||||||
|
* @param lr Reference to the Renderer
|
||||||
|
*/
|
||||||
|
DynObj(std::function<void(UI7::IO*, Li::Drawlist*, Container*)> RenderFunc) {
|
||||||
|
pRenFun = RenderFunc;
|
||||||
|
}
|
||||||
|
~DynObj() = default;
|
||||||
|
|
||||||
|
void AddInputHandler(std::function<void(UI7::IO*, Container*)> inp) {
|
||||||
|
pInp = inp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return true if butten is pressed*/
|
||||||
|
bool IsPressed() { return pressed; }
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
void Reset() override {
|
||||||
|
Container::Reset();
|
||||||
|
color = UI7Color_Button;
|
||||||
|
pressed = false;
|
||||||
|
pRenFun = nullptr;
|
||||||
|
pInp = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
UI7Color color = UI7Color_Button; ///< current button color
|
||||||
|
bool pressed = false; ///< ispressed value
|
||||||
|
std::function<void(UI7::IO*, Li::Drawlist*, Container*)> pRenFun;
|
||||||
|
std::function<void(UI7::IO*, Container*)> pInp;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+74
@@ -0,0 +1,74 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Image Object
|
||||||
|
*/
|
||||||
|
class PD_API Image : public Container {
|
||||||
|
public:
|
||||||
|
Image() {}
|
||||||
|
/**
|
||||||
|
* Constructor for the Image Object
|
||||||
|
* @param img Image Texture Reference
|
||||||
|
* @param size Custom Size of the Image
|
||||||
|
*/
|
||||||
|
Image(Li::Texture img, fvec2 size = 0.f, Li::Rect uv = fvec4(0.f)) {
|
||||||
|
this->img = img;
|
||||||
|
if (size == fvec2(0.f)) {
|
||||||
|
size = img.GetSize();
|
||||||
|
}
|
||||||
|
if (uv == Li::Rect(fvec4(0.f))) {
|
||||||
|
uv = img.GetUV();
|
||||||
|
}
|
||||||
|
this->cuv = uv;
|
||||||
|
this->newsize = size;
|
||||||
|
SetSize(size);
|
||||||
|
}
|
||||||
|
~Image() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
void Reset() override {
|
||||||
|
Container::Reset();
|
||||||
|
img = Li::Texture();
|
||||||
|
newsize = 0.f;
|
||||||
|
cuv = Li::Rect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Li::Texture img; ///< Texture
|
||||||
|
fvec2 newsize = 0.f; ///< New Size
|
||||||
|
Li::Rect cuv; ///< Custom UV
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+71
@@ -0,0 +1,71 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Label [Text] Object
|
||||||
|
*/
|
||||||
|
class PD_API Label : public Container {
|
||||||
|
public:
|
||||||
|
Label() {}
|
||||||
|
/**
|
||||||
|
* Constructor for Label Object
|
||||||
|
* @param label Label [Text] to Draw
|
||||||
|
* @param lr Renderer Reference
|
||||||
|
*/
|
||||||
|
Label(const std::string& label, IO& io) {
|
||||||
|
this->label = label;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
this->SetSize(tdim);
|
||||||
|
}
|
||||||
|
~Label() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for the Rendering Handler
|
||||||
|
* @note This function is usally called by Menu::Update
|
||||||
|
* */
|
||||||
|
void Draw() override;
|
||||||
|
/**
|
||||||
|
* Override Update func to support Text modifications
|
||||||
|
*/
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
void Reset() override {
|
||||||
|
Container::Reset();
|
||||||
|
tdim = 0;
|
||||||
|
color = UI7Color_Text;
|
||||||
|
label.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
fvec2 tdim; ///< Text Size
|
||||||
|
UI7Color color = UI7Color_Text; ///< Color
|
||||||
|
std::string label; ///< Text to Render
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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_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& 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.pSize.z * 0.3f;
|
||||||
|
this->tdim = io.Font->GetTextBounds(label.c_str(), io.FontScale);
|
||||||
|
}
|
||||||
|
~Slider() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
Executable
+33
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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/button.hpp>
|
||||||
|
#include <pd/ui7/container/checkbox.hpp>
|
||||||
|
#include <pd/ui7/container/coloredit.hpp>
|
||||||
|
#include <pd/ui7/container/dragdata.hpp>
|
||||||
|
#include <pd/ui7/container/dynobj.hpp>
|
||||||
|
#include <pd/ui7/container/image.hpp>
|
||||||
|
#include <pd/ui7/container/label.hpp>
|
||||||
|
#include <pd/ui7/container/slider.hpp>
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 32Bit Value to Stpre Menu Flags */
|
||||||
|
using UI7MenuFlags = unsigned int;
|
||||||
|
/** 32Bit Value to store Alignment Flags */
|
||||||
|
using UI7Align = unsigned int;
|
||||||
|
/** 32Bit Value to store Context (IO) flags */
|
||||||
|
using UI7IOFlags = unsigned int;
|
||||||
|
/** 32Bit Value for Layout Flags */
|
||||||
|
using UI7LayoutFlags = unsigned int;
|
||||||
|
|
||||||
|
/** Menu Flags */
|
||||||
|
enum UI7MenuFlags_ {
|
||||||
|
UI7MenuFlags_None = 0, ///< No Flags (Default)
|
||||||
|
UI7MenuFlags_NoTitlebar = 1 << 0, ///< Dont Show Titlebar
|
||||||
|
UI7MenuFlags_CenterTitle = 1 << 1, ///< Center the Menu Title in Titlebar
|
||||||
|
UI7MenuFlags_HzScrolling = 1 << 2, ///< Enable Horizontal Scrolling
|
||||||
|
UI7MenuFlags_VtScrolling = 1 << 3, ///< Enable Vertical Scrolling
|
||||||
|
UI7MenuFlags_NoBackground = 1 << 4, ///< Dont Render Menu Background
|
||||||
|
UI7MenuFlags_NoClipRect = 1 << 5, ///< Disable clip render area of the Menu
|
||||||
|
UI7MenuFlags_NoCollapse = 1 << 6, ///< Disable Menu Collapse
|
||||||
|
UI7MenuFlags_NoMove = 1 << 7, ///< Disable Menu Movement
|
||||||
|
UI7MenuFlags_NoResize = 1 << 8, ///< Disable Menu Resize
|
||||||
|
UI7MenuFlags_NoClose = 1 << 9, ///< Disable Close Button
|
||||||
|
UI7MenuFlags_NoScrollbar = 1 << 10, ///< Hide the Scrollbar
|
||||||
|
// POC
|
||||||
|
UI7MenuFlags_Maximize = 1 << 11, ///< Add a Maximize Button
|
||||||
|
UI7MenuFlags_Minimize = 1 << 12, ///< Add a Minimize Button
|
||||||
|
UI7MenuFlags_AlwaysAutoSize = 1 << 13, ///< Always Auto Resize Menu
|
||||||
|
// Enable Horizontal and Vertical Scrolling
|
||||||
|
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** UI7 Layout Flags */
|
||||||
|
enum UI7LayoutFlags_ {
|
||||||
|
UI7LayoutFlags_None = 0, ///< No Flags used
|
||||||
|
UI7LayoutFlags_UseClipRect = 1 << 0, ///< Enable ClipRect
|
||||||
|
UI7LayoutFlags_HzScrolling = 1 << 1, ///< Scrolling Horizontal
|
||||||
|
UI7LayoutFlags_VtScrolling = 1 << 2, ///< Scrolling Vertical
|
||||||
|
};
|
||||||
|
|
||||||
|
/** UI7 Context Flags */
|
||||||
|
enum UI7IOFlags_ {
|
||||||
|
UI7IOFlags_None = 0, ///< No Additional Config available
|
||||||
|
UI7IOFlags_HasTouch = 1 << 0, ///< Enable touch support [future]
|
||||||
|
UI7IOFlags_HasMouseCursor = 1 << 1, ///< Enable Mouse support [future]
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Probably need to update this */
|
||||||
|
enum UI7Align_ {
|
||||||
|
UI7Align_Left = 1 << 0, ///< [Hz Op] Align Left (Default)
|
||||||
|
UI7Align_Center = 1 << 1, ///< [Hz Op] Align Center
|
||||||
|
UI7Align_Right = 1 << 2, ///< [Hz Op] Align Right
|
||||||
|
UI7Align_Top = 1 << 3, ///< [Vt Op] Align Top (Default)
|
||||||
|
UI7Align_Mid = 1 << 4, ///< [Vt Op] Align Mid
|
||||||
|
UI7Align_Bottom = 1 << 5, ///< [Vt Op] Align Bottom
|
||||||
|
// Default Horizontal and Vertical Alignment
|
||||||
|
UI7Align_Default = UI7Align_Left | UI7Align_Top,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Special flags for Layout::AddObjectEx */
|
||||||
|
enum UI7LytAdd_ {
|
||||||
|
UI7LytAdd_None = 0, ///< Also known as default or ->AddObject
|
||||||
|
UI7LytAdd_NoCursorUpdate = 1 << 0, ///< Add without cursor alignment
|
||||||
|
UI7LytAdd_NoScrollHandle = 1 << 1, ///< Skip HandleScrolling
|
||||||
|
UI7LytAdd_Front = 1 << 2, ///< Add in front of the list
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Todo: Look at this
|
||||||
|
* Maybe proof of concept ???
|
||||||
|
* Didnt remember that this exists
|
||||||
|
*/
|
||||||
|
enum UI7ContainerFlags_ {
|
||||||
|
UI7ContainerFlags_None = 0,
|
||||||
|
UI7ContainerFlags_EnableInternalInput = 1 << 0,
|
||||||
|
UI7ContainerFlags_Selectable = 1 << 1,
|
||||||
|
UI7ContainerFlags_OutlineSelected = 1 << 2,
|
||||||
|
};
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* ID Class (Generating an ID by String)
|
||||||
|
*/
|
||||||
|
class ID {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor to Generate ID by input string
|
||||||
|
* @param text Input String
|
||||||
|
*/
|
||||||
|
ID(const std::string& text) {
|
||||||
|
pID = PD::Strings::FastHash(text);
|
||||||
|
// pStrName = text;
|
||||||
|
pName = text;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Constructor used for const char* which is automatically
|
||||||
|
* used when directly placing a string istead of using ID("")
|
||||||
|
* @param text Input String
|
||||||
|
*/
|
||||||
|
constexpr ID(const char* text) {
|
||||||
|
pID = PD::FNV1A32(text);
|
||||||
|
pName = text;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Use an ID as Input
|
||||||
|
*/
|
||||||
|
ID(u32 id) { pID = id; }
|
||||||
|
~ID() = default;
|
||||||
|
|
||||||
|
/** Get The ID Initial Name */
|
||||||
|
// 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 */
|
||||||
|
constexpr const u32& RawID() const { return pID; }
|
||||||
|
|
||||||
|
/** Return the ID when casting to u32 */
|
||||||
|
constexpr operator u32() const { return pID; }
|
||||||
|
|
||||||
|
u32 pID; ///< Hash of the name
|
||||||
|
std::string pName; ///< Name
|
||||||
|
// std::string pStrName; ///< Keep this stringview alive
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/drivers/drivers.hpp>
|
||||||
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/id.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class InputHandler {
|
||||||
|
public:
|
||||||
|
InputHandler() {}
|
||||||
|
~InputHandler() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to Check if current Object is dragged
|
||||||
|
* or set it dragged
|
||||||
|
* @param id ID to identify this specific Object
|
||||||
|
* @param area Area where to start dragging
|
||||||
|
* @return if inputs to this objects are alowed or not
|
||||||
|
*/
|
||||||
|
bool DragObject(const UI7::ID& id, fvec4 area) {
|
||||||
|
if (CurrentMenu != FocusedMenu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IsObjectDragged()) {
|
||||||
|
// Only block if the Dragged Object has a difrent id
|
||||||
|
if (DraggedObject != id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get a Short define for touch pos
|
||||||
|
fvec2 p = PD::Hid::MousePos();
|
||||||
|
// Check if Drag starts in the area position
|
||||||
|
if ((PD::Hid::IsEvent(PD::Hid::Event::Down, PD::Hid::Gamepad::Touch) ||
|
||||||
|
PD::Hid::IsEvent(PD::Hid::Event::Down,
|
||||||
|
PD::Hid::Keyboard::MouseLeft)) &&
|
||||||
|
Li::Math::InBounds(p, area)) {
|
||||||
|
// Set ID and iniatial Positions
|
||||||
|
DraggedObject = id;
|
||||||
|
DragSourcePos = p;
|
||||||
|
DragPosition = p;
|
||||||
|
DragLastPosition = p;
|
||||||
|
DragDestination = area;
|
||||||
|
// Reset and Start DragTimer
|
||||||
|
DragTime.Reset();
|
||||||
|
DragTime.Rseume();
|
||||||
|
return false; // To make sure the Object is "Dragged"
|
||||||
|
} else if ((PD::Hid::IsEvent(PD::Hid::Event::Held,
|
||||||
|
PD::Hid::Gamepad::Touch) ||
|
||||||
|
PD::Hid::IsEvent(PD::Hid::Event::Held,
|
||||||
|
PD::Hid::Keyboard::MouseLeft)) &&
|
||||||
|
IsObjectDragged()) {
|
||||||
|
// Update DragLast and DragPoisition
|
||||||
|
DragLastPosition = DragPosition;
|
||||||
|
DragPosition = p;
|
||||||
|
} else if ((PD::Hid::IsEvent(PD::Hid::Event::Up, PD::Hid::Gamepad::Touch) ||
|
||||||
|
PD::Hid::IsEvent(PD::Hid::Event::Up,
|
||||||
|
PD::Hid::Keyboard::MouseLeft)) &&
|
||||||
|
IsObjectDragged()) {
|
||||||
|
// Released... Everything gets reset
|
||||||
|
DraggedObject = 0;
|
||||||
|
DragPosition = 0;
|
||||||
|
DragSourcePos = 0;
|
||||||
|
DragLastPosition = 0;
|
||||||
|
DragDestination = fvec4(0);
|
||||||
|
// Set Drag released to true (only one frame)
|
||||||
|
// and Only if still in Box
|
||||||
|
DragReleased = Li::Math::InBounds(PD::Hid::MousePosLast(), area);
|
||||||
|
DragReleasedAW = true; // Advanced
|
||||||
|
u64 d_rel = PD::Os::GetTime();
|
||||||
|
if (d_rel - DragLastReleased < DoubleClickTime) {
|
||||||
|
DragDoubleRelease = true;
|
||||||
|
DragLastReleased = 0; // Set 0 to prevent double exec
|
||||||
|
} else {
|
||||||
|
DragLastReleased = d_rel;
|
||||||
|
}
|
||||||
|
// Ensure timer is paused
|
||||||
|
DragTime.Pause();
|
||||||
|
DragTime.Reset();
|
||||||
|
// Still return The Object is Dragged to ensure
|
||||||
|
// the DragReleased var can be used
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return IsObjectDragged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
DragTime.Update();
|
||||||
|
DragReleased = false;
|
||||||
|
DragReleasedAW = false;
|
||||||
|
DragDoubleRelease = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 DoubleClickTime = 500; // Milliseconds
|
||||||
|
u32 FocusedMenu = 0;
|
||||||
|
fvec4 FocusedMenuRect;
|
||||||
|
u32 CurrentMenu = 0;
|
||||||
|
u32 DraggedObject = 0;
|
||||||
|
fvec2 DragSourcePos = 0;
|
||||||
|
fvec2 DragPosition = 0;
|
||||||
|
fvec2 DragLastPosition = 0;
|
||||||
|
/** Fvec4 has an constructor problem currently */
|
||||||
|
fvec4 DragDestination = fvec4(0);
|
||||||
|
Timer DragTime;
|
||||||
|
u64 DragLastReleased = 0;
|
||||||
|
bool DragReleased = false; ///< Drag Releaded in Box
|
||||||
|
bool DragReleasedAW = false; ///< Drag Released Anywhere
|
||||||
|
bool DragDoubleRelease = false; ///< Double Click
|
||||||
|
/** Check if an object is Dragged already */
|
||||||
|
bool IsObjectDragged() const { return DraggedObject != 0; }
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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 <list>
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/input_api.hpp>
|
||||||
|
#include <pd/ui7/theme.hpp>
|
||||||
|
#include <pd/ui7/viewport.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class Label;
|
||||||
|
class Image;
|
||||||
|
class DynObj;
|
||||||
|
class PD_API IO {
|
||||||
|
public:
|
||||||
|
IO();
|
||||||
|
~IO();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IO Update Internal Variables
|
||||||
|
*/
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final Draw List for PD::Li::Gfx::RednerDrawData
|
||||||
|
*
|
||||||
|
* Possible thanks to the Drawlist::Merge Feature
|
||||||
|
*/
|
||||||
|
Li::Drawlist FDL;
|
||||||
|
ViewPort CurrentViewPort;
|
||||||
|
// ivec4 CurrentViewPort = ivec4(0, 0, 0, 0);
|
||||||
|
std::unordered_map<u32, ViewPort> ViewPorts;
|
||||||
|
float Framerate = 0.f;
|
||||||
|
float Delta = 0.f;
|
||||||
|
u64 LastTime = 0;
|
||||||
|
TimeStats DeltaStats;
|
||||||
|
Timer Time;
|
||||||
|
Li::Font* Font = nullptr;
|
||||||
|
float FontScale = 0.7f;
|
||||||
|
UI7::Theme Theme;
|
||||||
|
fvec2 MenuPadding = 5.f;
|
||||||
|
fvec2 FramePadding = 5.f;
|
||||||
|
float ItemRowHeight = 0.f;
|
||||||
|
float FrameRounding = 0.f;
|
||||||
|
fvec2 ItemSpace = fvec2(5.f, 2.f);
|
||||||
|
fvec2 MinSliderDragSize = 10.f; // Min height (Vt) and Min Width (Hz)
|
||||||
|
bool ShowMenuBorder = true;
|
||||||
|
bool ShowFrameBorder = false; // not implemented yet
|
||||||
|
bool WrapLabels = false; // Beta state
|
||||||
|
float OverScrollMod = 0.15f;
|
||||||
|
u64 DoubleClickTime = 500; // Milliseconds
|
||||||
|
std::list<std::pair<UI7::ID, Li::Drawlist*>> DrawlistRegestry;
|
||||||
|
// Short define for DrawKLstRegestryLast
|
||||||
|
std::list<std::pair<UI7::ID, Li::Drawlist*>> pDLRL;
|
||||||
|
Li::Drawlist Back;
|
||||||
|
Li::Drawlist Front;
|
||||||
|
u32 NumVertices = 0; ///< Debug Vertices Num
|
||||||
|
u32 NumIndices = 0; ///< Debug Indices Num
|
||||||
|
std::vector<u32> MenuOrder;
|
||||||
|
std::vector<Li::Font*> FontStack;
|
||||||
|
|
||||||
|
// Pools
|
||||||
|
PD::Pool<UI7::Label> LabelPool;
|
||||||
|
PD::Pool<UI7::Image> ImagePool;
|
||||||
|
PD::Pool<UI7::DynObj> DynObjPool;
|
||||||
|
|
||||||
|
// DrawlistApi
|
||||||
|
void RegisterDrawlist(const UI7::ID& id, Li::Drawlist* v) {
|
||||||
|
DrawlistRegestry.push_back(std::make_pair(id, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddViewPort(const ID& id, const ivec4& size) {
|
||||||
|
if (ViewPorts.count(id.RawID())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ViewPorts[id.RawID()] = ViewPort(id, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewPort& GetViewPort(const ID& id) {
|
||||||
|
if (!ViewPorts.count(id.RawID())) {
|
||||||
|
static ViewPort err;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return ViewPorts[id.RawID()];
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushFont(Li::Font* f) {
|
||||||
|
FontStack.push_back(Font);
|
||||||
|
Font = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopFont() {
|
||||||
|
if (!FontStack.empty()) {
|
||||||
|
Font = FontStack.back();
|
||||||
|
FontStack.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UI7::InputHandler InputHandler;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.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/input_api.hpp>
|
||||||
|
#include <pd/ui7/theme.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class Context;
|
||||||
|
class PD_API Layout {
|
||||||
|
public:
|
||||||
|
Layout(const ID& id, IO& io) : ID(id), IO(io) {
|
||||||
|
DrawList.SetFont(IO.Font);
|
||||||
|
DrawList.SetFontscale(io.FontScale);
|
||||||
|
Scrolling[0] = false;
|
||||||
|
Scrolling[1] = false;
|
||||||
|
CursorInit();
|
||||||
|
Pos = fvec2(io.CurrentViewPort.pSize.x, io.CurrentViewPort.pSize.y);
|
||||||
|
Size = 0;
|
||||||
|
WorkRect = fvec4(IO.MenuPadding, Size - (fvec2(2) * IO.MenuPadding));
|
||||||
|
}
|
||||||
|
~Layout();
|
||||||
|
|
||||||
|
/** SECTION CONTAINERS */
|
||||||
|
/**
|
||||||
|
* 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 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* r = FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::DragData<T>(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* r = FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Slider<T>(label, data, this->IO, min, max, precision);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
AddObject(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** SECTION OTHERSTUFF */
|
||||||
|
|
||||||
|
const std::string GetName() const { return ID.GetName(); }
|
||||||
|
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& GetDrawList() { return DrawList; }
|
||||||
|
|
||||||
|
void CursorInit();
|
||||||
|
void SameLine();
|
||||||
|
void CursorMove(const fvec2& size);
|
||||||
|
void PushFont(Li::Font* f) { IO.PushFont(f); }
|
||||||
|
void PopFont() { IO.PopFont(); }
|
||||||
|
|
||||||
|
bool ObjectWorkPos(fvec2& movpos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended Object Add Func to Add Object in Front or disable
|
||||||
|
* Position by cursor as well as cursor update...
|
||||||
|
* Should only be used in special cases as the
|
||||||
|
* AddObject function is faster
|
||||||
|
* Using Flags for its features cause dont want to have too much args
|
||||||
|
*/
|
||||||
|
void AddObjectEx(Container* obj, u32 Flags);
|
||||||
|
/**
|
||||||
|
* Fast Function to Add Object in Layout SPace like
|
||||||
|
* button Label images etc
|
||||||
|
*/
|
||||||
|
void AddObject(Container* obj);
|
||||||
|
Container* FindObject(u32 id);
|
||||||
|
void ClearIDObjects() { IDObjects.clear(); }
|
||||||
|
|
||||||
|
fvec2 AlignPosition(fvec2 pos, fvec2 size, fvec4 area, UI7Align alignment);
|
||||||
|
|
||||||
|
/** Get the Alignment for Current State */
|
||||||
|
UI7Align GetAlignment() {
|
||||||
|
/// if temp alignment is used then return it and
|
||||||
|
/// reset tmpalign
|
||||||
|
if (TempAlign) {
|
||||||
|
auto t = TempAlign;
|
||||||
|
TempAlign = 0;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return Alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAlign(UI7Align a) { Alignment = a; }
|
||||||
|
void NextAlign(UI7Align a) { TempAlign = a; }
|
||||||
|
|
||||||
|
void HandleScrolling();
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
fvec2 DbgScrollOffset() { return ScrollOffset; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Menu;
|
||||||
|
friend class PD::UI7::Context;
|
||||||
|
friend class ReMenu;
|
||||||
|
// Base Components
|
||||||
|
UI7::ID ID;
|
||||||
|
UI7::IO& IO;
|
||||||
|
Li::Drawlist DrawList;
|
||||||
|
UI7LayoutFlags Flags;
|
||||||
|
|
||||||
|
// Positioning
|
||||||
|
fvec2 Pos;
|
||||||
|
fvec2 Size;
|
||||||
|
UI7Align Alignment = UI7Align_Default;
|
||||||
|
UI7Align TempAlign;
|
||||||
|
|
||||||
|
// Cursor
|
||||||
|
fvec2 Cursor;
|
||||||
|
fvec2 InitialCursorOffset;
|
||||||
|
fvec2 BackupCursor;
|
||||||
|
fvec2 SamelineCursor;
|
||||||
|
fvec2 BeforeSameLine;
|
||||||
|
fvec2 LastObjSize;
|
||||||
|
fvec2 MaxPosition;
|
||||||
|
fvec4 WorkRect;
|
||||||
|
|
||||||
|
// Scrolling (Only theoretical)
|
||||||
|
// Rendering must be done by the Objective that uses the Lyt
|
||||||
|
fvec2 ScrollOffset;
|
||||||
|
fvec2 ScrollStart;
|
||||||
|
bool Scrolling[2];
|
||||||
|
|
||||||
|
// Objects
|
||||||
|
std::list<Container*> Objects;
|
||||||
|
std::vector<Container*> IDObjects;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
#include <pd/ui7/layout.hpp>
|
||||||
|
|
||||||
|
#include "pd/ui7/container/dragdata.hpp"
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class PD_API Menu {
|
||||||
|
public:
|
||||||
|
Menu(const UI7::ID& id, UI7::IO& pIO);
|
||||||
|
~Menu() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 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* r = pLayout.FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::DragData<T>(label, data, num_elms, pIO, min, max, step,
|
||||||
|
precision);
|
||||||
|
// Isnt This exactly the same line???
|
||||||
|
// r = UI7::DragData<T>::New(label, data, num_elms, pIO, min, max, step,
|
||||||
|
// precision);
|
||||||
|
r->SetID(id);
|
||||||
|
}
|
||||||
|
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* r = pLayout.FindObject(id);
|
||||||
|
if (!r) {
|
||||||
|
r = new UI7::Slider<T>(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 Separator();
|
||||||
|
void SeparatorText(const std::string& label);
|
||||||
|
bool BeginTreeNode(const ID& id);
|
||||||
|
void EndTreeNode();
|
||||||
|
|
||||||
|
void HandleFocus();
|
||||||
|
void HandleTitlebarActions();
|
||||||
|
void DrawBaseLayout();
|
||||||
|
|
||||||
|
void AddObject(PD::UI7::Container* obj) { pLayout.AddObject(obj); }
|
||||||
|
void AddObjectEx(PD::UI7::Container* obj, PD::u32 flags) {
|
||||||
|
pLayout.AddObjectEx(obj, flags);
|
||||||
|
}
|
||||||
|
Container* FindObject(u32 id) { return pLayout.FindObject(id); }
|
||||||
|
|
||||||
|
void PushFont(Li::Font* f) { pIO.PushFont(f); }
|
||||||
|
void PopFont() { pIO.PopFont(); }
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
void SetSize(PD::fvec2 size) { pLayout.SetSize(size); }
|
||||||
|
void SetPosition(PD::fvec2 pos) { pLayout.SetPosition(pos); }
|
||||||
|
const PD::fvec2& GetSize() const { return pLayout.GetSize(); }
|
||||||
|
const PD::fvec2& GetPosition() const { return pLayout.GetPosition(); }
|
||||||
|
|
||||||
|
/** Data Section */
|
||||||
|
|
||||||
|
UI7MenuFlags Flags = 0;
|
||||||
|
Layout pLayout;
|
||||||
|
IO& pIO;
|
||||||
|
ID pID;
|
||||||
|
bool* pIsShown = nullptr;
|
||||||
|
bool pIsOpen = true;
|
||||||
|
std::unordered_map<u32, bool> pTreeNodes;
|
||||||
|
fvec2 TempScrollXY;
|
||||||
|
|
||||||
|
float TitleBarHeight = 0.f;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+159
@@ -0,0 +1,159 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using this to support 32bit color values as well as
|
||||||
|
* values from UI7Color_
|
||||||
|
*/
|
||||||
|
using UI7Color = PD::u32;
|
||||||
|
|
||||||
|
/** Theme Color */
|
||||||
|
enum UI7Color_ {
|
||||||
|
UI7Color_Background, ///< UI7 Menu Background
|
||||||
|
UI7Color_Border, ///< Menu/Frame Border Color
|
||||||
|
UI7Color_Button, ///< UI7 Button Idle Color
|
||||||
|
UI7Color_ButtonDead, ///< UI7 Disabled Button Color
|
||||||
|
UI7Color_ButtonActive, ///< UI7 Pressed Button Color
|
||||||
|
UI7Color_ButtonHovered, ///< UI7 Hovered Button Color
|
||||||
|
UI7Color_Text, ///< UI7 Text Color
|
||||||
|
UI7Color_TextDead, ///< UI7 Dead Text Color
|
||||||
|
UI7Color_Header, ///< UI7 Menu Header Color
|
||||||
|
UI7Color_HeaderDead, ///< Inactive Header
|
||||||
|
UI7Color_Selector, ///< UI7 Selector Color
|
||||||
|
UI7Color_Checkmark, ///< UI7 Checkmark Color
|
||||||
|
UI7Color_FrameBackground, ///< UI7 Frame Background
|
||||||
|
UI7Color_FrameBackgroundHovered, ///< UI7 Hovered Frame Background
|
||||||
|
UI7Color_Progressbar, ///< UI7 Progressbar Background
|
||||||
|
UI7Color_ListEven, ///< UI7 List (Even Entry) Background Color
|
||||||
|
UI7Color_ListOdd, ///< UI7 List (Odd Entry) Background Color
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class PD_API Theme {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default Constructor Setting up the Default theme
|
||||||
|
* @note if using Shared Reference you probably need to do
|
||||||
|
* Theme::Default(*theme.get());
|
||||||
|
*/
|
||||||
|
Theme() { Default(*this); }
|
||||||
|
~Theme() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple static Loader for the Default Theme
|
||||||
|
* @param theme Theme Reference
|
||||||
|
*/
|
||||||
|
static void Default(Theme& theme);
|
||||||
|
/**
|
||||||
|
* White Mode Theme
|
||||||
|
* @param Theme theme reference
|
||||||
|
*/
|
||||||
|
static void Flashbang(Theme& theme);
|
||||||
|
|
||||||
|
/** Revert the last Color Change */
|
||||||
|
Theme& Pop() {
|
||||||
|
pTheme[pChanges[pChanges.size() - 1].first] =
|
||||||
|
pChanges[pChanges.size() - 1].second;
|
||||||
|
pChanges.pop_back();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revert the last color Change done for a specific color
|
||||||
|
* @param c Color to revert change from
|
||||||
|
*/
|
||||||
|
Theme& Pop(UI7Color c) {
|
||||||
|
for (size_t i = pChanges.size() - 1; i > 0; i--) {
|
||||||
|
if (pChanges[i].first == c) {
|
||||||
|
pTheme[c] = pChanges[i].second;
|
||||||
|
pChanges.erase(pChanges.begin() + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change a Color
|
||||||
|
* @param tc Color Identifier
|
||||||
|
* @param color Color to change to
|
||||||
|
*/
|
||||||
|
Theme& Change(UI7Color tc, u32 color) {
|
||||||
|
if (pTheme.find(tc) == pTheme.end()) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
pChanges.push_back(std::make_pair(tc, pTheme[tc]));
|
||||||
|
pTheme[tc] = color;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Color of a Color ReferenceID
|
||||||
|
* @param c ReferenceID
|
||||||
|
*/
|
||||||
|
u32 Get(UI7Color c) const {
|
||||||
|
auto e = pTheme.find(c);
|
||||||
|
if (e == pTheme.end()) {
|
||||||
|
return 0x00000000;
|
||||||
|
}
|
||||||
|
return e->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [UNSAFE] to use
|
||||||
|
* Get the Color Ref of a Color ReferenceID
|
||||||
|
* @param c ReferenceID
|
||||||
|
*/
|
||||||
|
u32& GetRef(UI7Color c) {
|
||||||
|
auto e = pTheme.find(c);
|
||||||
|
if (e == pTheme.end()) {
|
||||||
|
static u32 noclr = 0x00000000;
|
||||||
|
return noclr;
|
||||||
|
}
|
||||||
|
return e->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operator wrapper for get
|
||||||
|
* @param c Color ReferenceID
|
||||||
|
*/
|
||||||
|
u32 operator[](UI7Color c) const { return Get(c); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change but just sets [can implement completly new ids]
|
||||||
|
* @param tc Color ID (Can be self creeated ones as well)
|
||||||
|
* @param clr Color it should be set to
|
||||||
|
*/
|
||||||
|
void Set(UI7Color tc, u32 clr) { pTheme[tc] = clr; }
|
||||||
|
|
||||||
|
std::unordered_map<u32, u32> pTheme; ///< Theme Data
|
||||||
|
std::vector<std::pair<UI7Color, u32>> pChanges; ///< List of Changes
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/pd_p_api.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
#include <pd/ui7/menu.hpp>
|
||||||
|
|
||||||
|
#include "pd/ui7/flags.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare UI7 Version
|
||||||
|
* Format: 00 00 00 00
|
||||||
|
* Major Minor Patch Build
|
||||||
|
* 0x01010000 -> 1.1.0-0
|
||||||
|
*/
|
||||||
|
#define UI7_VERSION 0x00070000
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
/**
|
||||||
|
* Get UI7 Version String
|
||||||
|
* @param show_build Show build num (mostly unused)
|
||||||
|
* @return Version String (1.0.0-1 for example)
|
||||||
|
*/
|
||||||
|
PD_API std::string GetVersion(bool show_build = false);
|
||||||
|
/** Base Context for UI7 */
|
||||||
|
class PD_API Context {
|
||||||
|
public:
|
||||||
|
Context() {}
|
||||||
|
~Context() = default;
|
||||||
|
|
||||||
|
IO& GetIO() { return pIO; }
|
||||||
|
void AddViewPort(const ID& id, const ivec4& vp);
|
||||||
|
void UseViewPort(const ID& id);
|
||||||
|
void Update();
|
||||||
|
Menu* BeginMenu(const ID& id, UI7MenuFlags flags = 0, bool* pShow = nullptr);
|
||||||
|
Menu* CurrentMenu() { return pCurrent; }
|
||||||
|
void EndMenu();
|
||||||
|
void AboutMenu(bool* show = nullptr);
|
||||||
|
void MetricsMenu(bool* show = nullptr);
|
||||||
|
void StyleEditor(bool* show = nullptr);
|
||||||
|
|
||||||
|
Li::Drawlist& GetDrawData() { return pIO.FDL; }
|
||||||
|
|
||||||
|
Menu* pGetOrCreateMenu(const ID& id) {
|
||||||
|
auto menu = pMenus.find(id);
|
||||||
|
if (menu == pMenus.end()) {
|
||||||
|
pMenus[id] = new Menu(id, pIO);
|
||||||
|
menu = pMenus.find(id);
|
||||||
|
}
|
||||||
|
return menu->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
IO pIO;
|
||||||
|
/** Current Menu */
|
||||||
|
Menu* pCurrent = nullptr;
|
||||||
|
std::vector<u32> pCurrentMenus;
|
||||||
|
std::vector<u32> pDFO; /** Debug Final Order */
|
||||||
|
std::unordered_map<u32, Menu*> pMenus;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/ui7/id.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
class ViewPort {
|
||||||
|
public:
|
||||||
|
ViewPort() : pID(""), pSize(0) {}
|
||||||
|
ViewPort(const ID& id, const ivec4& size) : pID(id), pSize(size) {}
|
||||||
|
~ViewPort() {}
|
||||||
|
|
||||||
|
ID GetID() const { return pID; }
|
||||||
|
ivec4& GetSize() { return pSize; }
|
||||||
|
|
||||||
|
ID pID;
|
||||||
|
ivec4 pSize;
|
||||||
|
};
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
#include <pd/ultra/flags.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class PD_API Canvas {
|
||||||
|
public:
|
||||||
|
Canvas();
|
||||||
|
Canvas(const PD::fvec2& size);
|
||||||
|
~Canvas();
|
||||||
|
|
||||||
|
void SetVirtualViewport(const PD::fvec2& size);
|
||||||
|
void SetViewport(const PD::fvec2& size);
|
||||||
|
|
||||||
|
PD::fvec2 VTranslatePos(const PD::fvec2& p) const;
|
||||||
|
PD::fvec2 VTranslateAlignPos(const PD::fvec2& pos, const PD::fvec2& size,
|
||||||
|
UltraAlignment align) const;
|
||||||
|
PD::Li::Rect VTranslateObject(const PD::fvec2& pos, const PD::fvec2& size,
|
||||||
|
UltraAlignment align,
|
||||||
|
bool size_modified = false) const;
|
||||||
|
PD::Li::Rect TranslateObject(const PD::fvec2& pos, const PD::fvec2& size,
|
||||||
|
UltraAlignment align,
|
||||||
|
bool size_modified = false) const;
|
||||||
|
PD::fvec2 TranslatePos(const PD::fvec2& p) const;
|
||||||
|
PD::fvec2 VTranslateSize(const PD::fvec2& s) const;
|
||||||
|
PD::fvec2 TranslateSize(const PD::fvec2& s) const;
|
||||||
|
float VTranslateFontscale(float f) const;
|
||||||
|
float TranslateFontscale(float f) const;
|
||||||
|
const PD::u32& GetRevision() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PD::fvec2 pViewport;
|
||||||
|
PD::fvec2 pVirtualViewPort;
|
||||||
|
float pVfactor = 0.f;
|
||||||
|
PD::fvec2 pVoff;
|
||||||
|
PD::u32 pRev; // revision
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
#include <pd/ultra/canvas.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class Container {
|
||||||
|
public:
|
||||||
|
Container() {}
|
||||||
|
Container(const PD::Li::Rect& r) : pRect(r) {}
|
||||||
|
virtual ~Container() {}
|
||||||
|
|
||||||
|
void Push(PD::Ultra::ElementBase& elem) {
|
||||||
|
elem.SetParent(this);
|
||||||
|
pElems.Push(&elem);
|
||||||
|
}
|
||||||
|
void Reset() { pElems.ResetFast(); }
|
||||||
|
const PD::Li::Rect& GetRenderspace() const { return pRect; }
|
||||||
|
|
||||||
|
void SetViewport(const PD::fvec2& vp) {
|
||||||
|
pCanvas.SetViewport(vp);
|
||||||
|
pRect = PD::fvec4(PD::fvec2(0), vp);
|
||||||
|
}
|
||||||
|
void SetBaseViewport(const PD::ivec2& vp) { pCanvas.SetVirtualViewport(vp); }
|
||||||
|
|
||||||
|
const PD::fvec2 GetTopLeft() const { return pRect.TopLeft(); }
|
||||||
|
const PD::fvec2 GetTopRight() const { return pRect.TopRight(); }
|
||||||
|
const PD::fvec2 GetBotLeft() const { return pRect.BotLeft(); }
|
||||||
|
const PD::fvec2 GetBotRight() const { return pRect.BotRight(); }
|
||||||
|
const PD::fvec2 GetSize() const { return pRect.BotRight() - pRect.TopLeft(); }
|
||||||
|
const PD::fvec2 GetPosition() const { return pRect.TopLeft(); }
|
||||||
|
const Canvas& GetCanvas() const { return pCanvas; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PD::Pool<PD::Ultra::ElementBase*>& GetElements() { return pElems; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PD::Li::Rect pRect;
|
||||||
|
Canvas pCanvas;
|
||||||
|
PD::Pool<PD::Ultra::ElementBase*> pElems;
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class PD_API Button : public ElementBase {
|
||||||
|
public:
|
||||||
|
Button() {}
|
||||||
|
Button(const PD::fvec2& pos, const PD::fvec2& size, const PD::Color& color,
|
||||||
|
float rounding = 0.f, UltraAlignment align = 0)
|
||||||
|
: pColor(color), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = pos;
|
||||||
|
this->pSize = size;
|
||||||
|
}
|
||||||
|
Button(float x, float y, float w, float h, const PD::Color& color,
|
||||||
|
float rounding = 0.f, UltraAlignment align = 0)
|
||||||
|
: pColor(color), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = PD::fvec2(x, y);
|
||||||
|
this->pSize = PD::fvec2(w, h);
|
||||||
|
}
|
||||||
|
~Button() {}
|
||||||
|
|
||||||
|
void Draw(PD::Li::Drawlist& l) override;
|
||||||
|
void Update() override;
|
||||||
|
void SetColor(const PD::Color& color) { pColor = color; }
|
||||||
|
void SetFocusedColor(const PD::Color& color) { pHovered = color; }
|
||||||
|
void SetTextColor(const PD::Color& color) { pTextColor = color; }
|
||||||
|
void SetRounding(float r) { pRounding = r; }
|
||||||
|
void SetLined(bool v) { pLined = v; }
|
||||||
|
void SetThickness(int v) { pThickness = v; }
|
||||||
|
void SetText(const std::string& text) { pText = text; }
|
||||||
|
void SetAutoSizePadding(const PD::fvec2& size) { pAsp = size; }
|
||||||
|
|
||||||
|
// Discard these funcs
|
||||||
|
void OnFocus(EventFunc func) override {}
|
||||||
|
void OnUnFocus(EventFunc func) override {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string pText;
|
||||||
|
PD::Color pRenderColor;
|
||||||
|
PD::Color pColor;
|
||||||
|
PD::Color pHovered;
|
||||||
|
PD::Color pTextColor;
|
||||||
|
float pRounding = 0.f;
|
||||||
|
bool pLined = false;
|
||||||
|
int pThickness = 1.f;
|
||||||
|
// Auto-Size-Padding
|
||||||
|
PD::fvec2 pAsp = PD::fvec2(30, 10);
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <pd/lithium/lithium.hpp>
|
||||||
|
#include <pd/ultra/flags.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class Canvas;
|
||||||
|
class Container;
|
||||||
|
using EventFunc = std::function<void()>;
|
||||||
|
class PD_API ElementBase {
|
||||||
|
public:
|
||||||
|
ElementBase() {}
|
||||||
|
~ElementBase() {}
|
||||||
|
|
||||||
|
virtual void Draw(PD::Li::Drawlist& dl) = 0;
|
||||||
|
/**
|
||||||
|
* Reset Function (for PD::Pool::FastReset)
|
||||||
|
*/
|
||||||
|
virtual void Reset() {}
|
||||||
|
virtual void Update();
|
||||||
|
|
||||||
|
void SetAlignment(UltraAlignment a) { pAlignment = a; }
|
||||||
|
void SetPosition(const PD::fvec2& pos) { pPos = pos; }
|
||||||
|
void SetPosition(float x, float y) { pPos = PD::fvec2(x, y); }
|
||||||
|
void SetSize(const PD::fvec2& size) { pSize = size; }
|
||||||
|
void SetSize(float w, float h) { pSize = PD::fvec2(w, h); }
|
||||||
|
/**
|
||||||
|
* Executed on Hovering
|
||||||
|
* Elemnents can override / discard this func
|
||||||
|
*/
|
||||||
|
virtual void OnFocus(EventFunc func) { pHover = func; }
|
||||||
|
/**
|
||||||
|
* Executed on Mocing out of the space
|
||||||
|
* Elemnents can override / discard this func
|
||||||
|
*/
|
||||||
|
virtual void OnUnFocus(EventFunc func) { pUnHover = func; }
|
||||||
|
/**
|
||||||
|
* Executrd on KeyUp event
|
||||||
|
* Elemnents can override / discard this func
|
||||||
|
*/
|
||||||
|
virtual void OnPress(EventFunc func) { pPress = func; }
|
||||||
|
|
||||||
|
void SetFontScale(float s = 1.f) { pFontScale = 1.f; }
|
||||||
|
float GetFontScale() const { return pFontScale; }
|
||||||
|
|
||||||
|
void SetFont(PD::Li::Font& font) { pFont = &font; }
|
||||||
|
|
||||||
|
void SetFontIfNull(PD::Li::Font& font) {
|
||||||
|
if (!pFont) pFont = &font;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void UpdateInput();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class Container;
|
||||||
|
void SetParent(Container* c) { pParent = c; }
|
||||||
|
bool RevisionUpdate(PD::u32 req);
|
||||||
|
Container* pParent = nullptr;
|
||||||
|
PD::u32 pCanvasRev = 0;
|
||||||
|
UltraAlignment pAlignment = 0;
|
||||||
|
PD::fvec2 pPos;
|
||||||
|
PD::fvec2 pSize;
|
||||||
|
PD::Li::Rect pRenderspace;
|
||||||
|
EventFunc pHover = nullptr;
|
||||||
|
EventFunc pUnHover = nullptr;
|
||||||
|
EventFunc pPress = nullptr;
|
||||||
|
bool pFocued = false;
|
||||||
|
// Not used by every object btw
|
||||||
|
PD::Li::Font* pFont = nullptr;
|
||||||
|
float pFontScale = 1.f;
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class PD_API Image : public ElementBase {
|
||||||
|
public:
|
||||||
|
Image() {}
|
||||||
|
Image(PD::Li::Texture* tex, const PD::fvec2& pos, float rounding = 0.f,
|
||||||
|
UltraAlignment align = 0)
|
||||||
|
: pColor(0xffffffff), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = pos;
|
||||||
|
SetTexture(tex);
|
||||||
|
}
|
||||||
|
Image(PD::Li::Texture* tex, float x, float y, float rounding = 0.f,
|
||||||
|
UltraAlignment align = 0)
|
||||||
|
: pColor(0xffffffff), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = PD::fvec2(x, y);
|
||||||
|
SetTexture(tex);
|
||||||
|
}
|
||||||
|
~Image() {}
|
||||||
|
|
||||||
|
void Draw(PD::Li::Drawlist& l) override;
|
||||||
|
|
||||||
|
void SetColor(const PD::Color& color) { pColor = color; }
|
||||||
|
void SetRounding(float r) { pRounding = r; }
|
||||||
|
void SetTexture(PD::Li::Texture* tex) {
|
||||||
|
pTex = tex;
|
||||||
|
SetSize(pTex->GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PD::Color pColor = 0xffffffff;
|
||||||
|
PD::Li::Texture* pTex = nullptr;
|
||||||
|
float pRounding = 0.f;
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class PD_API Rect : public ElementBase {
|
||||||
|
public:
|
||||||
|
Rect() {}
|
||||||
|
Rect(const PD::fvec2& pos, const PD::fvec2& size, const PD::Color& color,
|
||||||
|
float rounding = 0.f, UltraAlignment align = 0)
|
||||||
|
: pColor(color), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = pos;
|
||||||
|
this->pSize = size;
|
||||||
|
}
|
||||||
|
Rect(float x, float y, float w, float h, const PD::Color& color,
|
||||||
|
float rounding = 0.f, UltraAlignment align = 0)
|
||||||
|
: pColor(color), pRounding(rounding) {
|
||||||
|
this->pAlignment = align;
|
||||||
|
this->pPos = PD::fvec2(x, y);
|
||||||
|
this->pSize = PD::fvec2(w, h);
|
||||||
|
}
|
||||||
|
~Rect() {}
|
||||||
|
|
||||||
|
void Draw(PD::Li::Drawlist& l) override;
|
||||||
|
|
||||||
|
void SetColor(const PD::Color& color) { pColor = color; }
|
||||||
|
void SetRounding(float r) { pRounding = r; }
|
||||||
|
void SetLined(bool v) { pLined = v; }
|
||||||
|
void SetThickness(int v) { pThickness = v; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PD::Color pColor;
|
||||||
|
float pRounding = 0.f;
|
||||||
|
bool pLined = false;
|
||||||
|
int pThickness = 1.f;
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class PD_API Text : public ElementBase {
|
||||||
|
public:
|
||||||
|
Text() {}
|
||||||
|
~Text() {}
|
||||||
|
|
||||||
|
void Draw(PD::Li::Drawlist& l) override;
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
void SetColor(const PD::Color& color) { pColor = color; }
|
||||||
|
void SetText(const std::string& text) { pText = text; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PD::Color pColor;
|
||||||
|
std::string pText;
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/common.hpp>
|
||||||
|
|
||||||
|
using UltraAlignment = PD::u32;
|
||||||
|
enum UltraAlignment_ {
|
||||||
|
UltraAlignment_None = 0,
|
||||||
|
UltraAlignment_Top = 1 << 0,
|
||||||
|
UltraAlignment_Bot = 1 << 1,
|
||||||
|
UltraAlignment_Left = 1 << 2,
|
||||||
|
UltraAlignment_Right = 1 << 3,
|
||||||
|
UltraAlignment_CenterVertical = 1 << 4,
|
||||||
|
UltraAlignment_CenterHorizontal = 1 << 5,
|
||||||
|
UltraAlignment_TopLeft = UltraAlignment_Top | UltraAlignment_Left,
|
||||||
|
UltraAlignment_TopRight = UltraAlignment_Top | UltraAlignment_Right,
|
||||||
|
UltraAlignment_BotLeft = UltraAlignment_Bot | UltraAlignment_Left,
|
||||||
|
UltraAlignment_BotRight = UltraAlignment_Bot | UltraAlignment_Right,
|
||||||
|
UltraAlignment_Center =
|
||||||
|
UltraAlignment_CenterVertical | UltraAlignment_CenterHorizontal,
|
||||||
|
};
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <pd/ultra/canvas.hpp>
|
||||||
|
#include <pd/ultra/container.hpp>
|
||||||
|
#include <pd/ultra/elems/element.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Ultra {
|
||||||
|
class PD_API Layout : public Container {
|
||||||
|
public:
|
||||||
|
Layout() {}
|
||||||
|
~Layout() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a fallback font if you dont want to explicitly set a font for every
|
||||||
|
* objectt individually
|
||||||
|
*/
|
||||||
|
void SetFont(PD::Li::Font& font) { pFont = &font; }
|
||||||
|
void Render(PD::Li::Drawlist& list);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PD::Li::Font* pFont = nullptr;
|
||||||
|
};
|
||||||
|
} // namespace Ultra
|
||||||
|
} // namespace PD
|
||||||
+30
-2
@@ -1,6 +1,34 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <pd/common.hpp>
|
#include <pd/common.hpp>
|
||||||
|
|
||||||
PD_API void PD::Log(const std::string& txt) {
|
namespace PD {
|
||||||
std::cout << "[PD] " << txt << std::endl;
|
constexpr const char* pColorNo = "\033[0m";
|
||||||
|
constexpr const char* pColorYellow = "\033[33m";
|
||||||
|
constexpr const char* pColorRed = "\033[31m";
|
||||||
|
static LogLevel pFilter = LogLevel::Info;
|
||||||
|
|
||||||
|
PD_API void LogFilter(LogLevel lvl) { pFilter = lvl; }
|
||||||
|
|
||||||
|
PD_API void Log(const std::string& txt, LogLevel lvl) {
|
||||||
|
if ((int)lvl < (int)pFilter) return;
|
||||||
|
const char* clr = pColorNo;
|
||||||
|
const char* plvl = "INFO";
|
||||||
|
switch (lvl) {
|
||||||
|
case PD::LogLevel::None:
|
||||||
|
case PD::LogLevel::Info:
|
||||||
|
clr = pColorNo;
|
||||||
|
plvl = "INFO";
|
||||||
|
break;
|
||||||
|
case PD::LogLevel::Warning:
|
||||||
|
clr = pColorYellow;
|
||||||
|
plvl = "WARNING";
|
||||||
|
break;
|
||||||
|
case PD::LogLevel::Error:
|
||||||
|
clr = pColorRed;
|
||||||
|
plvl = "ERROR";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << clr << "[PD][" << plvl << "] " << txt << pColorNo << std::endl;
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
@@ -22,15 +22,30 @@ SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pd/core/timetrace.hpp>
|
#include <pd/core/timetrace.hpp>
|
||||||
|
#include <pd/drivers/os.hpp>
|
||||||
|
|
||||||
namespace PD::TT {
|
namespace PD::TT {
|
||||||
|
static TraceMap pTraces;
|
||||||
|
|
||||||
|
PD_API TraceMap& GetTraceMap() { return pTraces; }
|
||||||
|
|
||||||
|
PD_API TT::Res& GetTraceRef(const std::string& id) {
|
||||||
|
if (!pTraces.count(id)) {
|
||||||
|
pTraces[id] = TT::Res();
|
||||||
|
pTraces[id].SetID(id);
|
||||||
|
}
|
||||||
|
return pTraces[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API bool TraceExist(const std::string& id) { return pTraces.count(id); }
|
||||||
|
|
||||||
PD_API void Beg(const std::string& id) {
|
PD_API void Beg(const std::string& id) {
|
||||||
/*auto trace = os.GetTraceRef(id);
|
auto& trace = GetTraceRef(id);
|
||||||
trace->SetStart(os.GetNanoTime());*/
|
trace.SetStart(PD::Os::GetTimeNano());
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void End(const std::string& id) {
|
PD_API void End(const std::string& id) {
|
||||||
/*auto trace = os.GetTraceRef(id);
|
auto& trace = GetTraceRef(id);
|
||||||
trace->SetEnd(os.GetNanoTime());*/
|
trace.SetEnd(PD::Os::GetTimeNano());
|
||||||
}
|
}
|
||||||
} // namespace PD::TT
|
} // namespace PD::TT
|
||||||
@@ -8,7 +8,7 @@ PD_API GfxDriver::GfxDriver(std::string_view name) : DriverInterface(name) {}
|
|||||||
|
|
||||||
PD_API GfxDriver::~GfxDriver() {
|
PD_API GfxDriver::~GfxDriver() {
|
||||||
if (pTextureRegestry.size()) {
|
if (pTextureRegestry.size()) {
|
||||||
PDLOG("GfxDriver: {} is still holding {} texture{}!", GetName(),
|
PDERR("GfxDriver: {} is still holding {} texture{}!", GetName(),
|
||||||
pTextureRegestry.size(), (pTextureRegestry.size() == 1 ? "" : "s"));
|
pTextureRegestry.size(), (pTextureRegestry.size() == 1 ? "" : "s"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,9 +25,14 @@ PD_API void GfxDriver::SetViewPort(int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PD_API void GfxDriver::Reset() {
|
PD_API void GfxDriver::Reset() {
|
||||||
|
CountIndices = CurrentIndex;
|
||||||
|
CountVertices = CurrentVertex;
|
||||||
CurrentVertex = 0;
|
CurrentVertex = 0;
|
||||||
CurrentIndex = 0;
|
CurrentIndex = 0;
|
||||||
ResetPools();
|
CountCommands = pCountCommands;
|
||||||
|
CountDrawcalls = pCountDrawcalls;
|
||||||
|
pCountCommands = 0;
|
||||||
|
pCountDrawcalls = 0;
|
||||||
SysReset();
|
SysReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +45,7 @@ PD_API void GfxDriver::UnregisterTexture(const Li::Texture& tex) {
|
|||||||
pTextureRegestry.erase(pTextureRegestry.find(tex.GetID()));
|
pTextureRegestry.erase(pTextureRegestry.find(tex.GetID()));
|
||||||
PDLOG("GfxDriver: Texture {{ {} }} has been deleted!", tex);
|
PDLOG("GfxDriver: Texture {{ {} }} has been deleted!", tex);
|
||||||
} else {
|
} else {
|
||||||
PDLOG("GfxDriver: WARNING Texture {{ {} }} does not exist in regestry!",
|
PDWARN("GfxDriver: WARNING Texture {{ {} }} does not exist in regestry!",
|
||||||
tex);
|
tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#include <pd/drivers/hid.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
PD_API std::unique_ptr<HidDriver> Hid::driver;
|
||||||
|
|
||||||
|
PD_API HidDriver::HidDriver(std::string_view name) : DriverInterface(name) {}
|
||||||
|
|
||||||
|
PD_API HidDriver::~HidDriver() {}
|
||||||
|
|
||||||
|
PD_API bool HidDriver::IsEvent(Event e, HidInternal::GamepadKey keys) {
|
||||||
|
return pGamepadEvents[0][e] & keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API bool HidDriver::IsEvent(Event e, HidInternal::Keyboard::Key keys) {
|
||||||
|
return pKeyboardEvents[0][e].Has(keys);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Todo: Keyboard support
|
||||||
|
*/
|
||||||
|
PD_API void HidDriver::SwapTab() {
|
||||||
|
auto tkd = pGamepadEvents[1][Event::Down];
|
||||||
|
auto tkh = pGamepadEvents[1][Event::Held];
|
||||||
|
auto tku = pGamepadEvents[1][Event::Up];
|
||||||
|
pGamepadEvents[1][Event::Down] = pGamepadEvents[0][Event::Down];
|
||||||
|
pGamepadEvents[1][Event::Held] = pGamepadEvents[0][Event::Held];
|
||||||
|
pGamepadEvents[1][Event::Up] = pGamepadEvents[0][Event::Up];
|
||||||
|
pGamepadEvents[0][Event::Down] = tkd;
|
||||||
|
pGamepadEvents[0][Event::Held] = tkh;
|
||||||
|
pGamepadEvents[0][Event::Up] = tku;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this func has no verride, still clear the stats
|
||||||
|
* cause if they are empty this leads to a crash
|
||||||
|
*/
|
||||||
|
PD_API void HidDriver::Update() {
|
||||||
|
// Clear States
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
pGamepadEvents[i][Event::Down] = 0;
|
||||||
|
pGamepadEvents[i][Event::Held] = 0;
|
||||||
|
pGamepadEvents[i][Event::Up] = 0;
|
||||||
|
for (auto& it : pKeyboardEvents[i]) {
|
||||||
|
it.second = 0; // ? why was this Event_Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pMouse[1] = pMouse[0]; // cycle here
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <pd/drivers/os.hpp>
|
#include <pd/drivers/os.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
PD_API std::unique_ptr<OsDriver> Os::driver;
|
PD_API std::unique_ptr<OsDriver> Os::driver = std::make_unique<OsDriver>();
|
||||||
|
|
||||||
PD_API u64 OsDriver::GetTime() const {
|
PD_API u64 OsDriver::GetTime() const {
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
@@ -10,7 +10,7 @@ PD_API u64 OsDriver::GetTime() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PD_API u64 OsDriver::GetTimeNano() const {
|
PD_API u64 OsDriver::GetTimeNano() const {
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||||
std::chrono::steady_clock::now().time_since_epoch())
|
std::chrono::steady_clock::now().time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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/image/convert.hpp>
|
||||||
|
|
||||||
|
namespace PD::ImgConvert {
|
||||||
|
|
||||||
|
PD_API void RGB24toRGBA32(std::vector<u8>& out, const std::vector<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_API void RGB32toRGBA24(std::vector<u8>& out, const std::vector<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_API void Reverse32(std::vector<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_API void ReverseBuf(std::vector<u8>& buf, size_t bpp, int w, int h) {
|
||||||
|
std::vector<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
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
#include <pd/image/convert.hpp>
|
||||||
|
#include <pd/image/image.hpp>
|
||||||
|
|
||||||
|
#if defined(PD_INCLUDE_STB_IMAGE)
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#endif
|
||||||
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
PD_API Image::Image() {}
|
||||||
|
|
||||||
|
PD_API Image::Image(const std::string& path) { Load(path); }
|
||||||
|
|
||||||
|
PD_API Image::Image(const std::vector<u8>& buf) { Load(buf); }
|
||||||
|
|
||||||
|
PD_API Image::Image(const std::vector<u8>& pixels, int w, int h, int bpp) {
|
||||||
|
Copy(pixels, w, h, bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API Image::~Image() {}
|
||||||
|
|
||||||
|
PD_API void Image::Load(const u8* buf, size_t size) {
|
||||||
|
int w = 0, h = 0, c = 0;
|
||||||
|
u8* img = stbi_load_from_memory(buf, size, &w, &h, &c, 4);
|
||||||
|
if (c == 3) {
|
||||||
|
stbi_image_free(img);
|
||||||
|
img = stbi_load_from_memory(buf, size, &w, &h, &c, 3);
|
||||||
|
pFormat = Format::RGB;
|
||||||
|
}
|
||||||
|
pData.assign(img, img + (w * h * c));
|
||||||
|
pSize = ivec2(w, h);
|
||||||
|
stbi_image_free(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Image::Load(const std::string& path) {
|
||||||
|
int w = 0, h = 0, c = 0;
|
||||||
|
u8* img = stbi_load(path.c_str(), &w, &h, &c, 4);
|
||||||
|
if (c == 3) {
|
||||||
|
stbi_image_free(img);
|
||||||
|
img = stbi_load(path.c_str(), &w, &h, &c, 3);
|
||||||
|
pFormat = Format::RGB;
|
||||||
|
}
|
||||||
|
pData.assign(img, img + (w * h * c));
|
||||||
|
pSize = ivec2(w, h);
|
||||||
|
stbi_image_free(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Image::Load(const std::vector<u8>& buf) {
|
||||||
|
Load(buf.data(), buf.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Image::Copy(const std::vector<u8>& pixels, int w, int h, int bpp) {
|
||||||
|
pData = pixels;
|
||||||
|
pSize = ivec2(w, h);
|
||||||
|
pFormat = GuessFmtFromBpp(bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Image::Convert(Format dst) {
|
||||||
|
if (pFormat == dst) {
|
||||||
|
return;
|
||||||
|
} else if (pFormat == Format::RGB && dst == Format::BGR) {
|
||||||
|
ImgConvert::ReverseBuf(pData, 3, pSize.x, pSize.y);
|
||||||
|
pFormat = Format::BGR;
|
||||||
|
} else if (pFormat == Format::RGB && dst == Format::RGBA) {
|
||||||
|
std::vector<PD::u8> cpy = pData;
|
||||||
|
pData.resize(pSize.x * pSize.y * 4);
|
||||||
|
ImgConvert::RGB24toRGBA32(pData, cpy, pSize.x, pSize.y);
|
||||||
|
pFormat = Format::RGBA;
|
||||||
|
} else if (pFormat == Format::RGBA && dst == Format::RGB) {
|
||||||
|
std::vector<PD::u8> cpy = pData;
|
||||||
|
pData.resize(pSize.x * pSize.y * 3);
|
||||||
|
ImgConvert::RGB32toRGBA24(pData, cpy, pSize.x, pSize.y);
|
||||||
|
pFormat = Format::RGB;
|
||||||
|
} else if (pFormat == Format::RGBA && dst == Format::BGRA) {
|
||||||
|
for (int i = 0; i < (pSize.x * pSize.y * 4); i += 4) {
|
||||||
|
u8 _tmp = pData[i + 0];
|
||||||
|
pData[i + 0] = pData[i + 2];
|
||||||
|
pData[i + 2] = _tmp;
|
||||||
|
}
|
||||||
|
} else if (pFormat == Format::RGBA && dst == Format::RGB565) {
|
||||||
|
Convert(Format::RGB);
|
||||||
|
Convert(Format::RGB565);
|
||||||
|
} else if (pFormat == Format::RGB && dst == Format::RGB565) {
|
||||||
|
auto f = [](u8 r, u8 g, u8 b) -> u16 {
|
||||||
|
u16 _r = (r >> 3);
|
||||||
|
u16 _g = (g >> 2);
|
||||||
|
u16 _b = (b >> 3);
|
||||||
|
return (_r << 11) | (_g << 5) | _b;
|
||||||
|
};
|
||||||
|
std::vector<PD::u8> cpy = pData;
|
||||||
|
pData.resize(pSize.x * pSize.y * 2);
|
||||||
|
for (int y = 0; y < pSize.x; y++) {
|
||||||
|
for (int x = 0; x < pSize.y; x++) {
|
||||||
|
int src = (y * pSize.x + x) * 3;
|
||||||
|
int dst = (y * pSize.x + x) * 2;
|
||||||
|
u16 new_px = f(cpy[src + 0], cpy[src + 1], cpy[src + 2]);
|
||||||
|
pData[dst + 0] = new_px >> 8;
|
||||||
|
pData[dst + 1] = new_px & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pFormat = Format::RGB565;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API int Image::Format2Bpp(Format fmt) {
|
||||||
|
switch (fmt) {
|
||||||
|
case Format::RGBA:
|
||||||
|
case Format::ABGR:
|
||||||
|
case Format::BGRA:
|
||||||
|
return 4;
|
||||||
|
case Format::BGR:
|
||||||
|
case Format::RGB:
|
||||||
|
return 3;
|
||||||
|
case Format::RGB565:
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API Image::Format Image::GuessFmtFromBpp(int bpp) {
|
||||||
|
/** Only return defaults here */
|
||||||
|
switch (bpp) {
|
||||||
|
case 4:
|
||||||
|
return Format::RGBA;
|
||||||
|
case 3:
|
||||||
|
return Format::RGB;
|
||||||
|
case 2:
|
||||||
|
return Format::RGB565;
|
||||||
|
default:
|
||||||
|
return Format::RGBA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Image::Flip(bool hz, bool vt) {
|
||||||
|
auto bpp = Format2Bpp(pFormat);
|
||||||
|
int rlen = pSize.x * bpp; // calculate as less as possible
|
||||||
|
if (hz) {
|
||||||
|
for (int j = 0; j < pSize.y; j++) {
|
||||||
|
int roff = j * rlen;
|
||||||
|
for (int i = 0; i < pSize.x / 2; i++) {
|
||||||
|
int src = roff + (i * bpp);
|
||||||
|
int dst = roff + (pSize.x - 1 - i) * bpp;
|
||||||
|
for (int k = 0; k < bpp; k++) {
|
||||||
|
PD::u8 tmp = pData[dst + k];
|
||||||
|
pData[dst + k] = pData[src + k];
|
||||||
|
pData[src + k] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vt) {
|
||||||
|
for (int j = 0; j < pSize.y / 2; j++) {
|
||||||
|
int rsrc = j * rlen;
|
||||||
|
int rdst = (pSize.y - 1 - j) * rlen;
|
||||||
|
for (int i = 0; i < rlen; i++) { // swap the entire row
|
||||||
|
PD::u8 tmp = pData[rdst + i];
|
||||||
|
pData[rdst + i] = pData[rsrc + i];
|
||||||
|
pData[rsrc + i] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
#include <pd/drivers/gfx.hpp>
|
||||||
|
#include <pd/lithium/command.hpp>
|
||||||
|
#include <pd/lithium/pools.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Li {
|
||||||
|
|
||||||
|
void Command::Reserve(size_t vtx, size_t idx) {
|
||||||
|
auto& vpool = GetVertexPool();
|
||||||
|
auto& ipool = GetIndexPool();
|
||||||
|
if (VertexCountMax == 0) {
|
||||||
|
FirstVertex = vpool.size();
|
||||||
|
vpool.Allocate(vtx);
|
||||||
|
VertexCountMax = vtx;
|
||||||
|
} else {
|
||||||
|
if (vpool.size() == FirstVertex + VertexCountMax) {
|
||||||
|
vpool.Allocate(vtx);
|
||||||
|
VertexCountMax += vtx;
|
||||||
|
} else {
|
||||||
|
size_t tmp = FirstVertex;
|
||||||
|
FirstVertex = vpool.size();
|
||||||
|
vpool.Allocate(VertexCountMax + vtx);
|
||||||
|
for (size_t i = 0; i < VertexCount; i++) {
|
||||||
|
vpool[FirstVertex + i] = vpool[tmp + i];
|
||||||
|
}
|
||||||
|
VertexCountMax += vtx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IndexCountMax == 0) {
|
||||||
|
FirstIndex = ipool.size();
|
||||||
|
ipool.Allocate(idx);
|
||||||
|
IndexCountMax = idx;
|
||||||
|
} else {
|
||||||
|
if (ipool.size() == FirstIndex + IndexCountMax) {
|
||||||
|
ipool.Allocate(idx);
|
||||||
|
IndexCountMax += idx;
|
||||||
|
} else {
|
||||||
|
size_t tmp = FirstIndex;
|
||||||
|
FirstIndex = ipool.size();
|
||||||
|
ipool.Allocate(IndexCountMax + idx);
|
||||||
|
for (size_t i = 0; i < IndexCount; i++) {
|
||||||
|
ipool[FirstIndex + i] = ipool[tmp + i];
|
||||||
|
}
|
||||||
|
IndexCountMax += idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command::Reset() {
|
||||||
|
Layer = 0;
|
||||||
|
Tex = 0;
|
||||||
|
SDF = false;
|
||||||
|
FirstIndex = 0;
|
||||||
|
FirstVertex = 0;
|
||||||
|
IndexCount = 0;
|
||||||
|
VertexCount = 0;
|
||||||
|
VertexCountMax = 0;
|
||||||
|
IndexCountMax = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command& Command::Add(const Vertex& vtx) {
|
||||||
|
if (VertexCount < VertexCountMax) {
|
||||||
|
GetVertexPool()[FirstVertex + VertexCount++] = vtx;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Command& Command::Add(u16 idx) {
|
||||||
|
if (IndexCount < IndexCountMax) {
|
||||||
|
GetIndexPool()[FirstIndex + IndexCount++] =
|
||||||
|
static_cast<u16>(VertexCount + idx);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Command& Command::Add(u16 a, u16 b, u16 c) {
|
||||||
|
if (IndexCount + 3 <= IndexCountMax) {
|
||||||
|
auto& ip = GetIndexPool();
|
||||||
|
size_t idx = FirstIndex + IndexCount;
|
||||||
|
ip[idx + 0] = static_cast<u16>(VertexCount + a);
|
||||||
|
ip[idx + 1] = static_cast<u16>(VertexCount + b);
|
||||||
|
ip[idx + 2] = static_cast<u16>(VertexCount + c);
|
||||||
|
IndexCount += 3;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Li
|
||||||
|
} // namespace PD
|
||||||
+140
-33
@@ -1,5 +1,8 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
#include <pd/drivers/gfx.hpp>
|
#include <pd/drivers/gfx.hpp>
|
||||||
#include <pd/lithium/drawlist.hpp>
|
#include <pd/lithium/drawlist.hpp>
|
||||||
|
#include <pd/lithium/formatters.hpp>
|
||||||
#include <pd/lithium/math.hpp>
|
#include <pd/lithium/math.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
@@ -8,22 +11,45 @@ PD_API Drawlist::Drawlist() { Clear(); }
|
|||||||
|
|
||||||
PD_API Drawlist::~Drawlist() { Clear(); }
|
PD_API Drawlist::~Drawlist() { Clear(); }
|
||||||
|
|
||||||
PD_API void Drawlist::Merge(Drawlist& other) {}
|
PD_API void Drawlist::Merge(Drawlist& other) {
|
||||||
|
size_t start = pCommands.size();
|
||||||
|
pCommands.AppendMove(other.pCommands);
|
||||||
|
for (size_t i = start; i < pCommands.size(); i++) {
|
||||||
|
pCommands[i].Layer += this->pCurrentLayer;
|
||||||
|
}
|
||||||
|
other.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Copy(Drawlist& other) {}
|
PD_API void Drawlist::Copy(Drawlist& other) {
|
||||||
|
int start = pCommands.size();
|
||||||
|
pCommands.AppendCopy(other.pCommands);
|
||||||
|
for (size_t i = start; i < pCommands.size(); i++) {
|
||||||
|
pCommands[i].Layer += this->pCurrentLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Optimize() {}
|
PD_API void Drawlist::Optimize() {
|
||||||
|
if (pCommands.size() <= 1) return;
|
||||||
|
std::stable_sort(pCommands.begin(), pCommands.end(),
|
||||||
|
[](const Command& a, const Command& b) {
|
||||||
|
if (a.Layer != b.Layer) return a.Layer < b.Layer;
|
||||||
|
if (a.SDF != b.SDF) return a.SDF < b.SDF;
|
||||||
|
return a.Tex < b.Tex;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::Clear() {
|
PD_API void Drawlist::Clear() {
|
||||||
UnbindTexture();
|
UnbindTexture();
|
||||||
pPath.Reset();
|
pPath.ResetFast();
|
||||||
pVertices.Reset();
|
pCommands.NoReset();
|
||||||
pIndices.Reset();
|
pCurrentLayer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Command Allocation */
|
/** Command Allocation */
|
||||||
PD_API Command& Drawlist::NewCommand() {
|
PD_API Command& Drawlist::NewCommand() {
|
||||||
auto cmd = pCommands.Allocate(1);
|
auto cmd = pCommands.Allocate(1);
|
||||||
|
cmd->Reset();
|
||||||
|
cmd->Layer = pCurrentLayer;
|
||||||
cmd->Tex = pCurrentTexture.GetID();
|
cmd->Tex = pCurrentTexture.GetID();
|
||||||
return *cmd;
|
return *cmd;
|
||||||
}
|
}
|
||||||
@@ -31,16 +57,23 @@ PD_API Command& Drawlist::NewCommand() {
|
|||||||
PD_API void Drawlist::BindTexture(const Texture& tex) { pCurrentTexture = tex; }
|
PD_API void Drawlist::BindTexture(const Texture& tex) { pCurrentTexture = tex; }
|
||||||
|
|
||||||
/** Path API */
|
/** Path API */
|
||||||
PD_API void Drawlist::PathStroke(u32 color, int t, LiDrawFlags flags) {
|
PD_API void Drawlist::PathStroke(const PD::Color& color, int t,
|
||||||
|
LiDrawFlags flags) {
|
||||||
DrawPolyLine(pPath, color, flags, t);
|
DrawPolyLine(pPath, color, flags, t);
|
||||||
PathClear();
|
PathClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::PathFill(u32 color) {
|
PD_API void Drawlist::PathFill(const PD::Color& color) {
|
||||||
DrawConvexPolyFilled(pPath, color);
|
DrawConvexPolyFilled(pPath, color);
|
||||||
PathClear();
|
PathClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_API void Drawlist::PathFillGradient(const PD::Color& a, const PD::Color& b,
|
||||||
|
float rad) {
|
||||||
|
DrawConvexPolyFilled(pPath, a, b, rad);
|
||||||
|
PathClear();
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::PathArcToN(const fvec2& c, float r, float amin,
|
PD_API void Drawlist::PathArcToN(const fvec2& c, float r, float amin,
|
||||||
float amax, int s) {
|
float amax, int s) {
|
||||||
// Path.push_back(c);
|
// Path.push_back(c);
|
||||||
@@ -65,14 +98,15 @@ PD_API void Drawlist::PathFastArcToN(const fvec2& c, float r, float amin,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::PathRect(const fvec2& tl, const fvec2& br, float r) {
|
PD_API void Drawlist::PathRect(const fvec2& tl, const fvec2& br,
|
||||||
if (r == 0.f) {
|
float rounding) {
|
||||||
|
if (rounding == 0.f) {
|
||||||
PathAdd(tl);
|
PathAdd(tl);
|
||||||
PathAdd(vec2(br.x, tl.y));
|
PathAdd(vec2(br.x, tl.y));
|
||||||
PathAdd(br);
|
PathAdd(br);
|
||||||
PathAdd(vec2(tl.x, br.y));
|
PathAdd(vec2(tl.x, br.y));
|
||||||
} else {
|
} else {
|
||||||
float r = std::min({r, (br.x - tl.x) * 0.5f, (br.y - tl.y) * 0.5f});
|
float r = std::min({rounding, (br.x - tl.x) * 0.5f, (br.y - tl.y) * 0.5f});
|
||||||
/** Calculate Optimal segment count automatically */
|
/** Calculate Optimal segment count automatically */
|
||||||
float corner = M_PI * 0.5f;
|
float corner = M_PI * 0.5f;
|
||||||
int segments = std::max(3, int(std::ceil(corner / (6.0f * M_PI / 180.0f))));
|
int segments = std::max(3, int(std::ceil(corner / (6.0f * M_PI / 180.0f))));
|
||||||
@@ -97,15 +131,15 @@ PD_API void Drawlist::PathRect(const fvec2& tl, const fvec2& br, float r) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::PathRectEx(const fvec2& tl, const fvec2& br, float r,
|
PD_API void Drawlist::PathRectEx(const fvec2& tl, const fvec2& br,
|
||||||
LiPathRectFlags flags) {
|
float rounding, LiPathRectFlags flags) {
|
||||||
if (r == 0.f) {
|
if (rounding == 0.f) {
|
||||||
PathAdd(tl);
|
PathAdd(tl);
|
||||||
PathAdd(vec2(br.x, tl.y));
|
PathAdd(vec2(br.x, tl.y));
|
||||||
PathAdd(br);
|
PathAdd(br);
|
||||||
PathAdd(vec2(tl.x, br.y));
|
PathAdd(vec2(tl.x, br.y));
|
||||||
} else {
|
} else {
|
||||||
float r = std::min({r, (br.x - tl.x) * 0.5f, (br.y - tl.y) * 0.5f});
|
float r = std::min({rounding, (br.x - tl.x) * 0.5f, (br.y - tl.y) * 0.5f});
|
||||||
/** Calculate Optimal segment count automatically */
|
/** Calculate Optimal segment count automatically */
|
||||||
float corner = M_PI * 0.5f;
|
float corner = M_PI * 0.5f;
|
||||||
int segments = std::max(3, int(std::ceil(corner / (6.0f * M_PI / 180.0f))));
|
int segments = std::max(3, int(std::ceil(corner / (6.0f * M_PI / 180.0f))));
|
||||||
@@ -148,20 +182,21 @@ PD_API void Drawlist::PathRectEx(const fvec2& tl, const fvec2& br, float r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Drawing functions */
|
/** Drawing functions */
|
||||||
PD_API void Drawlist::DrawRect(const fvec2& pos, const fvec2& size, u32 color,
|
PD_API void Drawlist::DrawRect(const fvec2& pos, const fvec2& size,
|
||||||
int t) {
|
const PD::Color& color, int t) {
|
||||||
PathRect(pos, pos + size);
|
PathRect(pos, pos + size);
|
||||||
PathStroke(color, t, LiDrawFlags_Close);
|
PathStroke(color, t, LiDrawFlags_Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawRectFilled(const fvec2& pos, const fvec2& size,
|
PD_API void Drawlist::DrawRectFilled(const fvec2& pos, const fvec2& size,
|
||||||
u32 color) {
|
const PD::Color& color) {
|
||||||
PathRect(pos, pos + size);
|
PathRect(pos, pos + size);
|
||||||
PathFill(color);
|
PathFill(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawTriangle(const fvec2& a, const fvec2& b,
|
PD_API void Drawlist::DrawTriangle(const fvec2& a, const fvec2& b,
|
||||||
const fvec2& c, u32 color, int t) {
|
const fvec2& c, const PD::Color& color,
|
||||||
|
int t) {
|
||||||
PathAdd(a);
|
PathAdd(a);
|
||||||
PathAdd(b);
|
PathAdd(b);
|
||||||
PathAdd(c);
|
PathAdd(c);
|
||||||
@@ -169,15 +204,17 @@ PD_API void Drawlist::DrawTriangle(const fvec2& a, const fvec2& b,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawTriangleFilled(const fvec2& a, const fvec2& b,
|
PD_API void Drawlist::DrawTriangleFilled(const fvec2& a, const fvec2& b,
|
||||||
const fvec2& c, u32 color) {
|
const fvec2& c,
|
||||||
|
const PD::Color& color) {
|
||||||
PathAdd(a);
|
PathAdd(a);
|
||||||
PathAdd(b);
|
PathAdd(b);
|
||||||
PathAdd(c);
|
PathAdd(c);
|
||||||
PathFill(color);
|
PathFill(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawCircle(const fvec2& center, float rad, u32 color,
|
PD_API void Drawlist::DrawCircle(const fvec2& center, float rad,
|
||||||
int num_segments, int t) {
|
const PD::Color& color, int num_segments,
|
||||||
|
int t) {
|
||||||
if (num_segments <= 0) {
|
if (num_segments <= 0) {
|
||||||
// Auto Segment
|
// Auto Segment
|
||||||
} else {
|
} else {
|
||||||
@@ -189,7 +226,8 @@ PD_API void Drawlist::DrawCircle(const fvec2& center, float rad, u32 color,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawCircleFilled(const fvec2& center, float rad,
|
PD_API void Drawlist::DrawCircleFilled(const fvec2& center, float rad,
|
||||||
u32 color, int num_segments) {
|
const PD::Color& color,
|
||||||
|
int num_segments) {
|
||||||
if (num_segments <= 0) {
|
if (num_segments <= 0) {
|
||||||
// Auto Segment
|
// Auto Segment
|
||||||
} else {
|
} else {
|
||||||
@@ -199,21 +237,37 @@ PD_API void Drawlist::DrawCircleFilled(const fvec2& center, float rad,
|
|||||||
PathFill(color);
|
PathFill(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawText(const fvec2& p, const char* text, u32 color) {}
|
PD_API void Drawlist::DrawText(const fvec2& p, const char* text,
|
||||||
|
const PD::Color& color) {
|
||||||
|
if (!pFont) return;
|
||||||
|
pFont->CmdTextEx(*this, p, color, pFontScale, text);
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawTextEx(const fvec2& p, const char* text, u32 color,
|
PD_API void Drawlist::DrawTextEx(const fvec2& p, const char* text,
|
||||||
LiTextFlags flags, const fvec2& box) {}
|
const PD::Color& color, LiTextFlags flags,
|
||||||
|
const fvec2& box) {
|
||||||
|
if (!pFont) return;
|
||||||
|
pFont->CmdTextEx(*this, p, color, pFontScale, text, flags, box);
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawPolyLine(const Pool<fvec2>& points, u32 color,
|
PD_API void Drawlist::DrawLine(const fvec2& a, const fvec2& b,
|
||||||
LiDrawFlags flags, int t) {
|
const PD::Color& color, int thickness) {
|
||||||
|
this->PathAdd(a);
|
||||||
|
this->PathAdd(b);
|
||||||
|
this->PathStroke(color, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Drawlist::DrawPolyLine(const Pool<fvec2>& points,
|
||||||
|
const PD::Color& color, LiDrawFlags flags,
|
||||||
|
int t) {
|
||||||
if (points.size() < 2) {
|
if (points.size() < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UnbindTexture();
|
UnbindTexture();
|
||||||
auto& cmd = NewCommand();
|
auto& cmd = NewCommand();
|
||||||
bool close = (flags & (1 << 0));
|
bool close = (flags & LiDrawFlags_Close);
|
||||||
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 & LiDrawFlags_AA) {
|
||||||
// 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
|
||||||
@@ -226,7 +280,7 @@ PD_API void Drawlist::DrawPolyLine(const Pool<fvec2>& points, u32 color,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::DrawConvexPolyFilled(const Pool<fvec2>& points,
|
PD_API void Drawlist::DrawConvexPolyFilled(const Pool<fvec2>& points,
|
||||||
u32 color) {
|
const PD::Color& color) {
|
||||||
if (points.size() < 3) {
|
if (points.size() < 3) {
|
||||||
return; // Need at least three points
|
return; // Need at least three points
|
||||||
}
|
}
|
||||||
@@ -264,8 +318,60 @@ PD_API void Drawlist::DrawConvexPolyFilled(const Pool<fvec2>& points,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_API void Drawlist::DrawConvexPolyFilled(const Pool<fvec2>& points,
|
||||||
|
const PD::Color& a,
|
||||||
|
const PD::Color b, float rad) {
|
||||||
|
if (points.size() < 3) {
|
||||||
|
return; // Need at least three points
|
||||||
|
}
|
||||||
|
|
||||||
|
fvec2 dir = fvec2(std::cos(rad), std::sin(rad));
|
||||||
|
// Support for Custom Textures (UV calculation)
|
||||||
|
float minX = points[0].x, minY = points[0].y;
|
||||||
|
float maxX = minX, maxY = minY;
|
||||||
|
// Check for the max and min Positions
|
||||||
|
for (const auto& it : points) {
|
||||||
|
if (it.x < minX) minX = it.x;
|
||||||
|
if (it.y < minY) minY = it.y;
|
||||||
|
if (it.x > maxX) maxX = it.x;
|
||||||
|
if (it.y > maxY) maxY = it.y;
|
||||||
|
}
|
||||||
|
// Get Short defines for UV
|
||||||
|
// (Bottom Right is not required)
|
||||||
|
auto uv_tl = pCurrentTexture.GetUV().TopLeft();
|
||||||
|
auto uv_tr = pCurrentTexture.GetUV().TopRight();
|
||||||
|
auto uv_bl = pCurrentTexture.GetUV().BotLeft();
|
||||||
|
|
||||||
|
// Gradient
|
||||||
|
float tmin = std::numeric_limits<float>::max();
|
||||||
|
float tmax = std::numeric_limits<float>::lowest();
|
||||||
|
for (const auto& p : points) {
|
||||||
|
float t = p.x * dir.x + p.y * dir.y;
|
||||||
|
if (t < tmin) tmin = t;
|
||||||
|
if (t > tmax) tmax = t;
|
||||||
|
}
|
||||||
|
// potential div0
|
||||||
|
float irange = (tmax != tmin) ? (1.0f / (tmax - tmin)) : 0.0f;
|
||||||
|
// Command building (oder so)
|
||||||
|
auto& cmd = NewCommand();
|
||||||
|
cmd.Reserve(points.size(), (points.size() - 2) * 3);
|
||||||
|
// Render
|
||||||
|
for (int i = 2; i < (int)points.size(); i++) {
|
||||||
|
cmd.Add(0, i, i - 1);
|
||||||
|
}
|
||||||
|
// Why was this for loop not used in normal Convex Poly filled???
|
||||||
|
for (auto& it : points) {
|
||||||
|
// Calculate U and V coords
|
||||||
|
float u = uv_tl.x + ((it.x - minX) / (maxX - minX)) * (uv_tr.x - uv_tl.x);
|
||||||
|
float v = uv_tl.y + ((it.y - minY) / (maxY - minY)) * (uv_bl.y - uv_tl.y);
|
||||||
|
float t = it.x * dir.x + it.y * dir.y;
|
||||||
|
cmd.Add(Vertex(it, fvec2(u, v), PD::Color(a).Lerp(b, (t - tmin) * irange)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::PrimQuad(Command& cmd, const Rect& quad, const Rect& uv,
|
PD_API void Drawlist::PrimQuad(Command& cmd, const Rect& quad, const Rect& uv,
|
||||||
u32 color) {
|
const PD::Color& color) {
|
||||||
|
cmd.Reserve(4, 6);
|
||||||
cmd.Add(2, 1, 0);
|
cmd.Add(2, 1, 0);
|
||||||
cmd.Add(3, 2, 0);
|
cmd.Add(3, 2, 0);
|
||||||
cmd.Add(Vertex(quad.TopLeft(), uv.TopLeft(), color));
|
cmd.Add(Vertex(quad.TopLeft(), uv.TopLeft(), color));
|
||||||
@@ -275,7 +381,8 @@ PD_API void Drawlist::PrimQuad(Command& cmd, const Rect& quad, const Rect& uv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PD_API void Drawlist::PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
|
PD_API void Drawlist::PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
|
||||||
const fvec2& c, u32 color) {
|
const fvec2& c, const PD::Color& color) {
|
||||||
|
cmd.Reserve(3, 3);
|
||||||
cmd.Add(2, 1, 0);
|
cmd.Add(2, 1, 0);
|
||||||
cmd.Add(Vertex(a, vec2(0.f, 1.f), color));
|
cmd.Add(Vertex(a, vec2(0.f, 1.f), color));
|
||||||
cmd.Add(Vertex(b, vec2(1.f, 1.f), color));
|
cmd.Add(Vertex(b, vec2(1.f, 1.f), color));
|
||||||
|
|||||||
@@ -0,0 +1,349 @@
|
|||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/drivers/gfx.hpp>
|
||||||
|
#include <pd/lithium/drawlist.hpp>
|
||||||
|
#include <pd/lithium/font.hpp>
|
||||||
|
#include <pd/lithium/math.hpp>
|
||||||
|
|
||||||
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
#include <stb_truetype.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace Li {
|
||||||
|
PD_API void Font::LoadTTF(const std::string& path, int px_height,
|
||||||
|
LiFontFlags flags) {
|
||||||
|
/**
|
||||||
|
* Just use LoadFile2Mem which looks way cleaner
|
||||||
|
* and helps not having the font loading code twice
|
||||||
|
* when adding LoadTTF with mem support
|
||||||
|
*/
|
||||||
|
PDLOG("Font: Loading {}...", path);
|
||||||
|
TT::Scope st("LI_LoadTTF_" + path);
|
||||||
|
auto font = PD::IO::LoadFile2Mem(path);
|
||||||
|
PDLOG("Font Size: {}", PD::Strings::FormatBytes(font.size()));
|
||||||
|
LoadTTF(font, px_height, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height,
|
||||||
|
LiFontFlags flags) {
|
||||||
|
/**
|
||||||
|
* Some additional Info:
|
||||||
|
* Removed the stbtt get bitmapbox as we dont need to place
|
||||||
|
* the glyps nicely in the tex. next step would be using the free
|
||||||
|
* space on the y axis to get mor glyphs inside
|
||||||
|
*/
|
||||||
|
pFlags = flags;
|
||||||
|
PixelHeight = px_height;
|
||||||
|
int texszs = PD::Bits::GetPow2(px_height * 16);
|
||||||
|
if (texszs > 1024) {
|
||||||
|
texszs = 1024; // Max size
|
||||||
|
}
|
||||||
|
|
||||||
|
stbtt_fontinfo inf;
|
||||||
|
if (!stbtt_InitFont(&inf, data.data(), 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float scale = stbtt_ScaleForPixelHeight(&inf, PixelHeight);
|
||||||
|
|
||||||
|
int ascent, descent, lineGap;
|
||||||
|
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
||||||
|
int baseline = static_cast<int>(ascent * scale);
|
||||||
|
|
||||||
|
float mono_advance = 0.f;
|
||||||
|
if (IsMonospace()) {
|
||||||
|
int a, l;
|
||||||
|
int rgi = stbtt_FindGlyphIndex(&inf, 'W');
|
||||||
|
if (rgi == 0) rgi = stbtt_FindGlyphIndex(&inf, '0');
|
||||||
|
if (rgi != 0) {
|
||||||
|
stbtt_GetGlyphHMetrics(&inf, rgi, &a, &l);
|
||||||
|
mono_advance = a * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache to not render same codepoint tex twice
|
||||||
|
std::map<u32, int> buf_cache;
|
||||||
|
|
||||||
|
std::vector<u8> font_tex(texszs * texszs, 0);
|
||||||
|
fvec2 off;
|
||||||
|
|
||||||
|
bool empty = true;
|
||||||
|
|
||||||
|
std::vector<std::pair<u32, u32>> ranges = {
|
||||||
|
{0x0020, 0x007E}, // ASCII
|
||||||
|
{0x00A0, 0x00FF}, // LATIN-1
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& it : ranges) {
|
||||||
|
for (u32 ii = it.first; ii <= it.second; ii++) {
|
||||||
|
int gi = stbtt_FindGlyphIndex(&inf, ii);
|
||||||
|
if (gi == 0) continue;
|
||||||
|
|
||||||
|
int advance, lsb;
|
||||||
|
stbtt_GetGlyphHMetrics(&inf, gi, &advance, &lsb);
|
||||||
|
float sadvance = advance * scale;
|
||||||
|
float final_advance = sadvance;
|
||||||
|
float center_offset = 0.f;
|
||||||
|
|
||||||
|
if (IsMonospace() && mono_advance > 0.f) {
|
||||||
|
final_advance = mono_advance;
|
||||||
|
center_offset = (mono_advance - sadvance) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stbtt_IsGlyphEmpty(&inf, gi)) {
|
||||||
|
Codepoint c;
|
||||||
|
c.AdvanceX = final_advance;
|
||||||
|
c.Size = fvec2(0.f);
|
||||||
|
c.pCodepoint = ii;
|
||||||
|
c.pInvalid = false;
|
||||||
|
CodeMap[ii] = c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = 0, h = 0, xo = 0, yo = 0;
|
||||||
|
unsigned char* bitmap = nullptr;
|
||||||
|
if (IsSDF()) {
|
||||||
|
bitmap = stbtt_GetCodepointSDF(&inf, scale, ii, 5, 128, 255.f / 5.f, &w,
|
||||||
|
&h, &xo, &yo);
|
||||||
|
} else {
|
||||||
|
bitmap =
|
||||||
|
stbtt_GetCodepointBitmap(&inf, scale, scale, ii, &w, &h, &xo, &yo);
|
||||||
|
}
|
||||||
|
if (!bitmap || w <= 0 || h <= 0) {
|
||||||
|
if (bitmap) free(bitmap);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 hashed_map =
|
||||||
|
IO::HashMemory(std::vector<u8>(bitmap, bitmap + (w * h)));
|
||||||
|
if (buf_cache.find(hashed_map) != buf_cache.end()) {
|
||||||
|
Codepoint c = GetCodepoint(buf_cache[hashed_map]);
|
||||||
|
c.pCodepoint = ii;
|
||||||
|
CodeMap[ii] = c;
|
||||||
|
free(bitmap);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
buf_cache[hashed_map] = ii;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next row
|
||||||
|
if (off.x + w > texszs) {
|
||||||
|
off.y += PixelHeight;
|
||||||
|
off.x = 0.0f;
|
||||||
|
}
|
||||||
|
// Bake cause we go out of the tex
|
||||||
|
if (off.y + PixelHeight > texszs) {
|
||||||
|
BakeAndPush(false, font_tex, texszs);
|
||||||
|
off = 0;
|
||||||
|
std::fill(font_tex.begin(), font_tex.end(), 0);
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UVs & Codepoint
|
||||||
|
Codepoint c;
|
||||||
|
fvec4 uvs;
|
||||||
|
// cast the ints to floats and not the floats...
|
||||||
|
// dont know where my mind was when creating the code
|
||||||
|
uvs.x = off.x / static_cast<float>(texszs);
|
||||||
|
uvs.y = off.y / static_cast<float>(texszs);
|
||||||
|
uvs.z = (off.x + w) / static_cast<float>(texszs);
|
||||||
|
uvs.w = (off.y + h) / static_cast<float>(texszs);
|
||||||
|
// Flip if needed
|
||||||
|
if (PD::Gfx::GetFlags() & PDGfxBackendFlags_FlipUV_Y) {
|
||||||
|
uvs.y = 1.f - uvs.y;
|
||||||
|
uvs.w = 1.f - uvs.w;
|
||||||
|
}
|
||||||
|
c.SimpleUV = uvs;
|
||||||
|
c.Tex = pCurrentTex;
|
||||||
|
c.Size = fvec2(w, h);
|
||||||
|
c.Offset = fvec2(xo + center_offset, baseline + yo);
|
||||||
|
c.AdvanceX = final_advance;
|
||||||
|
c.pCodepoint = ii;
|
||||||
|
|
||||||
|
for (int y = 0; y < h; ++y) {
|
||||||
|
for (int x = 0; x < w; ++x) {
|
||||||
|
int map_pos = ((static_cast<int>(off.y) + y) * texszs +
|
||||||
|
(static_cast<int>(off.x) + x));
|
||||||
|
font_tex[map_pos] = bitmap[x + y * w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
empty = false;
|
||||||
|
CodeMap[ii] = c;
|
||||||
|
free(bitmap);
|
||||||
|
|
||||||
|
// offset by 1 (prevents visual glitches i had)
|
||||||
|
off.x += w + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty) {
|
||||||
|
BakeAndPush(true, font_tex, texszs);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 128; i++) {
|
||||||
|
auto r = CodeMap.find(i);
|
||||||
|
if (r == CodeMap.end()) {
|
||||||
|
static Codepoint invalid;
|
||||||
|
invalid.pInvalid = true;
|
||||||
|
pAsciiCache[i] = invalid;
|
||||||
|
} else {
|
||||||
|
pAsciiCache[i] = CodeMap[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Font::LoadDefaultFont(int id, int pixel_height) {}
|
||||||
|
|
||||||
|
PD_API Font::Codepoint& Font::GetCodepoint(u32 c) {
|
||||||
|
if (c < 128) {
|
||||||
|
// Direct Access (~11% improvement)
|
||||||
|
return pAsciiCache[c];
|
||||||
|
}
|
||||||
|
// Check if codepoijt exist or return a static invalid one
|
||||||
|
auto res = CodeMap.find(c);
|
||||||
|
if (res == CodeMap.end()) {
|
||||||
|
static Codepoint invalid;
|
||||||
|
invalid.pInvalid = true;
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
return res->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API fvec2 Font::GetTextBounds(const char* text, float scale) {
|
||||||
|
// Create a temp position and offset as [0, 0]
|
||||||
|
fvec2 res;
|
||||||
|
float x = 0;
|
||||||
|
// Curent Font Scale
|
||||||
|
float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight;
|
||||||
|
float lh = (float)PixelHeight * cfs;
|
||||||
|
U8Iterator it(text);
|
||||||
|
u32 c;
|
||||||
|
while (it.Decode32(c)) {
|
||||||
|
auto cp = GetCodepoint(c);
|
||||||
|
if ((cp.pInvalid && c != L'\n' && c != L'\t' && c != L' ') && c != L'\r')
|
||||||
|
continue;
|
||||||
|
if (c == L'\n') {
|
||||||
|
res.y += lh;
|
||||||
|
res.x = std::max(res.x, x);
|
||||||
|
x = 0.f;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == L'\t') {
|
||||||
|
x += (cp.AdvanceX > 0 ? cp.AdvanceX : 16.f) * 4.f * cfs;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
x += cp.AdvanceX * cfs;
|
||||||
|
}
|
||||||
|
res.x = std::max(res.x, x);
|
||||||
|
res.y += lh;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void PrimTextQuad(Command& cmd, float x, float y, float w, float h,
|
||||||
|
const fvec4& uv, const PD::Color& color) {
|
||||||
|
cmd.Reserve(4, 6);
|
||||||
|
cmd.Add(2, 1, 0);
|
||||||
|
cmd.Add(3, 2, 0);
|
||||||
|
cmd.Add(Vertex(x, y, uv.x, uv.y, color));
|
||||||
|
cmd.Add(Vertex(x + w, y, uv.z, uv.y, color));
|
||||||
|
cmd.Add(Vertex(x + w, y + h, uv.z, uv.w, color));
|
||||||
|
cmd.Add(Vertex(x, y + h, uv.x, uv.w, color));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
|
||||||
|
float scale, const char* text, LiTextFlags flags,
|
||||||
|
const fvec2& box) {
|
||||||
|
fvec2 off;
|
||||||
|
float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight;
|
||||||
|
float lh = (float)PixelHeight * cfs;
|
||||||
|
fvec2 td;
|
||||||
|
fvec2 rpos = pos;
|
||||||
|
fvec2 rbox = box;
|
||||||
|
|
||||||
|
if (flags & (LiTextFlags_AlignMid | LiTextFlags_AlignRight)) {
|
||||||
|
td = GetTextBounds(text, scale);
|
||||||
|
}
|
||||||
|
if (flags & LiTextFlags_AlignMid) rpos = rbox * 0.5 - td * 0.5 + pos;
|
||||||
|
if (flags & LiTextFlags_AlignRight) rpos.x -= td.x;
|
||||||
|
|
||||||
|
U8Iterator it(text);
|
||||||
|
u32 c;
|
||||||
|
Command* cmd = dl.HasCommands() ? &dl.GetLastCommand() : nullptr;
|
||||||
|
while (it.Decode32(c)) {
|
||||||
|
auto cp = GetCodepoint(c);
|
||||||
|
if ((cp.pInvalid && c != L'\n' && c != L'\t' && c != L' ') && c != L'\r')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (c == L'\n') {
|
||||||
|
off.y += lh;
|
||||||
|
off.x = 0.f;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == L'\t') {
|
||||||
|
off.x += (cp.AdvanceX > 0 ? cp.AdvanceX : 16.f) * 4.f * cfs;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp.Size.x > 0 && cp.Size.y > 0) {
|
||||||
|
if (cmd == nullptr || cmd->Tex != Textures[cp.Tex] ||
|
||||||
|
cmd->Layer != dl.GetLayer()) {
|
||||||
|
if (cp.Tex >= Textures.size()) continue;
|
||||||
|
cmd = &dl.NewCommand();
|
||||||
|
cmd->Tex = Textures[cp.Tex];
|
||||||
|
cmd->SDF = IsSDF();
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculating once and using PrimTextQuad to directly push
|
||||||
|
// saves ~42% on raw multiline text draw time 6.3 -> 3.7 ms
|
||||||
|
// and ~25% on the whole frametime 20.3 -> 15.2 ms
|
||||||
|
// tested with Craftus-Next 0.8.0 commit:
|
||||||
|
// 33298ccc276bf996d341710e69ecf05f99c57961
|
||||||
|
float cx = rpos.x + off.x + (cp.Offset.x * cfs);
|
||||||
|
float cy = rpos.y + off.y + (cp.Offset.y * cfs);
|
||||||
|
float cw = cp.Size.x * cfs;
|
||||||
|
float ch = cp.Size.y * cfs;
|
||||||
|
|
||||||
|
if (flags & LiTextFlags_Shaddow) {
|
||||||
|
PrimTextQuad(*cmd, cx + 1.f, cy + 1.f, cw, ch, cp.SimpleUV, 0xff111111);
|
||||||
|
}
|
||||||
|
PrimTextQuad(*cmd, cx, cy, cw, ch, cp.SimpleUV, color);
|
||||||
|
}
|
||||||
|
off.x += cp.AdvanceX * cfs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Font::CleanupTMS() {}
|
||||||
|
|
||||||
|
PD_API void Font::BakeAndPush(bool final, std::vector<u8>& font_tex,
|
||||||
|
int texszs) {
|
||||||
|
auto t = PD::Gfx::LoadTexture(font_tex, texszs, texszs, TextureFormat::A8);
|
||||||
|
PDLOG("Font: Texture backed as 0x{:X} at {}", t.GetID(), pCurrentTex);
|
||||||
|
Textures.push_back(t.GetID());
|
||||||
|
pCurrentTex = Textures.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API std::string Font::pWrapText(const std::string& txt, float scale,
|
||||||
|
const PD::fvec2& max, PD::fvec2& dim) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API std::string Font::pShortText(const std::string& txt, float scale,
|
||||||
|
const PD::fvec2& max, PD::fvec2& dim) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Font::Delete() {
|
||||||
|
for (auto& it : Textures) {
|
||||||
|
// Creating a tmp fake Li tex for deletion
|
||||||
|
PD::Gfx::DeleteTexture(PD::Li::Texture(it, 0));
|
||||||
|
}
|
||||||
|
pCurrentTex = 0;
|
||||||
|
PixelHeight = 0;
|
||||||
|
pTMS.clear();
|
||||||
|
CodeMap.clear();
|
||||||
|
}
|
||||||
|
} // namespace Li
|
||||||
|
} // namespace PD
|
||||||
@@ -20,6 +20,11 @@ PD_API bool InBounds(const fvec2& a, const fvec2& b, const fvec2& c,
|
|||||||
(a.x > 0 && b.x > 0 && c.x > 0) || (a.y > 0 && b.y > 0 && c.y > 0));
|
(a.x > 0 && b.x > 0 && c.x > 0) || (a.y > 0 && b.y > 0 && c.y > 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PD_API bool InSpace(const PD::fvec2& pos, const Rect& rect) {
|
||||||
|
return (pos.x > rect.Top.x && pos.x < rect.Top.z && pos.y > rect.Top.y &&
|
||||||
|
pos.y < rect.Bot.y);
|
||||||
|
}
|
||||||
|
|
||||||
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus) {
|
PD_API void RotateCorner(fvec2& pos, float sinus, float cosinus) {
|
||||||
float x = pos.x * cosinus - pos.y * sinus;
|
float x = pos.x * cosinus - pos.y * sinus;
|
||||||
float y = pos.y * cosinus - pos.x * sinus;
|
float y = pos.y * cosinus - pos.x * sinus;
|
||||||
@@ -53,6 +58,7 @@ PD_API Rect PrimLine(const fvec2& a, const fvec2& b, int t) {
|
|||||||
// Using the vec maths api makes the code as short as it is
|
// Using the vec maths api makes the code as short as it is
|
||||||
vec2 dir = a - b;
|
vec2 dir = a - b;
|
||||||
float len = dir.Len();
|
float len = dir.Len();
|
||||||
|
if (len == 0.0f) return Rect();
|
||||||
vec2 unit_dir = dir / len;
|
vec2 unit_dir = dir / len;
|
||||||
vec2 perpendicular(-unit_dir.y, unit_dir.x);
|
vec2 perpendicular(-unit_dir.y, unit_dir.x);
|
||||||
vec2 off = perpendicular * ((float)t * 0.5f);
|
vec2 off = perpendicular * ((float)t * 0.5f);
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
#include <pd/core/core.hpp>
|
|
||||||
#include <pd/lithium/pools.hpp>
|
#include <pd/lithium/pools.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
namespace Li {
|
namespace Li {
|
||||||
PD::Pool<Vertex> pVtxPool;
|
static PD::Pool<Vertex> gVertexPool;
|
||||||
PD::Pool<u16> pIdxPool;
|
static PD::Pool<u16> gIndexPool;
|
||||||
|
|
||||||
PD_API Vertex* AllocateVertices(size_t count) {
|
PD_API PD::Pool<Vertex>& GetVertexPool() { return gVertexPool; }
|
||||||
return pVtxPool.Allocate(count);
|
PD_API PD::Pool<u16>& GetIndexPool() { return gIndexPool; }
|
||||||
}
|
|
||||||
|
|
||||||
PD_API u16* AllocateIndices(size_t count) { return pIdxPool.Allocate(count); }
|
|
||||||
|
|
||||||
PD_API void ResetPools() {
|
PD_API void ResetPools() {
|
||||||
pVtxPool.Reset();
|
gVertexPool.NoReset();
|
||||||
pIdxPool.Reset();
|
gIndexPool.NoReset();
|
||||||
}
|
}
|
||||||
} // namespace Li
|
} // namespace Li
|
||||||
} // namespace PD
|
} // namespace PD
|
||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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/button.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Button::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/// Ensure it gets sed to false and stays if not pressed
|
||||||
|
pressed = false;
|
||||||
|
color = UI7Color_Button;
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
if (io->InputHandler.DragObject(this->GetID(), fvec4(FinalPos(), size))) {
|
||||||
|
if (io->InputHandler.DragReleased) {
|
||||||
|
color = UI7Color_ButtonActive;
|
||||||
|
pressed = true;
|
||||||
|
} else {
|
||||||
|
color = UI7Color_ButtonHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
PD_API void Button::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->PathRect(FinalPos(), FinalPos() + size, io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(color));
|
||||||
|
list->LayerUp();
|
||||||
|
list->DrawText(FinalPos() + size * 0.5 - tdim * 0.5, label.c_str(),
|
||||||
|
io->Theme.Get(UI7Color_Text));
|
||||||
|
list->LayerDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Button::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
this->SetSize(tdim + io->FramePadding);
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+69
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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/checkbox.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Checkbox::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
color = UI7Color_FrameBackground;
|
||||||
|
/// Ensure it gets sed to false and stays if not pressed
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
if (io->InputHandler.DragObject(this->GetID(), fvec4(FinalPos(), size))) {
|
||||||
|
if (io->InputHandler.DragReleased) {
|
||||||
|
color = UI7Color_FrameBackgroundHovered;
|
||||||
|
usr_ref = !usr_ref;
|
||||||
|
} else {
|
||||||
|
color = UI7Color_FrameBackgroundHovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
PD_API void Checkbox::Draw() {
|
||||||
|
// Assert(list.get() && io.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->PathRect(FinalPos(), FinalPos() + cbs, io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(color));
|
||||||
|
if (usr_ref) {
|
||||||
|
list->PathRect(FinalPos() + 2, FinalPos() + cbs - 2, io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(UI7Color_Checkmark));
|
||||||
|
}
|
||||||
|
list->DrawText(
|
||||||
|
FinalPos() + fvec2(cbs.x + io->ItemSpace.x, cbs.y * 0.5 - tdim.y * 0.5),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Checkbox::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
cbs = io->ItemRowHeight;
|
||||||
|
this->SetSize(cbs + fvec2(tdim.x + io->ItemSpace.x, 0));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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/coloredit.hpp>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void ColorEdit::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
if (io->InputHandler.DragObject(this->GetID() + 2, fvec4(FinalPos(), size))) {
|
||||||
|
if (io->InputHandler.DragReleasedAW) {
|
||||||
|
is_shown = !is_shown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
PD_API void ColorEdit::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->PathRect(FinalPos(), FinalPos() + io->ItemRowHeight, io->FrameRounding);
|
||||||
|
list->PathFill(*color_ref);
|
||||||
|
list->DrawText(FinalPos() + fvec2(io->ItemSpace.x + io->ItemRowHeight, 0),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
if (is_shown) {
|
||||||
|
if (!layout) {
|
||||||
|
layout = new UI7::Layout(GetID(), *io);
|
||||||
|
}
|
||||||
|
layout->SetPosition(FinalPos());
|
||||||
|
DynObj* r = io->DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
||||||
|
list->SetFont(thiz->GetFont());
|
||||||
|
thiz->SetSize(layout->GetSize());
|
||||||
|
// l->Layer(30);
|
||||||
|
l->PathRect(thiz->GetPos(), thiz->GetPos() + thiz->GetSize(),
|
||||||
|
io->FrameRounding);
|
||||||
|
l->PathFill(io->Theme.Get(UI7Color_FrameBackground));
|
||||||
|
l->SetLayer(0);
|
||||||
|
});
|
||||||
|
layout->AddObjectEx(r, UI7LytAdd_Front | UI7LytAdd_NoCursorUpdate |
|
||||||
|
UI7LytAdd_NoScrollHandle);
|
||||||
|
r = io->DynObjPool.Allocate();
|
||||||
|
*r = UI7::DynObj([=, this](UI7::IO* io, Li::Drawlist* l, Container* thiz) {
|
||||||
|
list->SetFont(thiz->GetFont());
|
||||||
|
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.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
});
|
||||||
|
r->SetSize(PD::fvec2(200, io->ItemRowHeight));
|
||||||
|
layout->AddObject(r);
|
||||||
|
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();
|
||||||
|
list->SetLayer(50);
|
||||||
|
list->Merge(layout->GetDrawList());
|
||||||
|
list->SetLayer(0);
|
||||||
|
// io->RegisterDrawList(GetID(), layout->GetDrawList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void ColorEdit::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
this->SetSize(
|
||||||
|
fvec2(tdim.x + io->ItemSpace.x + io->ItemRowHeight, io->ItemRowHeight));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Container::HandleScrolling(fvec2 scrolling, fvec4 viewport) {
|
||||||
|
if (last_use != 0 && PD::Os::GetTime() - last_use > 5000) {
|
||||||
|
rem = true;
|
||||||
|
}
|
||||||
|
last_use = PD::Os::GetTime();
|
||||||
|
pos -= fvec2(0, scrolling.y);
|
||||||
|
skippable =
|
||||||
|
!Li::Math::InBounds(pos, size,
|
||||||
|
fvec4(viewport.x, viewport.y, viewport.x + viewport.z,
|
||||||
|
viewport.y + viewport.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void Container::HandleInternalInput() {
|
||||||
|
/** Requires Handle Scrolling First */
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Internal function */
|
||||||
|
PD_API void Container::PreDraw() {
|
||||||
|
if (pCLipRectUsed) {
|
||||||
|
// list->PushClipRect(pClipRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Internal function */
|
||||||
|
PD_API void Container::PostDraw() {
|
||||||
|
if (pCLipRectUsed) {
|
||||||
|
// list->PopClipRect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+119
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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 <algorithm>
|
||||||
|
#include <pd/ui7/container/dragdata.hpp>
|
||||||
|
#include <pd/ui7/container/label.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_API DragData<float>;
|
||||||
|
template class PD_API DragData<int>;
|
||||||
|
template class PD_API DragData<double>;
|
||||||
|
template class PD_API DragData<u8>;
|
||||||
|
template class PD_API DragData<u16>;
|
||||||
|
template class PD_API DragData<u32>;
|
||||||
|
template class PD_API DragData<u64>;
|
||||||
|
template <typename T>
|
||||||
|
PD_API void DragData<T>::HandleInput() {
|
||||||
|
/// Ensure to only check input once
|
||||||
|
if (inp_done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Assert(screen.get(), "Screen is not set up!");
|
||||||
|
// if (screen->ScreenType() == Screen::Bottom) {
|
||||||
|
float off_x = 0;
|
||||||
|
for (size_t i = 0; i < elm_count; i++) {
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", data[i], precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", data[i]);
|
||||||
|
}
|
||||||
|
vec2 tdim = io->Font->GetTextBounds(p.c_str(), io->FontScale);
|
||||||
|
// Unsafe but is the fastest solution
|
||||||
|
if (io->InputHandler.DragObject(
|
||||||
|
this->GetID() + i + 1,
|
||||||
|
fvec4(FinalPos() + fvec2(off_x, 0), tdim + io->FramePadding))) {
|
||||||
|
data[i] = std::clamp(
|
||||||
|
T(data[i] + (step * (io->InputHandler.DragPosition.x -
|
||||||
|
io->InputHandler.DragLastPosition.x))),
|
||||||
|
this->min, this->max);
|
||||||
|
}
|
||||||
|
off_x += tdim.x + io->ItemSpace.x + io->FramePadding.x;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
inp_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PD_API void DragData<T>::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
float off_x = 0.f;
|
||||||
|
for (size_t i = 0; i < elm_count; i++) {
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", data[i], precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", data[i]);
|
||||||
|
}
|
||||||
|
vec2 td = io->Font->GetTextBounds(p.c_str(), io->FontScale);
|
||||||
|
list->PathRect(FinalPos() + fvec2(off_x, 0),
|
||||||
|
FinalPos() + fvec2(off_x, 0) + td + io->FramePadding,
|
||||||
|
io->FrameRounding);
|
||||||
|
list->PathFill(io->Theme.Get(UI7Color_Button));
|
||||||
|
list->LayerUp();
|
||||||
|
list->DrawTextEx(FinalPos() + fvec2(off_x, 0), p.c_str(),
|
||||||
|
io->Theme.Get(UI7Color_Text), LiTextFlags_AlignMid,
|
||||||
|
td + io->FramePadding);
|
||||||
|
list->LayerDown();
|
||||||
|
off_x += td.x + io->ItemSpace.x + io->FramePadding.x;
|
||||||
|
}
|
||||||
|
list->DrawText(FinalPos() + fvec2(off_x, io->FramePadding.y * 0.5),
|
||||||
|
label.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PD_API void DragData<T>::Update() {
|
||||||
|
// Assert(io.get(), "Did you run Container::Init correctly?");
|
||||||
|
// Probably need to find a faster solution (caching sizes calculated here)
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
float off_x = 0;
|
||||||
|
for (size_t i = 0; i < elm_count; i++) {
|
||||||
|
std::string p;
|
||||||
|
if constexpr (std::is_floating_point_v<T>) {
|
||||||
|
p = std::format("{:.{}f}", data[i], precision);
|
||||||
|
} else {
|
||||||
|
p = std::format("{}", data[i]);
|
||||||
|
}
|
||||||
|
vec2 tdim = io->Font->GetTextBounds(p.c_str(), io->FontScale);
|
||||||
|
off_x += tdim.x + io->ItemSpace.x + io->FramePadding.x;
|
||||||
|
}
|
||||||
|
this->SetSize(vec2(tdim.x + off_x, tdim.y + io->FramePadding.y));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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/dynobj.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void DynObj::Draw() { pRenFun(io, list, this); }
|
||||||
|
|
||||||
|
PD_API void DynObj::HandleInput() {
|
||||||
|
if (pInp) {
|
||||||
|
pInp(io, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API void DynObj::Update() {}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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/image.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Image::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// Assert(img.get(), "Image is nullptr!");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->LayerUp();
|
||||||
|
list->BindTexture(img);
|
||||||
|
list->DrawRectFilled(FinalPos(), newsize, 0xffffffff);
|
||||||
|
list->UnbindTexture();
|
||||||
|
list->LayerDown();
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
Executable
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
namespace UI7 {
|
||||||
|
PD_API void Label::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
list->DrawTextEx(FinalPos(), label.c_str(), io->Theme.Get(UI7Color_Text),
|
||||||
|
LiTextFlags_NoOOS,
|
||||||
|
PD::fvec2(0, io->CurrentViewPort.pSize.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_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.pSize.z - FinalPos().x * 4,
|
||||||
|
io->CurrentViewPort.pSize.w),
|
||||||
|
this->tdim);
|
||||||
|
SetSize(tdim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 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 <algorithm>
|
||||||
|
#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_API Slider<float>;
|
||||||
|
template class PD_API Slider<int>;
|
||||||
|
template class PD_API Slider<double>;
|
||||||
|
template class PD_API Slider<u8>;
|
||||||
|
template class PD_API Slider<u16>;
|
||||||
|
template class PD_API Slider<u32>;
|
||||||
|
template class PD_API Slider<u64>;
|
||||||
|
template <typename T>
|
||||||
|
PD_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_API void Slider<T>::Draw() {
|
||||||
|
// Assert(io.get() && list.get(), "Did you run Container::Init correctly?");
|
||||||
|
// io->Ren->OnScreen(screen);
|
||||||
|
list->SetFont(GetFont());
|
||||||
|
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.c_str(), 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.c_str(), 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.c_str(), io->Theme.Get(UI7Color_Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PD_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.c_str(), io->FontScale);
|
||||||
|
|
||||||
|
this->SetSize(
|
||||||
|
fvec2(width + tdim.x + io->ItemSpace.x * 2, tdim.y + io->FramePadding.y));
|
||||||
|
}
|
||||||
|
} // namespace UI7
|
||||||
|
} // namespace PD
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
Copyright (c) 2024 - 2026 René Amthor (tobid7)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pd/core/core.hpp>
|
||||||
|
#include <pd/drivers/drivers.hpp>
|
||||||
|
#include <pd/ui7/containers.hpp>
|
||||||
|
#include <pd/ui7/io.hpp>
|
||||||
|
|
||||||
|
namespace PD {
|
||||||
|
|
||||||
|
PD_API UI7::IO::IO() : DeltaStats(60), CurrentViewPort("", 0) {
|
||||||
|
/** Probably not the best solution i guess */
|
||||||
|
// CurrentViewPort =
|
||||||
|
// ViewPort::New("Default", ivec4(ivec2(0, 0), pCtx.Gfx()->ViewPort));
|
||||||
|
// Start a little larger on these
|
||||||
|
LabelPool.Init(512);
|
||||||
|
DynObjPool.Init(512);
|
||||||
|
}
|
||||||
|
|
||||||
|
PD_API UI7::IO::~IO() {}
|
||||||
|
|
||||||
|
PD_API void UI7::IO::Update() {
|
||||||
|
/** Todo: find out if we even still use the Drawlist regestry */
|
||||||
|
u64 current = PD::Os::GetTimeNano();
|
||||||
|
Delta = static_cast<float>(current - LastTime) / 1000000.f;
|
||||||
|
LastTime = current;
|
||||||
|
DeltaStats.Add(Delta * 1000);
|
||||||
|
Time.Update();
|
||||||
|
InputHandler.Update();
|
||||||
|
Framerate = 1000.f / Delta;
|
||||||
|
DrawlistRegestry.clear();
|
||||||
|
DrawlistRegestry.push_front(std::make_pair("CtxBackList", &Back));
|
||||||
|
if (Font) ItemRowHeight = FontScale * Font->PixelHeight;
|
||||||
|
// RegisterDrawList("CtxBackList", Back);
|
||||||
|
NumIndices = FDL.GetNumIndices();
|
||||||
|
NumVertices = FDL.GetNumVertices();
|
||||||
|
LabelPool.ResetFast();
|
||||||
|
DynObjPool.ResetFast();
|
||||||
|
ImagePool.ResetFast();
|
||||||
|
}
|
||||||
|
} // namespace PD
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user