summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-05-20 21:08:19 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-05-20 21:08:19 -0400
commit40d69e7e40a18865a31af2f55efcde369d36dbbb (patch)
tree95a2cbbe40192183d13f846f3444b32d7e12b0e8
parentead9e484db969a880470d625b1884aced296e722 (diff)
pke: serialization overhaul + embedded assets
-rw-r--r--Makefile103
-rw-r--r--assets/fonts/font-mannequin.glyphbin0 -> 6272 bytes
-rw-r--r--assets/fonts/font-mannequin.pngbin0 -> 44235 bytes
-rw-r--r--embed/embedded-file.h12
-rw-r--r--embed/embedded-fonts.c9
-rw-r--r--embed/embedded-fonts.h8
-rw-r--r--src/asset-manager.cpp38
-rw-r--r--src/asset-manager.hpp8
-rw-r--r--src/ecs.cpp10
-rw-r--r--src/ecs.hpp1
-rw-r--r--src/entities.cpp14
-rw-r--r--src/font.cpp530
-rw-r--r--src/font.hpp4
-rw-r--r--src/game.cpp20
-rw-r--r--src/serialization-component.cpp2
-rw-r--r--src/serialization-font.cpp140
-rw-r--r--src/serialization-font.hpp2
-rw-r--r--src/serialization-static-ui.cpp294
-rw-r--r--src/serialization.cpp66
-rw-r--r--src/serialization.hpp16
-rw-r--r--src/static-ui.cpp66
-rw-r--r--src/static-ui.hpp19
-rw-r--r--src/vendor-pkh-include.cpp2
-rw-r--r--tests/pke-test-serialization.cpp255
-rw-r--r--tests/pke-test-static-ui.cpp50
25 files changed, 1048 insertions, 621 deletions
diff --git a/Makefile b/Makefile
index 0da6a41..9a82d8f 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,14 @@ endef
define cxx-dbg-command
$(CXX) -std=c++23 -c -o $@ -DDEBUG -g -O0 $(CXXFLAGS) $(INCS) $<
endef
+define cc-encode-binary-command
+$(1): $(2)
+ xxd -i $$< | sed -e 's/^unsigned /const unsigned /' > $$@
+endef
+define cc-pre-compile-header-command
+$(1): $(2)
+ $(CC) -std=c2x -O3 -c $$< -o $$@
+endef
FLG_PKE = -Isub/imgui -Isub/stb -Isub/cgltf -Isub/bullet3/src
FLG_EDT = $(FLG_PKE) -Isrc -I/home/pikum/build/msdfgen -I/home/pikum/build/msdf-atlas-gen
@@ -24,6 +32,26 @@ FLG_MPL = $(FLG_PKE) -Isrc
FLG_RUN = $(FLG_PKE) -Isrc
FLG_TST = $(FLG_PKE) -Isrc
+FILES_BIN = \
+ assets/fonts/font-mannequin.png \
+ assets/fonts/font-mannequin.glyph \
+
+FILES_BIN_SAFE = $(subst -,_,$(subst .,_,$(FILES_BIN)))
+FILES_BIN_H = $(FILES_BIN_SAFE:%=%.h)
+FILES_BIN_GCH = $(FILES_BIN_SAFE:%=%.gch)
+
+# I don't like foreach but this works
+$(foreach f,$(FILES_BIN), \
+ $(eval \
+ $(call cc-encode-binary-command,$(subst -,_,$(subst .,_,$f)).h,$(f)) \
+ ) \
+)
+$(foreach f,$(FILES_BIN_SAFE), \
+ $(eval \
+ $(call cc-pre-compile-header-command,$(f).gch,$(f).h) \
+ ) \
+)
+
DIR_OBJ=obj
DIR_BIN=bin
DIR_DBG=dbg
@@ -48,6 +76,9 @@ default: options $(DIR_BIN)/pke-editor $(DIR_BIN)/libpke-example.a $(DIR_BIN)/pk
default-dbg: options $(DIR_DBG)/pke-editor $(DIR_DBG)/libpke-example.a $(DIR_DBG)/pke-runtime ;
.PHONY: prepare
+prepare: config.h
+prepare: config.mk
+prepare: $(FILES_BIN_GCH)
prepare:
mkdir -p $(DIR_BIN) $(DIR_DBG) $(DIR_OBJ) $(DIR_OBJ)/shaders $(DIR_DBG)/bullet3 $(DIR_BIN)/bullet3
mkdir -p $(DIR_BIN)/bullet3
@@ -65,63 +96,64 @@ options: prepare .WAIT
config.h:
cp config.def.h $@
-%.h: ;
-
-%.hpp: ;
-
-$(DIR_OBJ)/%.o : config.h config.mk
-$(DIR_OBJ)/%.so : config.h config.mk
-
-$(DIR_OBJ)/%.o : sub/imgui/%.cpp
+$(DIR_OBJ)/%.o : sub/imgui/%.cpp | prepare
$(cxx-bin-command) -Isub/imgui
-$(DIR_OBJ)/%.so : sub/imgui/%.cpp
+$(DIR_OBJ)/%.so : sub/imgui/%.cpp | prepare
$(cxx-dbg-command) -Isub/imgui
-$(DIR_OBJ)/%.o : sub/imgui/backends/%.cpp
+$(DIR_OBJ)/%.o : sub/imgui/backends/%.cpp | prepare
$(cxx-bin-command) -Isub/imgui
-$(DIR_OBJ)/%.so : sub/imgui/backends/%.cpp
+$(DIR_OBJ)/%.so : sub/imgui/backends/%.cpp | prepare
$(cxx-dbg-command) -Isub/imgui
-$(DIR_OBJ)/%.o : sub/imgui/misc/cpp/%.cpp
+$(DIR_OBJ)/%.o : sub/imgui/misc/cpp/%.cpp | prepare
$(cxx-bin-command) -Isub/imgui
-$(DIR_OBJ)/%.so : sub/imgui/misc/cpp/%.cpp
+$(DIR_OBJ)/%.so : sub/imgui/misc/cpp/%.cpp | prepare
$(cxx-dbg-command) -Isub/imgui
-$(DIR_OBJ)/shaders/%.vert.spv: assets/shaders/%.vert
+$(DIR_OBJ)/shaders/%.vert.spv: assets/shaders/%.vert | prepare
$(GLSLC) $^ -o $@
-$(DIR_OBJ)/shaders/%.frag.spv: assets/shaders/%.frag
+$(DIR_OBJ)/shaders/%.frag.spv: assets/shaders/%.frag | prepare
$(GLSLC) $^ -o $@
-$(DIR_OBJ)/%.o : src/%.c
+$(DIR_OBJ)/%.o : src/%.c | prepare
+ $(cc-bin-command) $(FLG_PKE)
+$(DIR_OBJ)/%.so : src/%.c | prepare
+ $(cc-dbg-command) $(FLG_PKE)
+$(DIR_OBJ)/%.o : embed/%.c | prepare
$(cc-bin-command) $(FLG_PKE)
-$(DIR_OBJ)/%.so : src/%.c
+$(DIR_OBJ)/%.so : embed/%.c | prepare
$(cc-dbg-command) $(FLG_PKE)
-$(DIR_OBJ)/%.o : src/vendor/tinyfiledialogs/%.c
+$(DIR_OBJ)/%.o : src/vendor/tinyfiledialogs/%.c | prepare
$(cc-bin-command) $(FLG_PKE)
-$(DIR_OBJ)/%.so : src/vendor/tinyfiledialogs/%.c
+$(DIR_OBJ)/%.so : src/vendor/tinyfiledialogs/%.c | prepare
$(cc-dbg-command) $(FLG_PKE)
-$(DIR_OBJ)/%.o : tests/%.c
+$(DIR_OBJ)/%.o : tests/%.c | prepare
$(cc-bin-command) $(FLG_TST)
-$(DIR_OBJ)/%.so : tests/%.c
+$(DIR_OBJ)/%.so : tests/%.c | prepare
$(cc-dbg-command) $(FLG_TST)
-$(DIR_OBJ)/%.o : src/%.cpp
+$(DIR_OBJ)/%.o : src/%.cpp | prepare
+ $(cxx-bin-command) $(FLG_PKE)
+$(DIR_OBJ)/%.so : src/%.cpp | prepare
+ $(cxx-dbg-command) $(FLG_PKE)
+$(DIR_OBJ)/%.o : embed/%.cpp | prepare
$(cxx-bin-command) $(FLG_PKE)
-$(DIR_OBJ)/%.so : src/%.cpp
+$(DIR_OBJ)/%.so : embed/%.cpp | prepare
$(cxx-dbg-command) $(FLG_PKE)
-$(DIR_OBJ)/%.o : editor/%.cpp
+$(DIR_OBJ)/%.o : editor/%.cpp | prepare
$(cxx-bin-command) $(FLG_EDT)
-$(DIR_OBJ)/%.so : editor/%.cpp
+$(DIR_OBJ)/%.so : editor/%.cpp | prepare
$(cxx-dbg-command) $(FLG_EDT)
-$(DIR_OBJ)/%.o : example/%.cpp
+$(DIR_OBJ)/%.o : example/%.cpp | prepare
$(cxx-bin-command) $(FLG_MPL)
-$(DIR_OBJ)/%.so : example/%.cpp
+$(DIR_OBJ)/%.so : example/%.cpp | prepare
$(cxx-dbg-command) $(FLG_MPL)
-$(DIR_OBJ)/%.o : runtime/%.cpp
+$(DIR_OBJ)/%.o : runtime/%.cpp | prepare
$(cxx-bin-command) $(FLG_RUN)
-$(DIR_OBJ)/%.so : runtime/%.cpp
+$(DIR_OBJ)/%.so : runtime/%.cpp | prepare
$(cxx-dbg-command) $(FLG_RUN)
-$(DIR_OBJ)/%.o : tests/%.cpp
+$(DIR_OBJ)/%.o : tests/%.cpp | prepare
$(cxx-bin-command) $(FLG_TST)
-$(DIR_OBJ)/%.so : tests/%.cpp
+$(DIR_OBJ)/%.so : tests/%.cpp | prepare
$(cxx-dbg-command) $(FLG_TST)
$(DIR_BIN)/libImgui.a: $(DIR_OBJ)/imgui.o
@@ -168,6 +200,7 @@ $(DIR_BIN)/libpke.a: $(DIR_OBJ)/asset-manager.o
$(DIR_BIN)/libpke.a: $(DIR_OBJ)/camera.o
$(DIR_BIN)/libpke.a: $(DIR_OBJ)/dynamic-array.o
$(DIR_BIN)/libpke.a: $(DIR_OBJ)/ecs.o
+$(DIR_BIN)/libpke.a: $(DIR_OBJ)/embedded-fonts.o
$(DIR_BIN)/libpke.a: $(DIR_OBJ)/entities.o
$(DIR_BIN)/libpke.a: $(DIR_OBJ)/event.o
$(DIR_BIN)/libpke.a: $(DIR_OBJ)/font.o
@@ -207,6 +240,7 @@ $(DIR_DBG)/libpke.a: $(DIR_OBJ)/asset-manager.so
$(DIR_DBG)/libpke.a: $(DIR_OBJ)/camera.so
$(DIR_DBG)/libpke.a: $(DIR_OBJ)/dynamic-array.so
$(DIR_DBG)/libpke.a: $(DIR_OBJ)/ecs.so
+$(DIR_DBG)/libpke.a: $(DIR_OBJ)/embedded-fonts.so
$(DIR_DBG)/libpke.a: $(DIR_OBJ)/entities.so
$(DIR_DBG)/libpke.a: $(DIR_OBJ)/event.so
$(DIR_DBG)/libpke.a: $(DIR_OBJ)/font.so
@@ -304,14 +338,13 @@ $(DIR_DBG)/pke-test: $(DIR_OBJ)/pke-test.so
.PHONY: print
print:
- @echo $(OUT_OBJ)
- @echo $(MAINS_OBJ)
- @echo $(MAINS_SOBJ)
+ @echo $(FILES_BIN_H)
+ @echo $(FILES_BIN_GCH)
.PHONY: clean
clean:
rm -rf .cache
- rm -f *.o *.so *.plist config.h
+ rm -f *.o *.so *.plist config.h $(FILES_BIN_GCH)
rm -rf $(DIR_BIN) $(DIR_OBJ) $(DIR_DBG)
.PHONY: dist install uninstall
diff --git a/assets/fonts/font-mannequin.glyph b/assets/fonts/font-mannequin.glyph
new file mode 100644
index 0000000..219564e
--- /dev/null
+++ b/assets/fonts/font-mannequin.glyph
Binary files differ
diff --git a/assets/fonts/font-mannequin.png b/assets/fonts/font-mannequin.png
new file mode 100644
index 0000000..9f72777
--- /dev/null
+++ b/assets/fonts/font-mannequin.png
Binary files differ
diff --git a/embed/embedded-file.h b/embed/embedded-file.h
new file mode 100644
index 0000000..85f2a34
--- /dev/null
+++ b/embed/embedded-file.h
@@ -0,0 +1,12 @@
+#ifndef PKE_EMBED_EMBEDDED_FILE_H
+#define PKE_EMBED_EMBEDDED_FILE_H
+
+#include <stddef.h>
+
+struct embedded_file {
+ const char *name;
+ const unsigned char *data;
+ const size_t size;
+};
+
+#endif /* PKE_EMBED_EMBEDDED_FILE_H */
diff --git a/embed/embedded-fonts.c b/embed/embedded-fonts.c
new file mode 100644
index 0000000..ca85d91
--- /dev/null
+++ b/embed/embedded-fonts.c
@@ -0,0 +1,9 @@
+
+#include "./embedded-fonts.h"
+#include "../assets/fonts/font_mannequin_png.h"
+#include "../assets/fonts/font_mannequin_glyph.h"
+
+const struct embedded_file embedded_fonts[] = {
+ { "fnt_mquin_img\0\0", assets_fonts_font_mannequin_png, assets_fonts_font_mannequin_png_len },
+ { "fnt_mquin_gly\0\0", assets_fonts_font_mannequin_glyph, assets_fonts_font_mannequin_glyph_len },
+};
diff --git a/embed/embedded-fonts.h b/embed/embedded-fonts.h
new file mode 100644
index 0000000..da513e8
--- /dev/null
+++ b/embed/embedded-fonts.h
@@ -0,0 +1,8 @@
+#ifndef PKE_EMBED_EMBEDDED_FONTS_H
+#define PKE_EMBED_EMBEDDED_FONTS_H
+
+#include "./embedded-file.h"
+
+extern const struct embedded_file embedded_fonts[];
+
+#endif /* PKE_EMBED_EMBEDDED_FONTS_H */
diff --git a/src/asset-manager.cpp b/src/asset-manager.cpp
index 2976643..b7a82fd 100644
--- a/src/asset-manager.cpp
+++ b/src/asset-manager.cpp
@@ -46,10 +46,11 @@ void AM_Load_Task(Asset &asset) {
return;
}
asset.size = std::filesystem::file_size(asset.basePath);
- asset.ptr = pk_new_base(asset.size, alignof(max_align_t));
+ void *ptr = pk_new_base(asset.size, alignof(max_align_t));
file.seekg(0, std::ios::beg);
- file.read(static_cast<char *>(asset.ptr), asset.size);
+ file.read(static_cast<char *>(ptr), asset.size);
file.close();
+ asset.ptr = ptr;
asset.state = PKE_ASSET_LOADING_STATE_LOADED;
}
@@ -85,8 +86,9 @@ AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t
strncpy(asset.key, key, AssetKeyLength);
asset.basePath = nullptr;
asset.size = size;
- asset.ptr = pk_new_base(size, alignment);
- memcpy(asset.ptr, data, size);
+ void *ptr = pk_new_base(size, alignment);
+ memcpy(ptr, data, size);
+ asset.ptr = ptr;
asset.state = PKE_ASSET_LOADING_STATE_LOADED;
asset.type = type;
return assetHandle;
@@ -149,6 +151,28 @@ AssetHandle AM_Register(const char *path, AssetType type) {
return assetHandle;
}
+AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, int64_t size) {
+ assert(data != nullptr && "Attempt to register invalid asset data");
+ assert(data != CAFE_BABE(void) && "Attempt to register invalid asset data");
+ assert(size != 0 && "Attempt to register asset data of size 0");
+ Asset *searchedAsset = AM_Get_Inner(key);
+ if (searchedAsset != nullptr) {
+ return searchedAsset->handle;
+ }
+ AssetHandle assetHandle{Buckets_NewHandle(Asset_BucketContainer)};
+ Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex];
+ new (&asset) Asset{};
+ asset.handle = assetHandle;
+ strncpy(asset.key, key, AssetKeyLength);
+ asset.basePath = nullptr;
+ asset.size = size;
+ asset.ptr = data;
+ asset.state = PKE_ASSET_LOADING_STATE_LOADED;
+ asset.type = type;
+ asset.flags = PKE_ASSET_FLAGS_MEM_STATIC;
+ return assetHandle;
+}
+
void AM_Release(AssetHandle assetHandle) {
assert(assetHandle != AssetHandle_MAX);
Asset &asset = Asset_BucketContainer.buckets[assetHandle.bucketIndex][assetHandle.itemIndex];
@@ -243,9 +267,11 @@ void AM_GC() {
for (long b = 0; b <= Asset_BucketContainer.pkeHandle.bucketIndex; ++b) {
for (long i = 0; i < Asset_BucketContainer.pkeHandle.itemIndex; ++i) {
Asset &asset = Asset_BucketContainer.buckets[b][i];
- if (asset.referenceCount > 0)
+ if (asset.referenceCount > 0) {
+ fprintf(stderr, "[AM_GC] Asset '%.16s' still in use, count: %i", asset.key, asset.referenceCount);
continue;
- if (asset.ptr != nullptr && asset.ptr != CAFE_BABE(void)) {
+ }
+ if (asset.ptr != nullptr && asset.ptr != CAFE_BABE(void) && !PK_HAS_FLAG(asset.flags, PKE_ASSET_FLAGS_MEM_STATIC)) {
pk_delete_base(asset.ptr, asset.size);
}
asset.size = 0;
diff --git a/src/asset-manager.hpp b/src/asset-manager.hpp
index ec98d08..5106375 100644
--- a/src/asset-manager.hpp
+++ b/src/asset-manager.hpp
@@ -12,6 +12,7 @@ constexpr AssetHandle AssetHandle_MAX = AssetHandle{ pk_handle_MAX_constexpr };
TypeSafeInt_constexpr(AssetLoadingState, uint8_t, 0xFF);
TypeSafeInt_constexpr(AssetType, uint8_t, 0xFF);
+TypeSafeInt_constexpr(AssetFlags, uint8_t, 0xFF);
const int64_t AssetKeyLength = 16;
using AssetKey = char[AssetKeyLength];
@@ -29,6 +30,9 @@ const AssetType PKE_ASSET_TYPE_AUDIO = AssetType {0x08};
const AssetType PKE_ASSET_TYPE_FONT = AssetType {0x10};
const AssetType PKE_ASSET_TYPE_ALL = AssetType {0xFF};
+const AssetFlags PKE_ASSET_FLAGS_NONE = AssetFlags {0x00};
+const AssetFlags PKE_ASSET_FLAGS_MEM_STATIC = AssetFlags {0x01};
+
constexpr int64_t EngineDefinedAssetCount = 8;
extern AssetKey EngineDefinedAssets[EngineDefinedAssetCount];
@@ -37,17 +41,19 @@ struct Asset {
AssetKey key = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
const char *basePath = nullptr;
int64_t size = 0;
- void *ptr = nullptr;
+ const void *ptr = nullptr;
std::future<void> future;
int8_t referenceCount = 0;
AssetLoadingState state = PKE_ASSET_LOADING_STATE_UNLOADED;
AssetType type = PKE_ASSET_TYPE_UNSET;
+ AssetFlags flags = PKE_ASSET_FLAGS_NONE;
};
void AM_Init();
AssetHandle AM_Register(AssetKey key, AssetType type, const void *data, int64_t size, std::size_t alignment);
AssetHandle AM_Register(const char *path, AssetType type);
AssetHandle AM_Register(AssetKey key, AssetType type, const char *path);
+AssetHandle AM_Register_Static(AssetKey key, AssetType type, const void *data, int64_t size);
void AM_Release(AssetHandle assetHandle);
const Asset *AM_Get(AssetHandle assetHandle);
const AssetHandle AM_GetHandle(AssetKey key);
diff --git a/src/ecs.cpp b/src/ecs.cpp
index d029b18..9d0245e 100644
--- a/src/ecs.cpp
+++ b/src/ecs.cpp
@@ -105,6 +105,16 @@ Entity_Base *ECS_GetEntity(EntityHandle handle) {
return ecs.bc.entityPtrs[handle];
}
+Entity_Base *ECS_GetEntityByUUID(pk_uuid uuid) {
+ for (pk_handle_bucket_index_T b = 0; b <= ecs.bc.entityPtrs.pkeHandle.bucketIndex; ++b) {
+ for (pk_handle_item_index_T i = 0; i < ecs.bc.entityPtrs.pkeHandle.itemIndex; ++i) {
+ Entity_Base *bs = ecs.bc.entityPtrs.buckets[b][i];
+ if (bs->uuid == uuid) return bs;
+ }
+ }
+ return nullptr;
+}
+
void ECS_MarkForRemoval(Entity_Base *entity) {
assert(entity->handle != EntityHandle_MAX && "Attempting to remove invalid entity");
assert(entity->isMarkedForRemoval == false && "Entity already marked for removal");
diff --git a/src/ecs.hpp b/src/ecs.hpp
index b25fdb7..a934fa2 100644
--- a/src/ecs.hpp
+++ b/src/ecs.hpp
@@ -17,6 +17,7 @@ void ECS_Tick_Late(double delta);
Entity_Base *ECS_CreateGenericEntity();
EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEnt = nullptr);
Entity_Base *ECS_GetEntity(EntityHandle handle);
+Entity_Base *ECS_GetEntityByUUID(pk_uuid uuid);
void ECS_MarkForRemoval(Entity_Base *entity);
void ECS_HandleCollision(CompInstance *lhs, CompInstance *rhs);
diff --git a/src/entities.cpp b/src/entities.cpp
index 860907c..1ffecb3 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -343,7 +343,7 @@ void EntityType_PreLoad(EntityType_LoadHelperStruct &helper) {
btConvexHullShape *shape;
{
shape = pk_new<btConvexHullShape>(MemBkt_Bullet);
- btScalar *vertDataPointer = reinterpret_cast<btScalar *>(helper.modelBinAsset->ptr);
+ btScalar *vertDataPointer = reinterpret_cast<btScalar *>(const_cast<void *>(helper.modelBinAsset->ptr));
/* TODO JCB - 2024-01-02
* we shouldn't assume that the first index is the vertexes
*/
@@ -438,7 +438,7 @@ void EntityType_PreLoad(EntityType_LoadHelperStruct &helper) {
etdHelper.textureAssetHandle = AssetHandle{AM_GetHandle(etd.textureAssetKey)};
if (etdHelper.textureAssetHandle != AssetHandle_MAX) {
etdHelper.textureAsset = AM_Get(etdHelper.textureAssetHandle);
- stbi_uc *pixels = stbi_load_from_memory(static_cast<stbi_uc *>(etdHelper.textureAsset->ptr), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha);
+ stbi_uc *pixels = stbi_load_from_memory(static_cast<stbi_uc *>(const_cast<void *>(etdHelper.textureAsset->ptr)), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha);
assert(pixels != nullptr && "sbti_load failed to load image.");
stbi_image_free(pixels);
} else {
@@ -515,7 +515,7 @@ void EntityType_LoadTexture(EntityType_LoadHelperStruct &helper, const int64_t i
int32_t pixelWidth, pixelHeight, pixelChannels;
stbi_uc *pixels = nullptr;
if (etdHelper.textureAssetHandle != AssetHandle_MAX) {
- pixels = stbi_load_from_memory(static_cast<stbi_uc *>(etdHelper.textureAsset->ptr), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha);
+ pixels = stbi_load_from_memory(static_cast<stbi_uc *>(const_cast<void *>(etdHelper.textureAsset->ptr)), etdHelper.textureAsset->size, &pixelWidth, &pixelHeight, &pixelChannels, STBI_rgb_alpha);
assert(pixels != nullptr && "sbti_load failed to load image.");
} else {
pixelWidth = 2;
@@ -827,19 +827,19 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh
char *srcPtr = nullptr;
dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetVert;
- srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accVert.buffer_view->offset;
+ srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accVert.buffer_view->offset;
memcpy(dstPtr, srcPtr, accVert.buffer_view->size);
dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetNorm;
- srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accNorm.buffer_view->offset;
+ srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accNorm.buffer_view->offset;
memcpy(dstPtr, srcPtr, accNorm.buffer_view->size);
dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetUV;
- srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accUV.buffer_view->offset;
+ srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accUV.buffer_view->offset;
memcpy(dstPtr, srcPtr, accUV.buffer_view->size);
dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + offsetIndex;
- srcPtr = static_cast<char *>(helper.modelBinAsset->ptr) + accIndex.buffer_view->offset;
+ srcPtr = static_cast<char *>(const_cast<void *>(helper.modelBinAsset->ptr)) + accIndex.buffer_view->offset;
memcpy(dstPtr, srcPtr, accIndex.buffer_view->size);
VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
diff --git a/src/font.cpp b/src/font.cpp
index c94890b..380827b 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -8,6 +8,7 @@
#include "vendor-stb-image-include.h"
#include "game-settings.hpp"
#include "ecs.hpp"
+#include "../embed/embedded-fonts.h"
#include <vulkan/vulkan_core.h>
@@ -253,6 +254,21 @@ void FontType_Init() {
ft->glyphs = nullptr;
ft->renders = nullptr;
}
+ AssetKey ak_img = "fnt_mquin_img\0\0";
+ AssetKey ak_glyphs = "fnt_mquin_gly\0\0";
+ AssetHandle ah_img = AM_Register_Static(ak_img, PKE_ASSET_TYPE_TEXTURE, embedded_fonts[0].data, embedded_fonts[0].size);
+ AssetHandle ah_glyphs = AM_Register_Static(ak_glyphs, PKE_ASSET_TYPE_UNSET, embedded_fonts[1].data, embedded_fonts[1].size);
+ FontTypeMSDFSettings msdf_s;
+ msdf_s.minimum_scale = 144;
+ msdf_s.px_range = 4;
+ FontTypeSpacing spacing;
+ spacing.geometry_scale = 0.0625;
+ spacing.em_size = 1;
+ spacing.ascender_y = 0.875;
+ spacing.descender_y = -0.125;
+ spacing.line_height = 1.125;
+ spacing.underline_y = 0.0625;
+ FontType_RegisterFont(cstring_to_pk_cstr("fnt_mquin_7y"), ah_img, ah_glyphs, &msdf_s, &spacing);
}
void FontType_Teardown() {
@@ -471,6 +487,11 @@ void FontType_Deserialize(std::istream &stream) {
}
}
+FontType* FontType_Get(FontTypeIndex idx) {
+ assert(idx < ftd.h_ft);
+ return &ftd.arr_ft[static_cast<FontTypeIndex_T>(idx)];
+}
+
FontType* FontType_GetFonts(FontTypeIndex &count) {
count = ftd.h_ft;
return ftd.arr_ft;
@@ -524,116 +545,124 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle
ft->atlas_size.x = (float)txtr_x;
ft->atlas_size.y = (float)txtr_y;
- // buffers
+ ECS_CreateEntity(ft);
- glm::vec2 atlas_size_buffer[4];
- for (int i = 0; i < 4; ++i) {
- atlas_size_buffer[i] = ft->atlas_size;
- }
+ if (window != NULL) {
- pkvk_buffer_create_data create_data{};
- create_data.buffer_byte_length[0] = sizeof(pkeIntrinsicsPlane.vert[0]) * 4;
- create_data.buffer_byte_length[1] = sizeof(pkeIntrinsicsPlane.uv[0]) * 4;
- create_data.buffer_byte_length[2] = sizeof(atlas_size_buffer[0]) * 4;
- create_data.buffer_byte_length[3] = sizeof(pkeIntrinsicsPlane.index[0]) * 6;
- create_data.buffer_byte_length[4] = sizeof(FontInstanceBufferItem);
- create_data.src_data[0] = &pkeIntrinsicsPlane.vert;
- create_data.src_data[1] = &pkeIntrinsicsPlane.uv;
- create_data.src_data[2] = &atlas_size_buffer;
- create_data.src_data[3] = &pkeIntrinsicsPlane.index;
- create_data.src_data[4] = nullptr;
- create_data.n_buffers = 5;
- create_data.index_index = 3;
- create_data.index_instance = 4;
-
- pkvk_buffer_create_data_out out{};
- pkvk_buffer_create(&create_data, &out);
-
- ft->bindings.bd_vertex.buffer = out.buffers[0];
- ft->bindings.bd_vertex.firstBinding = 0;
- ft->bindings.bd_vertex.bindingCount = 1;
- ft->bindings.bd_uv.buffer = out.buffers[1];
- ft->bindings.bd_uv.firstBinding = 1;
- ft->bindings.bd_uv.bindingCount = 1;
- ft->bindings.bd_atlas_size.buffer = out.buffers[2];
- ft->bindings.bd_atlas_size.firstBinding = 2;
- ft->bindings.bd_atlas_size.bindingCount = 1;
- ft->bindings.bd_index.buffer = out.buffers[3];
- ft->bindings.bd_index.firstBinding = 0;
- ft->bindings.bd_index.bindingCount = 1;
- ft->bindings.index_count = 6;
- ft->bindings.bd_instance.buffer = out.buffers[4];
- ft->bindings.bd_instance.firstBinding = 3;
- ft->bindings.bd_instance.bindingCount = 1;
- ft->gr.deviceMemoryVert = out.device_memory_vertex;
- ft->gr.deviceMemoryInst = out.device_memory_instance;
-
- ft->bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(FontInstanceBufferItem);
-
- // texture
-
- pkvk_texture_upload_data txtr_data{};
- txtr_data.bytes = txtr_bytes;
- txtr_data.n_bytes = imageSizeBytes;
- txtr_data.width = (uint32_t)txtr_x;
- txtr_data.height = (uint32_t)txtr_y;
-
- pkvk_texture_upload_data_out txtr_out{};
- pkvk_texture_upload(&txtr_data, &txtr_out);
-
- ft->gr.textureImage = txtr_out.image;
- ft->gr.textureImageView = txtr_out.image_view;
- ft->gr.deviceMemoryTexture = txtr_out.device_memory;
-
- free(txtr_bytes);
-
- /*
- * Vulkan descriptor sets
- */
- VkDescriptorPoolSize descriptorPoolSizes[1];
- descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- descriptorPoolSizes[0].descriptorCount = (uint32_t)1;
-
- VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo;
- vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
- vkDescriptorPoolCreateInfo.pNext = nullptr;
- vkDescriptorPoolCreateInfo.flags = 0;
- vkDescriptorPoolCreateInfo.maxSets = (uint32_t)1;
- vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)1;
- vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
-
- // consider making me a global pool
- vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &ft->gr.vkDescriptorPool);
- assert(vkResult == VK_SUCCESS);
-
- VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo;
- vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
- vkDescriptorSetAllocateInfo.pNext = nullptr;
- vkDescriptorSetAllocateInfo.descriptorPool = ft->gr.vkDescriptorPool;
- vkDescriptorSetAllocateInfo.descriptorSetCount = (uint32_t)1;
- vkDescriptorSetAllocateInfo.pSetLayouts = &pkePipelines.descr_layouts.named.txtr;
-
- vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, &ft->gr.vkDescriptorSet);
- assert(vkResult == VK_SUCCESS);
-
- VkDescriptorImageInfo textureDescriptorInfo;
- textureDescriptorInfo.sampler = global_sampler;
- textureDescriptorInfo.imageView = ft->gr.textureImageView;
- textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-
- VkWriteDescriptorSet writeDescriptorSet;
- writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- writeDescriptorSet.pNext = nullptr;
- writeDescriptorSet.dstSet = ft->gr.vkDescriptorSet;
- writeDescriptorSet.dstBinding = (uint32_t)0;
- writeDescriptorSet.dstArrayElement = (uint32_t)0;
- writeDescriptorSet.descriptorCount = (uint32_t)1;
- writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- writeDescriptorSet.pImageInfo = &textureDescriptorInfo;
- writeDescriptorSet.pBufferInfo = nullptr;
- writeDescriptorSet.pTexelBufferView = nullptr;
-
- vkUpdateDescriptorSets(vkDevice, (uint32_t)1, &writeDescriptorSet, 0, nullptr);
+ // buffers
+
+ glm::vec2 atlas_size_buffer[4];
+ for (int i = 0; i < 4; ++i) {
+ atlas_size_buffer[i] = ft->atlas_size;
+ }
+
+ pkvk_buffer_create_data create_data{};
+ create_data.buffer_byte_length[0] = sizeof(pkeIntrinsicsPlane.vert[0]) * 4;
+ create_data.buffer_byte_length[1] = sizeof(pkeIntrinsicsPlane.uv[0]) * 4;
+ create_data.buffer_byte_length[2] = sizeof(atlas_size_buffer[0]) * 4;
+ create_data.buffer_byte_length[3] = sizeof(pkeIntrinsicsPlane.index[0]) * 6;
+ create_data.buffer_byte_length[4] = sizeof(FontInstanceBufferItem);
+ create_data.src_data[0] = &pkeIntrinsicsPlane.vert;
+ create_data.src_data[1] = &pkeIntrinsicsPlane.uv;
+ create_data.src_data[2] = &atlas_size_buffer;
+ create_data.src_data[3] = &pkeIntrinsicsPlane.index;
+ create_data.src_data[4] = nullptr;
+ create_data.n_buffers = 5;
+ create_data.index_index = 3;
+ create_data.index_instance = 4;
+
+ pkvk_buffer_create_data_out out{};
+ pkvk_buffer_create(&create_data, &out);
+
+ ft->bindings.bd_vertex.buffer = out.buffers[0];
+ ft->bindings.bd_vertex.firstBinding = 0;
+ ft->bindings.bd_vertex.bindingCount = 1;
+ ft->bindings.bd_uv.buffer = out.buffers[1];
+ ft->bindings.bd_uv.firstBinding = 1;
+ ft->bindings.bd_uv.bindingCount = 1;
+ ft->bindings.bd_atlas_size.buffer = out.buffers[2];
+ ft->bindings.bd_atlas_size.firstBinding = 2;
+ ft->bindings.bd_atlas_size.bindingCount = 1;
+ ft->bindings.bd_index.buffer = out.buffers[3];
+ ft->bindings.bd_index.firstBinding = 0;
+ ft->bindings.bd_index.bindingCount = 1;
+ ft->bindings.index_count = 6;
+ ft->bindings.bd_instance.buffer = out.buffers[4];
+ ft->bindings.bd_instance.firstBinding = 3;
+ ft->bindings.bd_instance.bindingCount = 1;
+ ft->gr.deviceMemoryVert = out.device_memory_vertex;
+ ft->gr.deviceMemoryInst = out.device_memory_instance;
+
+ ft->bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(FontInstanceBufferItem);
+
+ // texture
+
+ pkvk_texture_upload_data txtr_data{};
+ txtr_data.bytes = txtr_bytes;
+ txtr_data.n_bytes = imageSizeBytes;
+ txtr_data.width = (uint32_t)txtr_x;
+ txtr_data.height = (uint32_t)txtr_y;
+
+ pkvk_texture_upload_data_out txtr_out{};
+ pkvk_texture_upload(&txtr_data, &txtr_out);
+
+ ft->gr.textureImage = txtr_out.image;
+ ft->gr.textureImageView = txtr_out.image_view;
+ ft->gr.deviceMemoryTexture = txtr_out.device_memory;
+
+ free(txtr_bytes);
+
+ /*
+ * Vulkan descriptor sets
+ */
+ VkDescriptorPoolSize descriptorPoolSizes[1];
+ descriptorPoolSizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ descriptorPoolSizes[0].descriptorCount = (uint32_t)1;
+
+ VkDescriptorPoolCreateInfo vkDescriptorPoolCreateInfo;
+ vkDescriptorPoolCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+ vkDescriptorPoolCreateInfo.pNext = nullptr;
+ vkDescriptorPoolCreateInfo.flags = 0;
+ vkDescriptorPoolCreateInfo.maxSets = (uint32_t)1;
+ vkDescriptorPoolCreateInfo.poolSizeCount = (uint32_t)1;
+ vkDescriptorPoolCreateInfo.pPoolSizes = descriptorPoolSizes;
+
+ // consider making me a global pool
+ vkResult = vkCreateDescriptorPool(vkDevice, &vkDescriptorPoolCreateInfo, vkAllocator, &ft->gr.vkDescriptorPool);
+ assert(vkResult == VK_SUCCESS);
+
+ VkDescriptorSetAllocateInfo vkDescriptorSetAllocateInfo;
+ vkDescriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ vkDescriptorSetAllocateInfo.pNext = nullptr;
+ vkDescriptorSetAllocateInfo.descriptorPool = ft->gr.vkDescriptorPool;
+ vkDescriptorSetAllocateInfo.descriptorSetCount = (uint32_t)1;
+ vkDescriptorSetAllocateInfo.pSetLayouts = &pkePipelines.descr_layouts.named.txtr;
+
+ vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, &ft->gr.vkDescriptorSet);
+ assert(vkResult == VK_SUCCESS);
+
+ VkDescriptorImageInfo textureDescriptorInfo;
+ textureDescriptorInfo.sampler = global_sampler;
+ textureDescriptorInfo.imageView = ft->gr.textureImageView;
+ textureDescriptorInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ VkWriteDescriptorSet writeDescriptorSet;
+ writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ writeDescriptorSet.pNext = nullptr;
+ writeDescriptorSet.dstSet = ft->gr.vkDescriptorSet;
+ writeDescriptorSet.dstBinding = (uint32_t)0;
+ writeDescriptorSet.dstArrayElement = (uint32_t)0;
+ writeDescriptorSet.descriptorCount = (uint32_t)1;
+ writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ writeDescriptorSet.pImageInfo = &textureDescriptorInfo;
+ writeDescriptorSet.pBufferInfo = nullptr;
+ writeDescriptorSet.pTexelBufferView = nullptr;
+
+ vkUpdateDescriptorSets(vkDevice, (uint32_t)1, &writeDescriptorSet, 0, nullptr);
+
+ } else {
+ free(txtr_bytes);
+ }
AM_Release(fontTextureHandle);
AM_Release(glyphsHandle);
@@ -727,6 +756,7 @@ void FontType_Unload(FontTypeIndex idx) {
ft->title.val = nullptr;
ft->title.length = 0;
}
+ ECS_MarkForRemoval(ft);
}
// TODO perf?
@@ -735,7 +765,7 @@ void FontType_Unload(FontTypeIndex idx) {
// However, the new buffer is exactly the length it needs to be and no greater.
// Consider using a heuristic to allocate a buffer larger than needed.
// At the time of writing, the only way to do this is to un-register text.
-FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent) {
+FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent, pk_uuid uuid) {
assert(settings != nullptr);
PKVK_TmpBufferDetails tmpBufferDetails{};
VkDeviceSize byteCount;
@@ -757,103 +787,157 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&
}
fr = &ft->renders[(FontRenderIndex_T)idx_fr];
*fr = {};
+ fr->uuid = uuid;
ECS_CreateEntity(fr, parent);
fr->fr_handle.index_ft = idx_ft;
fr->fr_handle.index_fr = idx_fr;
fr->settings = *settings;
fr->text = str;
- // insert new characters into tmp buffer
- {
- DynArray<uint32_t> glyph_indices;
- glyph_indices.Reserve(str.length);
- count = 0;
- for (i = 0; i < str.length;) {
- fgc = nullptr;
- u = 0;
- // determine unicode char
- ii = utf8_to_unicode(&str.val[i], u);
- if (ii == 0) {
- fprintf(stderr, "failed to determine unicode for character: at byte index: '%i'\n", i);
- i += 1;
- continue;
+ if (window != NULL) {
+ // insert new characters into tmp buffer
+ {
+ DynArray<uint32_t> glyph_indices;
+ glyph_indices.Reserve(str.length);
+ count = 0;
+ for (i = 0; i < str.length;) {
+ fgc = nullptr;
+ u = 0;
+ // determine unicode char
+ ii = utf8_to_unicode(&str.val[i], u);
+ if (ii == 0) {
+ fprintf(stderr, "failed to determine unicode for character: at byte index: '%i'\n", i);
+ i += 1;
+ continue;
+ }
+ i += ii;
+
+ // binary search for glyph details
+ l = 0;
+ r = ft->n_glyphs - 1;
+ do {
+ m = l + (r-l)/2;
+ fgc = &ft->glyphs[m];
+ if (fgc->unicode < u)
+ l = m + 1;
+ else
+ r = m - 1;
+ } while (fgc->unicode != u && l <= r);
+
+ if (fgc->unicode != u) {
+ fprintf(stderr, "font: '%s' does not contain unicode character '%u'\n", ft->title.val, u);
+ continue;
+ }
+ count += 1;
+ glyph_indices.Push(m);
}
- i += ii;
-
- // binary search for glyph details
- l = 0;
- r = ft->n_glyphs - 1;
- do {
- m = l + (r-l)/2;
- fgc = &ft->glyphs[m];
- if (fgc->unicode < u)
- l = m + 1;
- else
- r = m - 1;
- } while (fgc->unicode != u && l <= r);
-
- if (fgc->unicode != u) {
- fprintf(stderr, "font: '%s' does not contain unicode character '%u'\n", ft->title.val, u);
- continue;
+
+ // TODO specific bucket
+ fr->n_glyphs = count;
+ fr->glyph_indices = pk_new<uint32_t>(count);
+ for (i = 0; i < count; ++i) {
+ fr->glyph_indices[i] = glyph_indices[i];
}
- count += 1;
- glyph_indices.Push(m);
}
- // TODO specific bucket
- fr->n_glyphs = count;
- fr->glyph_indices = pk_new<uint32_t>(count);
- for (i = 0; i < count; ++i) {
- fr->glyph_indices[i] = glyph_indices[i];
- }
- }
+ VkDeviceSize item_count_orig = ft->bindings.instance_counter;
+ VkDeviceSize item_length_new = PK_MAX(ft->bindings.instance_buffer_max_count, ft->bindings.instance_counter + count);
+
+ // copy existing buffer to new buffer
+ // create new buffer
+ if (ft->bindings.instance_buffer_max_count < item_length_new) {
+ byteCount = sizeof(FontInstanceBufferItem) * item_length_new;
+ VkBuffer newBuffer;
+ VkBufferCreateInfo bufferCI;
+ bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ bufferCI.pNext = nullptr;
+ bufferCI.flags = {};
+ bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ bufferCI.queueFamilyIndexCount = 1;
+ bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex;
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ bufferCI.size = byteCount;
+ vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer);
+ assert(vkResult == VK_SUCCESS);
- VkDeviceSize item_count_orig = ft->bindings.instance_counter;
- VkDeviceSize item_length_new = PK_MAX(ft->bindings.instance_buffer_max_count, ft->bindings.instance_counter + count);
-
- // copy existing buffer to new buffer
- // create new buffer
- if (ft->bindings.instance_buffer_max_count < item_length_new) {
- byteCount = sizeof(FontInstanceBufferItem) * item_length_new;
- VkBuffer newBuffer;
- VkBufferCreateInfo bufferCI;
- bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- bufferCI.pNext = nullptr;
- bufferCI.flags = {};
- bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- bufferCI.queueFamilyIndexCount = 1;
- bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex;
- bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
- bufferCI.size = byteCount;
- vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer);
- assert(vkResult == VK_SUCCESS);
+ VkMemoryRequirements vkMemReqs;
+ vkGetBufferMemoryRequirements(vkDevice, newBuffer, &vkMemReqs);
+ assert(sizeof(FontInstanceBufferItem) % vkMemReqs.alignment == 0);
- VkMemoryRequirements vkMemReqs;
- vkGetBufferMemoryRequirements(vkDevice, newBuffer, &vkMemReqs);
- assert(sizeof(FontInstanceBufferItem) % vkMemReqs.alignment == 0);
+ vkDestroyBuffer(vkDevice, newBuffer, vkAllocator);
+ newBuffer = VK_NULL_HANDLE;
- vkDestroyBuffer(vkDevice, newBuffer, vkAllocator);
- newBuffer = VK_NULL_HANDLE;
+ bufferCI.size = vkMemReqs.size + (vkMemReqs.alignment - (vkMemReqs.size & vkMemReqs.alignment));
+ vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer);
+ assert(vkResult == VK_SUCCESS);
- bufferCI.size = vkMemReqs.size + (vkMemReqs.alignment - (vkMemReqs.size & vkMemReqs.alignment));
- vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer);
- assert(vkResult == VK_SUCCESS);
+ VkDeviceMemory new_memory;
+ VkMemoryAllocateInfo vkMemoryAllocateInfo;
+ vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ vkMemoryAllocateInfo.pNext = nullptr;
+ vkMemoryAllocateInfo.allocationSize = bufferCI.size;
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
- VkDeviceMemory new_memory;
- VkMemoryAllocateInfo vkMemoryAllocateInfo;
- vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- vkMemoryAllocateInfo.pNext = nullptr;
- vkMemoryAllocateInfo.allocationSize = bufferCI.size;
- vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ vkResult = vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &new_memory);
+ assert(vkResult == VK_SUCCESS);
- vkResult = vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &new_memory);
- assert(vkResult == VK_SUCCESS);
+ vkResult = vkBindBufferMemory(vkDevice, newBuffer, new_memory, 0);
+ assert(vkResult == VK_SUCCESS);
- vkResult = vkBindBufferMemory(vkDevice, newBuffer, new_memory, 0);
- assert(vkResult == VK_SUCCESS);
+ if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE && ft->bindings.instance_counter > 0) {
+ PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails, PKVK_TmpBufferFlags_NONE);
+
+ VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
+ vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkCommandBufferBeginInfo.pNext = nullptr;
+ // TODO consider single-use?
+ vkCommandBufferBeginInfo.flags = 0;
+ vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
+ vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
+ assert(vkResult == VK_SUCCESS);
+
+ VkBufferCopy vk_buffer_copy{};
+ vk_buffer_copy.srcOffset = 0;
+ vk_buffer_copy.dstOffset = 0;
+ vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter;
+ assert(vk_buffer_copy.size != 0);
+ vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, ft->bindings.bd_instance.buffer, newBuffer, 1, &vk_buffer_copy);
+
+ vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer);
+ assert(vkResult == VK_SUCCESS);
+
+ VkSubmitInfo submitInfo;
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.pNext = nullptr;
+ submitInfo.waitSemaphoreCount = 0;
+ submitInfo.pWaitSemaphores = nullptr;
+ submitInfo.pWaitDstStageMask = nullptr;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &tmpBufferDetails.cmdBuffer;
+ submitInfo.signalSemaphoreCount = 0;
+ submitInfo.pSignalSemaphores = nullptr;
+ vkResult = vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr);
+ assert(vkResult == VK_SUCCESS);
+ vkResult = vkQueueWaitIdle(tmpBufferDetails.queue);
+ assert(vkResult == VK_SUCCESS);
+
+ PKVK_EndBuffer(tmpBufferDetails, PKVK_TmpBufferFlags_NONE);
+ }
+ if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, ft->bindings.bd_instance.buffer, vkAllocator);
+ if (ft->gr.deviceMemoryInst != VK_NULL_HANDLE)
+ vkFreeMemory(vkDevice, ft->gr.deviceMemoryInst, vkAllocator);
- if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE && ft->bindings.instance_counter > 0) {
- PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails, PKVK_TmpBufferFlags_NONE);
+ ft->gr.deviceMemoryInst = new_memory;
+ ft->bindings.bd_instance.buffer = newBuffer;
+ }
+ ft->bindings.instance_buffer_max_count = item_length_new;
+ ft->bindings.instance_counter += count;
+
+ // create tmp local buffer & copy data to graphics card
+ byteCount = sizeof(FontInstanceBufferItem) * count;
+ PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails);
+ {
VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@@ -864,12 +948,13 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&
vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
assert(vkResult == VK_SUCCESS);
+ FontType_Inner_CalcTransforms(ft, fr, (FontInstanceBufferItem*)tmpBufferDetails.deviceData);
+
VkBufferCopy vk_buffer_copy{};
vk_buffer_copy.srcOffset = 0;
- vk_buffer_copy.dstOffset = 0;
- vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * ft->bindings.instance_counter;
- assert(vk_buffer_copy.size != 0);
- vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, ft->bindings.bd_instance.buffer, newBuffer, 1, &vk_buffer_copy);
+ vk_buffer_copy.dstOffset = sizeof(FontInstanceBufferItem) * item_count_orig;
+ vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * count;
+ vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->bindings.bd_instance.buffer, 1, &vk_buffer_copy);
vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer);
assert(vkResult == VK_SUCCESS);
@@ -888,65 +973,20 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&
assert(vkResult == VK_SUCCESS);
vkResult = vkQueueWaitIdle(tmpBufferDetails.queue);
assert(vkResult == VK_SUCCESS);
-
- PKVK_EndBuffer(tmpBufferDetails, PKVK_TmpBufferFlags_NONE);
}
- if (ft->bindings.bd_instance.buffer != VK_NULL_HANDLE)
- vkDestroyBuffer(vkDevice, ft->bindings.bd_instance.buffer, vkAllocator);
- if (ft->gr.deviceMemoryInst != VK_NULL_HANDLE)
- vkFreeMemory(vkDevice, ft->gr.deviceMemoryInst, vkAllocator);
-
- ft->gr.deviceMemoryInst = new_memory;
- ft->bindings.bd_instance.buffer = newBuffer;
- }
- ft->bindings.instance_buffer_max_count = item_length_new;
- ft->bindings.instance_counter += count;
-
- // create tmp local buffer & copy data to graphics card
- byteCount = sizeof(FontInstanceBufferItem) * count;
- PKVK_BeginBuffer(transferFamilyIndex, byteCount, tmpBufferDetails);
- {
-
- VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
- vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- vkCommandBufferBeginInfo.pNext = nullptr;
- // TODO consider single-use?
- vkCommandBufferBeginInfo.flags = 0;
- vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
- vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
- assert(vkResult == VK_SUCCESS);
-
- FontType_Inner_CalcTransforms(ft, fr, (FontInstanceBufferItem*)tmpBufferDetails.deviceData);
-
- VkBufferCopy vk_buffer_copy{};
- vk_buffer_copy.srcOffset = 0;
- vk_buffer_copy.dstOffset = sizeof(FontInstanceBufferItem) * item_count_orig;
- vk_buffer_copy.size = sizeof(FontInstanceBufferItem) * count;
- vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->bindings.bd_instance.buffer, 1, &vk_buffer_copy);
-
- vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer);
- assert(vkResult == VK_SUCCESS);
-
- VkSubmitInfo submitInfo;
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 0;
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.pWaitDstStageMask = nullptr;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &tmpBufferDetails.cmdBuffer;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- vkResult = vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr);
- assert(vkResult == VK_SUCCESS);
- vkResult = vkQueueWaitIdle(tmpBufferDetails.queue);
- assert(vkResult == VK_SUCCESS);
+ PKVK_EndBuffer(tmpBufferDetails);
}
- PKVK_EndBuffer(tmpBufferDetails);
return fr->fr_handle;
}
+FontRender *FontType_GetFontRender(FontRenderHandle frh) {
+ assert(frh.index_ft < ftd.h_ft);
+ FontType *ft = &ftd.arr_ft[static_cast<FontTypeIndex_T>(frh.index_ft)];
+ assert(frh.index_fr < ft->h_render);
+ return &ft->renders[static_cast<FontRenderIndex_T>(frh.index_fr)];
+}
+
void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings) {
assert(settings != nullptr);
assert((FontTypeIndex_T)ftd.h_ft > (FontTypeIndex_T)frh.index_ft);
diff --git a/src/font.hpp b/src/font.hpp
index d31209c..a8b1ecf 100644
--- a/src/font.hpp
+++ b/src/font.hpp
@@ -118,10 +118,12 @@ void FontType_Teardown();
void FontType_Tick(double delta);
void FontType_Serialize(std::ostream &stream, FontType *ft);
void FontType_Deserialize(std::istream &stream);
+FontType* FontType_Get(FontTypeIndex idx);
FontType* FontType_GetFonts(FontTypeIndex &count);
FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing);
void FontType_Unload(FontTypeIndex idx);
-FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent = nullptr);
+FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent = nullptr, pk_uuid uuid = pk_uuid_zed);
+FontRender *FontType_GetFontRender(FontRenderHandle frh);
void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings);
void FontType_RemoveStringRender(FontRenderHandle frh);
diff --git a/src/game.cpp b/src/game.cpp
index 5013c49..4ca5161 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -186,21 +186,19 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) {
// TODO remove me: temp stuff for testing
pke_ui_box *ui_box = pke_ui_box_new_root();
ui_box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC;
- ui_box->pos_top_left_x = 0.1;
- ui_box->pos_top_left_y = 0.1;
- ui_box->max_width = 0.8;
- ui_box->max_height = 0.8;
+ ui_box->pos_top_left.x = 0.1;
+ ui_box->pos_top_left.y = 0.1;
+ ui_box->max_size.x = 0.8;
+ ui_box->max_size.y = 0.8;
// TODO remove me: temp stuff for testing
pke_ui_box *c_ui_box = pke_ui_box_new_child(ui_box, PKE_UI_BOX_TYPE_TEXT);
c_ui_box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC;
- c_ui_box->pos_top_left_x = 20;
- c_ui_box->pos_top_left_y = 20;
- c_ui_box->max_width = 3000;
- c_ui_box->max_height = 3000;
- pke_ui_box_type_data_text *box_text = reinterpret_cast<pke_ui_box_type_data_text*>(c_ui_box->type_data);
- box_text->font_render_handle = fr_1;
- box_text->font_render_settings = fr_set;
+ c_ui_box->pos_top_left.x = 20;
+ c_ui_box->pos_top_left.y = 20;
+ c_ui_box->max_size.x = 3000;
+ c_ui_box->max_size.y = 3000;
+ c_ui_box->type_data->text.font_render_handle = fr_1;
GameTimePoint lastTimePoint = pkeSettings.steadyClock.now();
double deltaTillNextRender = pkeSettings.deltaPerFrame;
diff --git a/src/serialization-component.cpp b/src/serialization-component.cpp
index 3ff4d5d..4f65a5a 100644
--- a/src/serialization-component.cpp
+++ b/src/serialization-component.cpp
@@ -276,7 +276,7 @@ void pke_deserialize_instance(srlztn_deserialize_helper *h, pke_kve_container *k
inst_pos.posRot.setOrigin(bt_pos);
inst_pos.posRot.setRotation(bt_quat);
pk_arr_t<CompInstance *> instances;
- srlztn_instance_mapping map{};
+ srlztn_ecs_mapping map{};
map.serialized_uuid = comp.uuid;
if (et_ptr != nullptr) {
if (et_ptr->createInstanceCallback.func != nullptr) {
diff --git a/src/serialization-font.cpp b/src/serialization-font.cpp
index 761643c..b57e6e7 100644
--- a/src/serialization-font.cpp
+++ b/src/serialization-font.cpp
@@ -1,13 +1,16 @@
#include "serialization-font.hpp"
+#include "ecs.hpp"
+#include "font.hpp"
#include "pk.h"
+#include "serialization.hpp"
pk_handle pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr) {
assert(h != nullptr);
assert(fr != nullptr);
char *s;
- pk_handle inst_pos_handle;
+ pk_handle font_render_settings_handle;
pke_kve kve{};
pke_kve_container kvec{};
@@ -15,55 +18,88 @@ pk_handle pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr)
return PK_HANDLE_MAX;
}
+ font_render_settings_handle = pke_serialize_font_render_settings(h, &fr->settings);
+
kvec.srlztn_handle = h->handle_head;
- kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_CAMERA);
+ kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_FONT_RENDER);
kvec.bkt = h->bkt;
kvec.arr.bkt = h->bkt;
kvec.children.bkt = h->bkt;
kvec.child_handles.bkt = h->bkt;
h->handle_head.itemIndex++;
- pk_arr_append_t(&kvec.child_handles, inst_pos_handle);
+ pk_arr_append_t(&kvec.child_handles, font_render_settings_handle);
- if (fr->uuid != pk_uuid_zed && fr->uuid != pk_uuid_max) {
- kve.key = SRLZTN_UI_BOX_UUID;
+ {
+ kve.key = SRLZTN_UI_FONT_RENDER_UUID;
s = pk_new<char>(37, h->bkt);
sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(fr->uuid));
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
+ {
+ kve.key = SRLZTN_UI_FONT_RENDER_FONT_TYPE_UUID;
+ s = pk_new<char>(37, h->bkt);
+ FontType *ft = FontType_Get(fr->fr_handle.index_ft);
+ sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(ft->uuid));
+ kve.val = s;
+ kve.end = SRLZTN_KVE_END;
+ pk_arr_append_t(&kvec.arr, kve);
+ }
if (fr->text.val != nullptr) {
kve.key = SRLZTN_UI_FONT_RENDER_TEXT_BEGIN;
- s = pk_new<char>(fr->text.reserved, h->bkt);
- sprintf(s, "%s", fr->text.val);
+ s = pk_new<char>(strlen(fr->text.val) + 3, h->bkt);
+ sprintf(s, "\n%s\n", fr->text.val);
kve.val = s;
kve.end = SRLZTN_MULTILINE_END;
pk_arr_append_t(&kvec.arr, kve);
}
pk_arr_append_t(&h->kvp_containers, kvec);
- return pke_serialize_font_render_settings(h, &fr->settings);
+ kvec.arr.data = nullptr;
+ kvec.children.data = nullptr;
+ kvec.child_handles.data = nullptr;
+ return kvec.srlztn_handle;
}
-void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRender *fr) {
+void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec) {
assert(h != nullptr);
- assert(fr != nullptr);
+ assert(kvec != nullptr);
+ assert(kvec->children.next == 1);
+
+ pke_kve *kve = nullptr;
+ pk_uuid uuid;
+ pk_uuid font_type_uuid;
+ pk_cstr str;
+ FontRenderSettings frs{};
+ pke_deserialize_font_render_settings(h, kvec->children[0], &frs);
+
uint32_t i;
char *s;
for (i = 0; i < kvec->arr.next; ++i) {
- if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_UUID, strlen(SRLZTN_UI_FONT_RENDER_UUID)) == 0) {
- kvec->arr[i].val >> fr->uuid;
+ kve = &kvec->arr[i];
+ if (strcmp(kve->key, SRLZTN_UI_FONT_RENDER_UUID) == 0) {
+ kve->val >> uuid;
+ continue;
+ }
+ if (strcmp(kve->key, SRLZTN_UI_FONT_RENDER_FONT_TYPE_UUID) == 0) {
+ kve->val >> font_type_uuid;
continue;
}
- if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_TEXT_BEGIN, strlen(SRLZTN_UI_FONT_RENDER_TEXT_BEGIN)) == 0) {
- fr->text.length = strlen(kvec->arr[i].val) + 1;
- fr->text.reserved = fr->text.reserved + 1;
- // TODO specific bkt
- s = pk_new<char>(fr->text.reserved, NULL);
- fr->text.val = s;
+ if (strcmp(kve->key, SRLZTN_UI_FONT_RENDER_TEXT_BEGIN) == 0) {
+ str.length = strlen(kve->val) + 1;
+ str.reserved = str.length + 1;
+ // TODO specific bkt?
+ s = pk_new<char>(str.reserved, NULL);
+ sprintf(s, "%s", kve->val);
+ str.val = s;
continue;
}
}
+
+ FontType *font_type_ent = static_cast<FontType *>(ECS_GetEntityByUUID(font_type_uuid));
+ // parent is set later - up to the parent to take ownership
+ FontType_AddStringRender(font_type_ent->index_ft, std::move(str), &frs, nullptr, uuid);
}
pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRenderSettings *frs) {
@@ -80,7 +116,7 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen
kvec.child_handles.bkt = h->bkt;
h->handle_head.itemIndex++;
- if (frs->char_scale != 0.0) {
+ {
kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE;
len = snprintf(NULL, 0, "%f", frs->char_scale);
s = pk_new<char>(len+1, h->bkt);
@@ -89,7 +125,7 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (frs->line_height_scale != 0.0) {
+ {
kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE;
len = snprintf(NULL, 0, "%f", frs->line_height_scale);
s = pk_new<char>(len+1, h->bkt);
@@ -98,7 +134,7 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (frs->char_spacing_scale != 0.0) {
+ {
kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE;
len = snprintf(NULL, 0, "%f", frs->char_spacing_scale);
s = pk_new<char>(len+1, h->bkt);
@@ -107,25 +143,25 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (frs->surface_area_size != glm::ivec2(0)) {
+ {
kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE;
- len = snprintf(NULL, 0, "%d, %d", frs->surface_area_size.x, frs->surface_area_size.y);
+ len = snprintf(NULL, 0, "%d%s%d", frs->surface_area_size.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_size.y);
s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%d, %d", frs->surface_area_size.x, frs->surface_area_size.y);
+ sprintf(s, "%d%s%d", frs->surface_area_size.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_size.y);
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (frs->surface_area_pos != glm::ivec2(0)) {
+ {
kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS;
- len = snprintf(NULL, 0, "%d, %d", frs->surface_area_pos.x, frs->surface_area_pos.y);
+ len = snprintf(NULL, 0, "%d%s%d", frs->surface_area_pos.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_pos.y);
s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%d, %d", frs->surface_area_pos.x, frs->surface_area_pos.y);
+ sprintf(s, "%d%s%d", frs->surface_area_pos.x, SRLZTN_NUM_SEPARATOR, frs->surface_area_pos.y);
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (frs->surface_area_type_flags != FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_NONE) {
+ {
kve.key = SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS;
s = pk_new<char>(5, h->bkt);
sprintf(s, "0x%.2X", FONT_RENDER_SURFACE_AREA_TYPE_FLAG_T(frs->surface_area_type_flags));
@@ -135,12 +171,16 @@ pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRen
}
pk_arr_append_t(&h->kvp_containers, kvec);
+ kvec.arr.data = nullptr;
+ kvec.children.data = nullptr;
+ kvec.child_handles.data = nullptr;
return kvec.srlztn_handle;
}
void pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRenderSettings *frs) {
(void)h;
- uint32_t i;
+ uint32_t i, index;
+ const char *starting_char;
PK_STN_RES stn_res;
char *str_end;
for (i = 0; i < kvec->arr.next; ++i) {
@@ -166,29 +206,31 @@ void pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, pke_kve_
continue;
}
if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE)) == 0) {
- stn_res = pk_stn(&frs->surface_area_size.x, kvec->arr[i].val, &str_end);
- if (stn_res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[%s] Err '%u' parsing '%s' (x) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, kvec->arr[i].val);
- continue;
- }
- size_t prefix_len = strchr(kvec->arr[i].val, ',') - (kvec->arr[i].val);
- stn_res = pk_stn(&frs->surface_area_size.y, kvec->arr[i].val + prefix_len, &str_end);
- if (stn_res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[%s] Err '%u' parsing '%s' (y) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, kvec->arr[i].val);
- }
+ starting_char = kvec->arr[i].val;
+ index = 0;
+ do {
+ assert(index < 2);
+ stn_res = pk_stn(&frs->surface_area_size[index], starting_char, &str_end);
+ if (stn_res != PK_STN_RES_SUCCESS) {
+ fprintf(stderr, "[%s] Err '%u' parsing '%s'[%i] from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, index, kvec->arr[i].val);
+ }
+ starting_char = str_end + 1;
+ ++index;
+ } while (*str_end != '\0');
continue;
}
if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS)) == 0) {
- stn_res = pk_stn(&frs->surface_area_pos.x, kvec->arr[i].val, &str_end);
- if (stn_res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[%s] Err '%u' parsing '%s' (x) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, kvec->arr[i].val);
- continue;
- }
- size_t prefix_len = strchr(kvec->arr[i].val, ',') - (kvec->arr[i].val);
- stn_res = pk_stn(&frs->surface_area_pos.y, kvec->arr[i].val + prefix_len, &str_end);
- if (stn_res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[%s] Err '%u' parsing '%s' (y) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, kvec->arr[i].val);
- }
+ starting_char = kvec->arr[i].val;
+ index = 0;
+ do {
+ assert(index < 2);
+ stn_res = pk_stn(&frs->surface_area_pos[index], starting_char, &str_end);
+ if (stn_res != PK_STN_RES_SUCCESS) {
+ fprintf(stderr, "[%s] Err '%u' parsing '%s'[%i] from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, index, kvec->arr[i].val);
+ }
+ starting_char = str_end + 1;
+ ++index;
+ } while (*str_end != '\0');
continue;
}
if (strncmp(kvec->arr[i].key, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS)) == 0) {
diff --git a/src/serialization-font.hpp b/src/serialization-font.hpp
index e41f974..c12dc13 100644
--- a/src/serialization-font.hpp
+++ b/src/serialization-font.hpp
@@ -5,7 +5,7 @@
#include "font.hpp"
pk_handle pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr);
-void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRender *fr);
+void pke_deserialize_font_render(srlztn_deserialize_helper *h, pke_kve_container *kvec);
pk_handle pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRenderSettings *frs);
void pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, pke_kve_container *kvec, FontRenderSettings *frs);
diff --git a/src/serialization-static-ui.cpp b/src/serialization-static-ui.cpp
index 447e7d0..4c45cc1 100644
--- a/src/serialization-static-ui.cpp
+++ b/src/serialization-static-ui.cpp
@@ -1,50 +1,56 @@
#include "serialization-static-ui.hpp"
#include "ecs.hpp"
+#include "font.hpp"
#include "pk.h"
-#include "serialization-font.hpp"
#include "static-ui.hpp"
-pk_handle pke_serialize_ui_box_internal(srlztn_serialize_helper *h, pke_ui_box_type_data_text *data) {
+pk_handle pke_serialize_ui_box_internal(srlztn_serialize_helper *h, pke_ui_box_type_data::pke_ui_box_type_data_text *data) {
char *s;
- pk_handle font_render_handle;
pke_kve kve{};
pke_kve_container kvec{};
- font_render_handle = pke_serialize_font_render_settings(h, &data->font_render_settings);
-
kvec.srlztn_handle = h->handle_head;
- kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_UI_BOX);
+ kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_UI_BOX_TYPE_DATA);
kvec.bkt = h->bkt;
kvec.arr.bkt = h->bkt;
kvec.children.bkt = h->bkt;
kvec.child_handles.bkt = h->bkt;
h->handle_head.itemIndex++;
- if (font_render_handle != PK_HANDLE_MAX) {
- pk_arr_append_t(&kvec.child_handles, font_render_handle);
- }
- if (data->font_render_uuid != pk_uuid_zed) {
+ {
kve.key = SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID;
s = pk_new<char>(37, h->bkt);
- sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(data->font_render_uuid));
+ FontRender *fr = FontType_GetFontRender(data->font_render_handle);
+ sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(fr->uuid));
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
pk_arr_append_t(&h->kvp_containers, kvec);
+ kvec.arr.data = nullptr;
+ kvec.children.data = nullptr;
+ kvec.child_handles.data = nullptr;
return kvec.srlztn_handle;
}
-void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_container *kvec, pke_ui_box_type_data_text *data) {
- assert(kvec->children.next == 1);
-
- pke_deserialize_font_render_settings(h, kvec, &data->font_render_settings);
+void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_container *kvec, pke_ui_box_type_data::pke_ui_box_type_data_text *data) {
+ (void)h;
+ assert(kvec != nullptr);
+ assert(data != nullptr);
+ assert(kvec->arr.next == 1);
+ pk_uuid font_render_uuid = pk_uuid_zed;
if (strstr(SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID, kvec->arr[0].key)) {
- kvec->arr[0].val >> data->font_render_uuid;
+ kvec->arr[0].val >> font_render_uuid;
}
+
+ assert(font_render_uuid != pk_uuid_zed);
+
+ FontRender *fr = static_cast<FontRender *>(ECS_GetEntityByUUID(font_render_uuid));
+
+ data->font_render_handle = fr->fr_handle;
}
pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) {
@@ -55,8 +61,7 @@ pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) {
pke_kve_container kvec{};
if (box->type == PKE_UI_BOX_TYPE_TEXT) {
- pke_ui_box_type_data_text *d = reinterpret_cast<pke_ui_box_type_data_text *>(box->type_data);
- internal_type_handle = pke_serialize_ui_box_internal(h, d);
+ internal_type_handle = pke_serialize_ui_box_internal(h, &box->type_data->text);
}
kvec.srlztn_handle = h->handle_head;
@@ -95,61 +100,34 @@ pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) {
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (box->pos_top_left_x != 0.0) {
- kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT_X;
- len = snprintf(NULL, 0, "%f", box->pos_top_left_x);
- s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%f", box->pos_top_left_x);
- kve.val = s;
- kve.end = SRLZTN_KVE_END;
- pk_arr_append_t(&kvec.arr, kve);
- }
- if (box->pos_top_left_y != 0.0) {
- kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT_Y;
- len = snprintf(NULL, 0, "%f", box->pos_top_left_y);
+ {
+ kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT;
+ len = snprintf(NULL, 0, "%f;%f", box->pos_top_left.x, box->pos_top_left.y);
s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%f", box->pos_top_left_y);
+ sprintf(s, "%f;%f", box->pos_top_left.x, box->pos_top_left.y);
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (box->min_width != 0.0) {
- kve.key = SRLZTN_UI_BOX_MIN_WIDTH;
- len = snprintf(NULL, 0, "%f", box->min_width);
+ if (box->min_size != glm::vec2(0,0)) {
+ kve.key = SRLZTN_UI_BOX_MIN_SIZE;
+ len = snprintf(NULL, 0, "%f;%f", box->min_size.x, box->min_size.y);
s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%f", box->min_width);
+ sprintf(s, "%f%f", box->min_size.x, box->min_size.y);
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (box->min_height != 0.0) {
- kve.key = SRLZTN_UI_BOX_MIN_HEIGHT;
- len = snprintf(NULL, 0, "%f", box->min_height);
+ if (box->max_size != glm::vec2(0,0)) {
+ kve.key = SRLZTN_UI_BOX_MAX_SIZE;
+ len = snprintf(NULL, 0, "%f;%f", box->max_size[0], box->max_size[1]);
s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%f", box->min_height);
+ sprintf(s, "%f;%f", box->max_size[0], box->max_size[1]);
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (box->max_width != 0.0) {
- kve.key = SRLZTN_UI_BOX_MAX_WIDTH;
- len = snprintf(NULL, 0, "%f", box->max_width);
- s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%f", box->max_width);
- kve.val = s;
- kve.end = SRLZTN_KVE_END;
- pk_arr_append_t(&kvec.arr, kve);
- }
- if (box->max_height != 0.0) {
- kve.key = SRLZTN_UI_BOX_MAX_HEIGHT;
- len = snprintf(NULL, 0, "%f", box->max_height);
- s = pk_new<char>(len+1, h->bkt);
- sprintf(s, "%f", box->max_height);
- kve.val = s;
- kve.end = SRLZTN_KVE_END;
- pk_arr_append_t(&kvec.arr, kve);
- }
- if (box->flex_weight != 0.0) {
+ if (box->flex_weight != 0.f) {
kve.key = SRLZTN_UI_BOX_FLEX_WEIGHT;
len = snprintf(NULL, 0, "%f", box->flex_weight);
s = pk_new<char>(len+1, h->bkt);
@@ -157,33 +135,35 @@ pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) {
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
- }
- if (box->type != PKE_UI_BOX_TYPE_STANDARD) {
- kve.key = SRLZTN_UI_BOX_FLAGS;
+ // only serialize if we're using flex
+ kve.key = SRLZTN_UI_BOX_FLEX_DIRECTION;
s = pk_new<char>(5, h->bkt);
- sprintf(s, "0x%.2X", static_cast<PKE_UI_BOX_TYPE_T>(box->type));
+ sprintf(s, "0x%.2X", box->flex_direction);
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (box->flex_direction != 0) {
- kve.key = SRLZTN_UI_BOX_FLEX_DIRECTION;
+ {
+ kve.key = SRLZTN_UI_BOX_TYPE;
s = pk_new<char>(5, h->bkt);
- sprintf(s, "%u", box->flex_direction);
+ sprintf(s, "0x%.2X", static_cast<PKE_UI_BOX_TYPE_T>(box->type));
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
- if (box->layer != 0) {
+ {
kve.key = SRLZTN_UI_BOX_LAYER;
s = pk_new<char>(5, h->bkt);
- sprintf(s, "%u", box->layer);
+ sprintf(s, "0x%.2X", box->layer);
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
}
pk_arr_append_t(&h->kvp_containers, kvec);
+ kvec.arr.data = nullptr;
+ kvec.children.data = nullptr;
+ kvec.child_handles.data = nullptr;
return kvec.srlztn_handle;
}
@@ -200,35 +180,34 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve
*
*/
- uint32_t i;
- uint64_t prefix_len;
+ uint32_t i, index;
PK_STN_RES res;
+ const char *starting_char;
char *stn_end;
+ pke_kve *kve;
pke_ui_box bx{};
pke_ui_box *parent_box = nullptr;
bx.type_data = nullptr;
for (i = 0; i < kvec->arr.next; ++i) {
- if (strstr(SRLZTN_UI_BOX_UUID, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_UUID);
- (kvec->arr[i].val + prefix_len) >> bx.uuid;
+ kve = &kvec->arr[i];
+ if (strstr(SRLZTN_UI_BOX_UUID, kve->key)) {
+ kve->val >> bx.uuid;
continue;
}
- if (strstr(SRLZTN_UI_BOX_PARENT_UUID, kvec->arr[i].key)) {
+ if (strstr(SRLZTN_UI_BOX_PARENT_UUID, kve->key)) {
uint32_t target_instance_index = -1;
pk_uuid id;
- prefix_len = strlen(SRLZTN_UI_BOX_PARENT_UUID);
- (kvec->arr[i].val + prefix_len) >> id;
+ kve->val >> id;
target_instance_index = pk_arr_find_first_index(&h->mapping, &id, srlztn_mapping_find_first_handle_by_uuid);
if (target_instance_index != uint32_t(-1)) {
parent_box = static_cast<pke_ui_box*>(h->mapping[target_instance_index].created_entity);
}
continue;
}
- if (strstr(SRLZTN_UI_BOX_FLAGS, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_FLAGS);
+ if (strstr(SRLZTN_UI_BOX_FLAGS, kve->key)) {
PKE_UI_BOX_FLAG_T flags;
- res = pk_stn(&flags, kvec->arr[i].val + prefix_len, &stn_end);
+ res = pk_stn(&flags, kve->val, &stn_end, 16);
if (res != PK_STN_RES_SUCCESS) {
fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_FLAGS, res);
continue;
@@ -236,125 +215,110 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve
bx.flags = PKE_UI_BOX_FLAG(flags);
continue;
}
- if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT_X, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_X);
- res = pk_stn(&bx.pos_top_left_x, kvec->arr[i].val + prefix_len, &stn_end);
- if (res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_POS_TOP_LEFT_X, res);
- continue;
- }
- continue;
- }
- if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT_Y, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_Y);
- res = pk_stn(&bx.pos_top_left_y, kvec->arr[i].val + prefix_len, &stn_end);
- if (res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_POS_TOP_LEFT_Y, res);
- continue;
- }
- continue;
- }
- if (strstr(SRLZTN_UI_BOX_MIN_WIDTH, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_MIN_WIDTH);
- res = pk_stn(&bx.min_width, kvec->arr[i].val + prefix_len, &stn_end);
- if (res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MIN_WIDTH, res);
- continue;
- }
- continue;
- }
- if (strstr(SRLZTN_UI_BOX_MIN_HEIGHT, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_MIN_HEIGHT);
- res = pk_stn(&bx.min_width, kvec->arr[i].val + prefix_len, &stn_end);
+ if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT, kve->key)) {
+ starting_char = kve->val;
+ index = 0;
+ do {
+ assert(index < 2);
+ res = pk_stn(&bx.pos_top_left[index], starting_char, &stn_end);
+ if (res != PK_STN_RES_SUCCESS) break;
+ starting_char = stn_end + 1;
+ ++index;
+ } while (*stn_end != '\0');
if (res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MIN_HEIGHT, res);
- continue;
+ fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_POS_TOP_LEFT, res);
}
continue;
}
- if (strstr(SRLZTN_UI_BOX_MAX_WIDTH, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_MAX_WIDTH);
- res = pk_stn(&bx.max_width, kvec->arr[i].val + prefix_len, &stn_end);
+ if (strstr(SRLZTN_UI_BOX_MIN_SIZE, kve->key)) {
+ starting_char = kve->val;
+ index = 0;
+ do {
+ assert(index < 2);
+ res = pk_stn(&bx.min_size[index], starting_char, &stn_end);
+ if (res != PK_STN_RES_SUCCESS) break;
+ starting_char = stn_end + 1;
+ ++index;
+ } while (*stn_end != '\0');
if (res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MAX_WIDTH, res);
- continue;
+ fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MIN_SIZE, res);
}
continue;
}
- if (strstr(SRLZTN_UI_BOX_MAX_HEIGHT, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_MAX_HEIGHT);
- res = pk_stn(&bx.max_width, kvec->arr[i].val + prefix_len, &stn_end);
+ if (strstr(SRLZTN_UI_BOX_MAX_SIZE, kve->key)) {
+ starting_char = kve->val;
+ index = 0;
+ do {
+ assert(index < 2);
+ res = pk_stn(&bx.max_size[index], starting_char, &stn_end);
+ if (res != PK_STN_RES_SUCCESS) break;
+ starting_char = stn_end + 1;
+ ++index;
+ } while (*stn_end != '\0');
if (res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MAX_HEIGHT, res);
- continue;
+ fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_MAX_SIZE, res);
}
continue;
}
- if (strstr(SRLZTN_UI_BOX_FLEX_WEIGHT, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_FLEX_WEIGHT);
- res = pk_stn(&bx.flex_weight, kvec->arr[i].val + prefix_len, &stn_end);
+ if (strstr(SRLZTN_UI_BOX_FLEX_WEIGHT, kve->key)) {
+ res = pk_stn(&bx.flex_weight, kve->val, &stn_end);
if (res != PK_STN_RES_SUCCESS) {
fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_FLEX_WEIGHT, res);
continue;
}
continue;
}
- if (strstr(SRLZTN_UI_BOX_FLEX_DIRECTION, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_FLEX_DIRECTION);
- res = pk_stn(&bx.flex_direction, kvec->arr[i].val + prefix_len, &stn_end);
+ if (strstr(SRLZTN_UI_BOX_FLEX_DIRECTION, kve->key)) {
+ res = pk_stn(&bx.flex_direction, kve->val, &stn_end);
if (res != PK_STN_RES_SUCCESS) {
fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_FLEX_DIRECTION, res);
continue;
}
continue;
}
- if (strstr(SRLZTN_UI_BOX_LAYER, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_LAYER);
- res = pk_stn(&bx.layer, kvec->arr[i].val + prefix_len, &stn_end);
+ if (strstr(SRLZTN_UI_BOX_LAYER, kve->key)) {
+ res = pk_stn(&bx.layer, kve->val, &stn_end);
if (res != PK_STN_RES_SUCCESS) {
fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_LAYER, res);
continue;
}
continue;
}
- if (strstr(SRLZTN_UI_BOX_TYPE, kvec->arr[i].key)) {
- prefix_len = strlen(SRLZTN_UI_BOX_TYPE);
- res = pk_stn(&bx.type, kvec->arr[i].val + prefix_len, &stn_end);
+ if (strstr(SRLZTN_UI_BOX_TYPE, kve->key)) {
+ uint8_t v;
+ res = pk_stn<uint8_t>(&v, kve->val, &stn_end);
if (res != PK_STN_RES_SUCCESS) {
- fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_TYPE, res);
+ fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse '%s' from '%s', err: %i\n", SRLZTN_UI_BOX_TYPE, kve->val, res);
continue;
}
- // TODO specific bucket?
+ // log warning for unknown
+ bx.type = PKE_UI_BOX_TYPE{v};
switch (bx.type) {
+ case PKE_UI_BOX_TYPE_STANDARD:
case PKE_UI_BOX_TYPE_TEXT:
+ case PKE_UI_BOX_TYPE_INPUT_TEXT:
break;
default:
- fprintf(stderr, "[pke_deserialize_ui_box] Parsed unknown ui box data type from: '%s'\n", kvec->arr[i].val);
+ fprintf(stderr, "[pke_deserialize_ui_box] Parsed unknown ui box data type from: '%s'\n", kve->val);
continue;
}
continue;
}
}
- // get ready to deserialize children
+ // deserialize data
+ // TODO specific bucket?
if (bx.type != PKE_UI_BOX_TYPE_STANDARD) {
+ bx.type_data = pk_new<pke_ui_box_type_data>();
switch (bx.type) {
case PKE_UI_BOX_TYPE_TEXT:
- bx.type_data = pk_new<pke_ui_box_type_data_text>();
+ pke_deserialize_ui_box_internal(h, kvec->children[0], &bx.type_data->text);
break;
default:
break;
}
}
- // deserialize children
- for (i = 0; i < kvec->children.next; ++i) {
- pke_kve_container *child_kvec = kvec->children[i];
- if (strcmp(child_kvec->type_code.val, SRLZTN_OBJ_UI_BOX_TYPE_DATA) == 0) {
- pke_deserialize_ui_box_internal(h, child_kvec, static_cast<pke_ui_box_type_data_text*>(bx.type_data));
- }
- }
-
pke_ui_box *box;
if (parent_box == nullptr) {
box = pke_ui_box_new_root(bx.type, bx.uuid);
@@ -362,31 +326,31 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve
box = pke_ui_box_new_child(parent_box, bx.type, bx.uuid);
}
box->flags = bx.flags;
- box->pos_top_left_x = bx.pos_top_left_x;
- box->pos_top_left_y = bx.pos_top_left_y;
- box->min_width = bx.min_width;
- box->min_height = bx.min_height;
- box->max_width = bx.max_width;
- box->max_height = bx.max_height;
+ box->pos_top_left = bx.pos_top_left;
+ box->min_size = bx.min_size;
+ box->max_size = bx.max_size;
box->flex_weight = bx.flex_weight;
box->type = bx.type;
box->flex_direction = bx.flex_direction;
box->layer = bx.layer;
- // TODO clone functions?
- // might not be necessary if we refactor deserialization into their own ctors
- if (bx.type != PKE_UI_BOX_TYPE_STANDARD) {
- switch (bx.type) {
- case PKE_UI_BOX_TYPE_TEXT:
- reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data )->font_render_uuid
- = reinterpret_cast<pke_ui_box_type_data_text*>(bx.type_data)->font_render_uuid;
- reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data )->font_render_handle
- = reinterpret_cast<pke_ui_box_type_data_text*>(bx.type_data)->font_render_handle;
- reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data )->font_render_settings
- = reinterpret_cast<pke_ui_box_type_data_text*>(bx.type_data)->font_render_settings;
- break;
- default:
- break;
+ // TODO consider type-specific clone functions
+ if (box->type_data != nullptr && bx.type_data != nullptr) {
+ *box->type_data = *box->type_data;
+ pk_delete<pke_ui_box_type_data>(bx.type_data);
+ bx.type_data = nullptr;
+ }
+
+ srlztn_ecs_mapping map{};
+ map.serialized_uuid = bx.uuid;
+ map.created_entity = box;
+ pk_arr_append_t(&h->mapping, map);
+
+ // recursively deserialize children
+ for (i = 0; i < kvec->children.next; ++i) {
+ pke_kve_container *child_kvec = kvec->children[i];
+ if (strcmp(child_kvec->type_code.val, SRLZTN_OBJ_UI_BOX) == 0) {
+ pke_deserialize_ui_box(h, child_kvec);
}
}
diff --git a/src/serialization.cpp b/src/serialization.cpp
index ce2dbd3..352ecc9 100644
--- a/src/serialization.cpp
+++ b/src/serialization.cpp
@@ -1,13 +1,17 @@
#include "serialization.hpp"
+#include "font.hpp"
#include "pk.h"
#include "serialization-component.hpp"
#include "serialization-camera.hpp"
#include "camera.hpp"
#include "ecs.hpp"
+#include "serialization-font.hpp"
+#include "serialization-static-ui.hpp"
+#include "static-ui.hpp"
bool srlztn_mapping_find_first_handle_by_uuid(void *handle, void *mapping) {
- srlztn_instance_mapping *inst_mapping = reinterpret_cast<srlztn_instance_mapping *>(mapping);
+ srlztn_ecs_mapping *inst_mapping = reinterpret_cast<srlztn_ecs_mapping *>(mapping);
return inst_mapping->serialized_uuid == *reinterpret_cast<pk_uuid *>(handle);
}
bool srlztn_kvec_find_first_by_handle(void *handle, void *container) {
@@ -27,10 +31,10 @@ srlztn_serialize_helper *pke_serialize_init(pk_membucket *bkt) {
srlztn_deserialize_helper *pke_deserialize_init(pk_membucket *bkt) {
srlztn_deserialize_helper *helper = pk_new<srlztn_deserialize_helper>(bkt);
helper->bkt = bkt;
+ helper->kvp_containers = {};
helper->kvp_containers.bkt = bkt;
+ helper->mapping = {};
helper->mapping.bkt = bkt;
- pk_arr_reset(&helper->kvp_containers);
- pk_arr_reset(&helper->mapping);
pk_arr_reserve(&helper->kvp_containers, 1);
pk_arr_reserve(&helper->mapping, 1);
return helper;
@@ -60,6 +64,27 @@ void pke_deserialize_project_from_stream(std::istream &i, srlztn_deserialize_hel
}
void pke_serialize_scene(srlztn_serialize_helper *h) {
+ FontTypeIndex font_type_count;
+ FontType *fonts = FontType_GetFonts(font_type_count);
+ for (FontTypeIndex_T b = 0; b < (FontTypeIndex_T)font_type_count; ++b) {
+ FontType *fr = &fonts[b];
+ if (PK_HAS_FLAG(fr->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) {
+ continue;
+ }
+ for (FontRenderIndex_T i = 0; i < (FontRenderIndex_T)fr->h_render; ++i) {
+ pke_serialize_font_render(h, &fr->renders[i]);
+ }
+ }
+
+ pke_ui_box_count_T box_count;
+ pke_ui_box **ui_boxes = pke_ui_get_root_boxes(&box_count);
+ for (pke_ui_box_count_T i = 0; i < box_count; ++i) {
+ if (PK_HAS_FLAG(ui_boxes[i]->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) {
+ continue;
+ }
+ pke_serialize_ui_box(h, ui_boxes[i]);
+ }
+
pk_handle_bucket_index_T instanceBucketCount = ECS_GetInstances_BucketCount();
for (pk_handle_bucket_index_T b = 0; b < instanceBucketCount; ++b) {
pk_handle_item_index_T count;
@@ -91,11 +116,19 @@ void pke_deserialize_scene(srlztn_deserialize_helper *h) {
for (i = 0; i < h->kvp_containers.next; ++i) {
kvec = &h->kvp_containers[i];
- if (strstr(kvec->type_code.val, SRLZTN_OBJ_INSTANCE) != nullptr) {
+ if (strcmp(kvec->type_code.val, SRLZTN_OBJ_FONT_RENDER) == 0) {
+ pke_deserialize_font_render(h, kvec);
+ continue;
+ }
+ if (strcmp(kvec->type_code.val, SRLZTN_OBJ_UI_BOX) == 0) {
+ pke_deserialize_ui_box(h, kvec);
+ continue;
+ }
+ if (strcmp(kvec->type_code.val, SRLZTN_OBJ_INSTANCE) == 0) {
pke_deserialize_instance(h, kvec);
continue;
}
- if (strstr(kvec->type_code.val, SRLZTN_OBJ_CAMERA) != nullptr) {
+ if (strcmp(kvec->type_code.val, SRLZTN_OBJ_CAMERA) == 0) {
pke_deserialize_camera(h, kvec);
continue;
}
@@ -195,10 +228,13 @@ void pke_deserialize_scene_from_stream(std::istream &i, srlztn_deserialize_helpe
} else if (state == 1 && strlen(read_line) > 0) { // kve start
offset = strchr(read_line, ':') - read_line;
s = pk_new<char>(strlen(read_line) + 1);
- sprintf(s, "%.*s", (int)offset+1, read_line);
- kve.key = s;
if (strstr(read_line, "::")) {
+ offset += 1;
state = 2;
+ }
+ sprintf(s, "%.*s", (int)offset+1, read_line);
+ kve.key = s;
+ if (state == 2) {
continue;
}
read_line[offset] = '\0';
@@ -217,21 +253,23 @@ void pke_deserialize_scene_from_stream(std::istream &i, srlztn_deserialize_helpe
state = 3;
continue;
}
- if (state == 3) {
- rl = pk_new<char>(strlen(s) + strlen(read_line) + 1, h->bkt);
- sprintf(rl, "%s%s", s, read_line);
- pk_delete<char>(s, strlen(s) + 1, h->bkt);
- s = rl;
- continue;
- }
// multiline end
if (strstr(read_line, SRLZTN_MULTILINE_END)) {
assert(state >= 2);
+ kve.val = s;
kve.end = SRLZTN_MULTILINE_END;
pk_arr_append_t(&kvec.arr, kve);
state = 1;
continue;
}
+ if (state == 3) {
+ int sz = snprintf(NULL, 0, "%s%s", s, read_line);
+ rl = pk_new<char>(sz+1, h->bkt);
+ sprintf(rl, "%s%s", s, read_line);
+ pk_delete<char>(s, strlen(s) + 1, h->bkt);
+ s = rl;
+ continue;
+ }
// end of object
if (state != 2) {
state = 0;
diff --git a/src/serialization.hpp b/src/serialization.hpp
index 93fd92a..1f9df48 100644
--- a/src/serialization.hpp
+++ b/src/serialization.hpp
@@ -49,19 +49,17 @@ iccsc SRLZTN_CAMERA_IS_PRIMARY = "IsPrimary:";
iccsc SRLZTN_UI_BOX_UUID = "UUID:";
iccsc SRLZTN_UI_BOX_PARENT_UUID = "ParentUUID:";
iccsc SRLZTN_UI_BOX_FLAGS = "Flags:";
-iccsc SRLZTN_UI_BOX_POS_TOP_LEFT_X = "PosTopLeftX:";
-iccsc SRLZTN_UI_BOX_POS_TOP_LEFT_Y = "PosTopLeftY:";
-iccsc SRLZTN_UI_BOX_MIN_WIDTH = "MinWidthX:";
-iccsc SRLZTN_UI_BOX_MIN_HEIGHT = "MinWidthY:";
-iccsc SRLZTN_UI_BOX_MAX_WIDTH = "MaxWidthX:";
-iccsc SRLZTN_UI_BOX_MAX_HEIGHT = "MaxWidthY:";
+iccsc SRLZTN_UI_BOX_POS_TOP_LEFT = "PosTopLeft:";
+iccsc SRLZTN_UI_BOX_MIN_SIZE = "MinSize:";
+iccsc SRLZTN_UI_BOX_MAX_SIZE = "MaxSize:";
iccsc SRLZTN_UI_BOX_FLEX_WEIGHT = "FlexWeight:";
-iccsc SRLZTN_UI_BOX_TYPE = "Type:";
iccsc SRLZTN_UI_BOX_FLEX_DIRECTION = "FlexDirection:";
iccsc SRLZTN_UI_BOX_LAYER = "Layer:";
+iccsc SRLZTN_UI_BOX_TYPE = "Type:";
iccsc SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID = "FontRenderUUID:";
iccsc SRLZTN_UI_FONT_RENDER_UUID = "UUID:";
+iccsc SRLZTN_UI_FONT_RENDER_FONT_TYPE_UUID = "FontTypeUUID:";
iccsc SRLZTN_UI_FONT_RENDER_TEXT_BEGIN = "TextBegin::";
iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE = "CharScale:";
iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE = "LineHeightScale:";
@@ -70,7 +68,7 @@ iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE = "SurfaceAreaSize:";
iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS = "SurfaceAreaPos:";
iccsc SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS = "SurfaceAreaFlags:";
-struct srlztn_instance_mapping {
+struct srlztn_ecs_mapping {
pk_uuid serialized_uuid = pk_uuid_zed;
Entity_Base *created_entity = nullptr;
CompInstance *created_instance = nullptr;
@@ -85,7 +83,7 @@ struct srlztn_serialize_helper {
struct srlztn_deserialize_helper {
pk_membucket *bkt;
pke_scene *scene;
- pk_arr_t<srlztn_instance_mapping> mapping;
+ pk_arr_t<srlztn_ecs_mapping> mapping;
pk_arr_t<pke_kve_container> kvp_containers;
};
diff --git a/src/static-ui.cpp b/src/static-ui.cpp
index 823c015..2f2ce11 100644
--- a/src/static-ui.cpp
+++ b/src/static-ui.cpp
@@ -3,6 +3,7 @@
#include "dynamic-array.hpp"
#include "ecs.hpp"
+#include "font.hpp"
#include "game-settings.hpp"
#include "pk.h"
#include "static-plane.hpp"
@@ -100,14 +101,14 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
glm::vec2 parent_size_padded;
glm::vec2 parent_pos_and_offset;
- assert(box->pos_top_left_x >= 0.0);
- assert(box->pos_top_left_y >= 0.0);
- assert(box->max_width >= 0.0);
- assert(box->max_height >= 0.0);
- assert(box->min_width >= 0.0);
- assert(box->min_height >= 0.0);
- assert(box->min_width <= box->max_width);
- assert(box->min_height <= box->max_height);
+ assert(box->pos_top_left.x >= 0.0);
+ assert(box->pos_top_left.y >= 0.0);
+ assert(box->max_size.x >= 0.0);
+ assert(box->max_size.y >= 0.0);
+ assert(box->min_size.x >= 0.0);
+ assert(box->min_size.y >= 0.0);
+ assert(box->min_size.x <= box->max_size.x);
+ assert(box->min_size.y <= box->max_size.y);
if (box->internal.parent != nullptr) {
parent_pos_and_offset.x = box->internal.parent->internal.px_corner.x
@@ -128,16 +129,16 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
px_size = glm::vec2(Extent.width, Extent.height);
}
- px_min_size.x = box->min_width;
- px_min_size.y = box->min_height;
- px_max_size.x = box->max_width;
- px_max_size.y = box->max_height;
+ px_min_size.x = box->min_size.x;
+ px_min_size.y = box->min_size.y;
+ px_max_size.x = box->max_size.x;
+ px_max_size.y = box->max_size.y;
box->internal.px_corner.x = 0
+ parent_pos_and_offset.x
- + box->pos_top_left_x;
+ + box->pos_top_left.x;
box->internal.px_corner.y = 0
+ parent_pos_and_offset.y
- + box->pos_top_left_y;
+ + box->pos_top_left.y;
if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX)) {
assert(flex_params != nullptr);
@@ -148,23 +149,23 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
px_size.y = flex_params->px_per_unit * box->flex_weight;
}
} else if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC)) {
- px_size.x -= box->pos_top_left_x;
- px_size.y -= box->pos_top_left_y;
+ px_size.x -= box->pos_top_left.x;
+ px_size.y -= box->pos_top_left.y;
} else {
- assert(box->pos_top_left_x < 1.0);
- assert(box->pos_top_left_y < 1.0);
+ assert(box->pos_top_left.x < 1.0);
+ assert(box->pos_top_left.y < 1.0);
box->internal.px_corner.x = parent_pos_and_offset.x;
box->internal.px_corner.y = parent_pos_and_offset.y;
- float px_left = px_size.x * box->pos_top_left_x;
- float px_top = px_size.y * box->pos_top_left_y;
+ float px_left = px_size.x * box->pos_top_left.x;
+ float px_top = px_size.y * box->pos_top_left.y;
box->internal.px_corner.x += px_left;
box->internal.px_corner.y += px_top;
px_size.x -= px_left;
px_size.y -= px_top;
- px_min_size.x = box->min_width * parent_size_padded.x;
- px_min_size.y = box->min_height * parent_size_padded.y;
- px_max_size.x = box->max_width * parent_size_padded.x;
- px_max_size.y = box->max_height * parent_size_padded.y;
+ px_min_size.x = box->min_size.x * parent_size_padded.x;
+ px_min_size.y = box->min_size.y * parent_size_padded.y;
+ px_max_size.x = box->max_size.x * parent_size_padded.x;
+ px_max_size.y = box->max_size.y * parent_size_padded.y;
}
px_size = glm::clamp(px_size, px_min_size, px_max_size);
@@ -202,10 +203,11 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
if (box->type_data != nullptr) {
// type-specific changes
if (box->type == PKE_UI_BOX_TYPE_TEXT) {
- pke_ui_box_type_data_text *data_text = reinterpret_cast<pke_ui_box_type_data_text*>(box->type_data);
- data_text->font_render_settings.surface_area_pos = box->internal.px_corner;
- data_text->font_render_settings.surface_area_size = box->internal.px_size;
- FontType_UpdateStringRender(data_text->font_render_handle, &data_text->font_render_settings);
+ FontRender *fr = FontType_GetFontRender(box->type_data->text.font_render_handle);
+ FontRenderSettings frs = fr->settings;
+ frs.surface_area_pos = box->internal.px_corner;
+ frs.surface_area_size = box->internal.px_size;
+ FontType_UpdateStringRender(box->type_data->text.font_render_handle, &frs);
}
}
@@ -443,13 +445,19 @@ void pke_ui_teardown() {
pke_ui_master.bindings.deviceMemoryVert = VK_NULL_HANDLE;
}
+pke_ui_box **pke_ui_get_root_boxes(pke_ui_box_count_T *count) {
+ assert(count != nullptr);
+ *count = pke_ui_master.h_root_boxes;
+ return pke_ui_master.root_boxes;
+}
+
void pke_ui_internal_new_typed_box(pke_ui_box *box, const PKE_UI_BOX_TYPE type) {
assert(box->type == type);
switch (type) {
case PKE_UI_BOX_TYPE_STANDARD:
break;
case PKE_UI_BOX_TYPE_TEXT:
- box->type_data = pk_new<pke_ui_box_type_data_text>(pke_ui_master.bkt);
+ box->type_data = pk_new<pke_ui_box_type_data>(pke_ui_master.bkt);
box->flags |= PKE_UI_BOX_FLAG_VISIBILITY_INVISIBLE;
break;
case PKE_UI_BOX_TYPE_INPUT_TEXT:
diff --git a/src/static-ui.hpp b/src/static-ui.hpp
index 149d588..1b53935 100644
--- a/src/static-ui.hpp
+++ b/src/static-ui.hpp
@@ -67,14 +67,14 @@ struct pke_ui_box;
struct pke_ui_box : public Entity_Base {
PKE_UI_BOX_FLAG flags;
- float pos_top_left_x, pos_top_left_y;
- float min_width, min_height;
- float max_width, max_height;
+ glm::vec2 pos_top_left;
+ glm::vec2 min_size;
+ glm::vec2 max_size;
float flex_weight;
PKE_UI_BOX_TYPE type;
uint8_t flex_direction;
uint8_t layer;
- void *type_data;
+ union pke_ui_box_type_data *type_data;
struct pke_ui_box_internals {
// the exact px to translate (shader)
glm::vec2 px_corner;
@@ -90,10 +90,11 @@ struct pke_ui_box : public Entity_Base {
} internal;
};
-struct pke_ui_box_type_data_text {
- pk_uuid font_render_uuid = pk_uuid_zed;
- FontRenderHandle font_render_handle;
- FontRenderSettings font_render_settings;
+// separate these if they become silly
+union pke_ui_box_type_data {
+ struct pke_ui_box_type_data_text {
+ FontRenderHandle font_render_handle;
+ } text;
};
struct pke_ui_graphics_bindings {
@@ -113,6 +114,8 @@ void pke_ui_init_bindings();
void pke_ui_tick(double delta);
void pke_ui_teardown();
+pke_ui_box **pke_ui_get_root_boxes(pke_ui_box_count_T *count);
+
pke_ui_box *pke_ui_box_new_root(const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD, pk_uuid uuid = pk_uuid_zed);
pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD, pk_uuid uuid = pk_uuid_zed);
diff --git a/src/vendor-pkh-include.cpp b/src/vendor-pkh-include.cpp
index 0d72dcb..75b3fba 100644
--- a/src/vendor-pkh-include.cpp
+++ b/src/vendor-pkh-include.cpp
@@ -1,5 +1,5 @@
#define PK_MEMORY_DEBUGGER
#define PK_IMPL_ALL
-
+#define PK_ARR_MOVE_IN_PLACE
#include "./pk.h"
diff --git a/tests/pke-test-serialization.cpp b/tests/pke-test-serialization.cpp
index c514578..840adfa 100644
--- a/tests/pke-test-serialization.cpp
+++ b/tests/pke-test-serialization.cpp
@@ -1,8 +1,9 @@
#include "./pke-test-serialization.h"
+#include "asset-manager.hpp"
+#include "font.hpp"
#include "game-settings.hpp"
-#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
#include "camera.hpp"
#include "ecs.hpp"
#include "physics.hpp"
@@ -11,6 +12,8 @@
#include "serialization-camera.hpp"
#include "serialization-component.hpp"
#include "serialization.hpp"
+#include "static-ui.hpp"
+#include "thread-pool.hpp"
#include <cstring>
#include <sstream>
@@ -18,23 +21,61 @@
pk_membucket *bkt = nullptr;
const char *test_scene_name = "srlztn_test_scene";
pke_scene *test_scene = nullptr;
+FontType *ft;
+
+#define FAKE_UUID_GEN(oct) { .uuid = { oct,oct,oct,oct,oct,oct,oct,oct,oct,oct,oct,oct,oct,oct,oct,oct } }
+
+const pk_uuid uuid_n[] = {
+ FAKE_UUID_GEN(0x00),
+ FAKE_UUID_GEN(0x01),
+ FAKE_UUID_GEN(0x02),
+ FAKE_UUID_GEN(0x03),
+ FAKE_UUID_GEN(0x04),
+ FAKE_UUID_GEN(0x05),
+ FAKE_UUID_GEN(0x06),
+ FAKE_UUID_GEN(0x07),
+ FAKE_UUID_GEN(0x08),
+ FAKE_UUID_GEN(0x09),
+ FAKE_UUID_GEN(0x0a),
+ FAKE_UUID_GEN(0x0b),
+ FAKE_UUID_GEN(0x0c),
+ FAKE_UUID_GEN(0x0d),
+ FAKE_UUID_GEN(0x0e),
+ FAKE_UUID_GEN(0x0f),
+};
+const pk_uuid uuid_17 = FAKE_UUID_GEN(0x11);
+// const pk_uuid uuid_34 = FAKE_UUID_GEN(0x22);
void pke_test_serialization_spinup() {
pkeSettings.isSimulationPaused = true;
Physics_Init();
+ PkeThreads_Init();
+ AM_Init();
ECS_Init();
+ pke_ui_init();
PkeCamera_Init();
+ FontType_Init();
pke_scene_master_init();
test_scene = pke_scene_create(test_scene_name);
+ FontTypeIndex fti;
+ FontType *ft = FontType_GetFonts(fti);
+ assert(fti > FontTypeIndex{0});
+ ft->uuid = uuid_17;
};
void pke_test_serialization_teardown() {
// pke_scene_remove(test_scene->scene_handle); // TODO this doesn't work?
test_scene = nullptr;
pke_scene_master_teardown();
+ FontType_Teardown();
PkeCamera_Teardown();
+ pke_ui_teardown();
ECS_Teardown();
+ AM_Teardown();
+ PkeThreads_Teardown();
Physics_Teardown();
+ pk_memory_teardown_all();
+ bkt = nullptr;
};
int pke_test_serialization_999() {
@@ -181,7 +222,7 @@ Rotation:0.000000;0.000000;0.000000;1.000000
Instance:00000000!00000001
ChildId:00000000!00000000
-UUID:67eec271-ab64-78d2-a38e-1f2946e87ccd
+UUID:01010101-0101-0101-0101-010101010101
Mass:1.000000
CollisionLayer:0x0000000000000001
CollisionMask:0x0000000000000001
@@ -193,10 +234,10 @@ Scale:5.000000;4.000000;3.000000
Camera:00000000!00000003
ChildId:00000000!00000002
-UUID:67eec26e-56c4-7aeb-a43c-986966334873
+UUID:02020202-0202-0202-0202-020202020202
Type:0x01
Orientation:0x01
-TargetUUID:67eec271-ab64-78d2-a38e-1f2946e87ccd
+TargetUUID:01010101-0101-0101-0101-010101010101
IsPrimary:1
:PKFE:)VOGON";
@@ -209,8 +250,6 @@ int pke_test_serialization_002() {
try {
bkt = pk_bucket_create("pke_test_serialization", PK_DEFAULT_BUCKET_SIZE, false);
h = pke_serialize_init(bkt);
- const pk_uuid camera_uuid = { .uuid = { 0x67,0xEE,0xC2,0x6E,0x56,0xC4,0x7A,0xEB,0xA4,0x3C,0x98,0x69,0x66,0x33,0x48,0x73 } };
- const pk_uuid target_uuid = { .uuid = { 0x67,0xEE,0xC2,0x71,0xAB,0x64,0x78,0xD2,0xA3,0x8E,0x1F,0x29,0x46,0xE8,0x7C,0xCD } };
// reminder that 'targeting' moves and rotates the camera, so we shouldn't see these values in the output
InstPos cam_inst_pos{};
@@ -221,10 +260,10 @@ int pke_test_serialization_002() {
cam_inst_pos.mass = 1.f;
Entity_Base *target_ent = ECS_CreateGenericEntity();
- CompInstance *target_ent_comp_inst = ECS_CreateInstance(target_ent, target_uuid, nullptr, &cam_inst_pos);
+ CompInstance *target_ent_comp_inst = ECS_CreateInstance(target_ent, uuid_n[1], nullptr, &cam_inst_pos);
cam_inst_pos.scale = btVector3(5,4,3);
- PkeCamera &cam = PkeCamera_Register(camera_uuid, cam_inst_pos);
+ PkeCamera &cam = PkeCamera_Register(uuid_n[2], cam_inst_pos);
cam.type = PKE_CAMERA_TYPE_PERSPECTIVE;
cam.view = PKE_CAMERA_VIEW_TARGET;
PkeCamera_SetPrimary(cam.camHandle);
@@ -284,8 +323,6 @@ int pke_test_deserialization_102() {
bkt = pk_bucket_create("pke_test_serialization", PK_DEFAULT_BUCKET_SIZE, false);
h = pke_deserialize_init(bkt);
h->scene = test_scene;
- const pk_uuid camera_uuid = { .uuid = { 0x67,0xEE,0xC2,0x6E,0x56,0xC4,0x7A,0xEB,0xA4,0x3C,0x98,0x69,0x66,0x33,0x48,0x73 } };
- const pk_uuid target_uuid = { .uuid = { 0x67,0xEE,0xC2,0x71,0xAB,0x64,0x78,0xD2,0xA3,0x8E,0x1F,0x29,0x46,0xE8,0x7C,0xCD } };
pke_deserialize_scene_from_stream(ss, h);
@@ -334,10 +371,10 @@ int pke_test_deserialization_102() {
PkeCamera *des_cam = &PkeCamera_GetCameras(0, item_index)[0];
// 57
PKE_TEST_ASSERT(des_cam != nullptr, err_index);
- PKE_TEST_ASSERT(des_cam->uuid == camera_uuid, err_index);
+ PKE_TEST_ASSERT(des_cam->uuid == uuid_n[2], err_index);
PKE_TEST_ASSERT(des_cam->type == PKE_CAMERA_TYPE_PERSPECTIVE, err_index);
PKE_TEST_ASSERT(des_cam->view == PKE_CAMERA_VIEW_TARGET, err_index);
- PKE_TEST_ASSERT(des_cam->phys.target_inst_uuid == target_uuid, err_index);
+ PKE_TEST_ASSERT(des_cam->phys.target_inst_uuid == uuid_n[1], err_index);
PKE_TEST_ASSERT(des_cam->isPrimary == true, err_index);
pke_deserialize_teardown(h);
@@ -350,8 +387,190 @@ int pke_test_deserialization_102() {
return 0;
}
+const char *const test_003_str = R"VOGON(:PKFB:
+:0:
+
+FontRenderSettings:00000000!00000000
+CharScale:1.000000
+LineHeightScale:1.000000
+CharSpacingScale:1.000000
+SurfaceAreaSize:250;250
+SurfaceAreaPos:0;0
+SurfaceAreaFlags:0x03
+
+FontRender:00000000!00000001
+ChildId:00000000!00000000
+UUID:01010101-0101-0101-0101-010101010101
+FontTypeUUID:11111111-1111-1111-1111-111111111111
+TextBegin::
+asdf
+:MULTILINE_END:
+
+UIBoxTypeData:00000000!00000002
+FontRenderUUID:01010101-0101-0101-0101-010101010101
+
+UIBox:00000000!00000003
+ChildId:00000000!00000002
+UUID:02020202-0202-0202-0202-020202020202
+Flags:0x84
+PosTopLeft:0.100000;0.100000
+MaxSize:0.800000;0.800000
+Type:0x28
+Layer:0x00
+
+:PKFE:)VOGON";
+int pke_test_serialization_003() {
+ int64_t err_index = 0;
+ uint32_t i, k;
+ srlztn_serialize_helper *h = nullptr;
+ pke_kve *kve = nullptr;
+ std::stringstream ss;
+ try {
+ bkt = pk_bucket_create("pke_test_serialization", PK_DEFAULT_BUCKET_SIZE, false);
+ h = pke_serialize_init(bkt);
+
+ FontTypeIndex fti;
+ FontRenderSettings frs;
+ frs.char_scale = 1.0;
+ frs.char_spacing_scale = 1.0;
+ frs.line_height_scale = 1.0;
+ frs.surface_area_size = glm::ivec2(250, 250);
+ frs.surface_area_pos = glm::ivec2(0, 0);
+ frs.surface_area_type_flags = FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_FLUID;
+ FontRenderHandle fr_handle = FontType_AddStringRender(FontType_GetFonts(fti)[0].index_ft, std::move(cstring_to_pk_cstr("asdf")), &frs, nullptr, uuid_n[1]);
+
+ pke_ui_box *ui_box = pke_ui_box_new_root(PKE_UI_BOX_TYPE_TEXT, uuid_n[2]);
+ ui_box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC;
+ ui_box->pos_top_left.x = 0.1;
+ ui_box->pos_top_left.y = 0.1;
+ ui_box->max_size.x = 0.8;
+ ui_box->max_size.y = 0.8;
+ ui_box->type_data->text.font_render_handle = fr_handle;
+
+ pke_serialize_scene(h);
+ pke_serialize_scene_to_stream(ss, h);
+ std::string s = ss.str();
+
+ PKE_TEST_ASSERT(h->bkt == bkt, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers.bkt == bkt, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers.next == 4, err_index);
+ // FontRenderSettings
+ PKE_TEST_ASSERT(h->kvp_containers[0].child_handles.next == 0, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[0].arr.next == 6, err_index);
+ // FontRender
+ PKE_TEST_ASSERT(h->kvp_containers[1].child_handles.next == 1, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[1].arr.next == 3, err_index);
+ // ui box type text
+ PKE_TEST_ASSERT(h->kvp_containers[2].child_handles.next == 0, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[2].arr.next == 1, err_index);
+ // ui box
+ PKE_TEST_ASSERT(h->kvp_containers[3].child_handles.next == 1, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[3].arr.next == 6, err_index);
+
+ // 12
+ for (k = 0; k < h->kvp_containers.next; ++k) {
+ for (i = 0; i < h->kvp_containers[k].arr.next; ++i) {
+ // 12 + (3 * (6 + 3 + 1 + 6))
+ kve = &h->kvp_containers[k].arr[i];
+ PKE_TEST_ASSERT(kve->key != nullptr, err_index);
+ PKE_TEST_ASSERT(kve->val != nullptr, err_index);
+ PKE_TEST_ASSERT(kve->end != nullptr, err_index);
+ }
+ }
+
+ // 60
+ PKE_TEST_ASSERT(strstr(test_003_str, s.c_str()) != nullptr, err_index);
+
+ pke_serialize_teardown(h);
+
+ } catch (const std::exception &ex) {
+ pk_bucket_destroy(bkt);
+ throw;
+ }
+ pk_bucket_destroy(bkt);
+ return 0;
+}
+
+int pke_test_deserialization_103() {
+ int64_t err_index = 0;
+ uint32_t i, k;
+ pke_kve *kve;
+ srlztn_deserialize_helper *h;
+ std::stringstream ss(test_003_str);
+ try {
+ bkt = pk_bucket_create("pke_test_serialization", PK_DEFAULT_BUCKET_SIZE, false);
+ h = pke_deserialize_init(bkt);
+ h->scene = test_scene;
+
+ pke_deserialize_scene_from_stream(ss, h);
+
+ PKE_TEST_ASSERT(h->bkt == bkt, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers.bkt == bkt, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers.next == 4, err_index);
+ // FontRenderSettings
+ PKE_TEST_ASSERT(h->kvp_containers[0].child_handles.next == 0, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[0].arr.next == 6, err_index);
+ // FontRender
+ PKE_TEST_ASSERT(h->kvp_containers[1].child_handles.next == 1, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[1].arr.next == 3, err_index);
+ // ui box type text
+ PKE_TEST_ASSERT(h->kvp_containers[2].child_handles.next == 0, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[2].arr.next == 1, err_index);
+ // ui box
+ PKE_TEST_ASSERT(h->kvp_containers[3].child_handles.next == 1, err_index);
+ PKE_TEST_ASSERT(h->kvp_containers[3].arr.next == 6, err_index);
+
+ // 12
+ for (k = 0; k < h->kvp_containers.next; ++k) {
+ for (i = 0; i < h->kvp_containers[k].arr.next; ++i) {
+ // 12 + (3 * (6 + 3 + 1 + 6))
+ kve = &h->kvp_containers[k].arr[i];
+ PKE_TEST_ASSERT(kve->key != nullptr, err_index);
+ PKE_TEST_ASSERT(kve->val != nullptr, err_index);
+ PKE_TEST_ASSERT(kve->end != nullptr, err_index);
+ }
+ }
+
+ pke_deserialize_scene(h);
+
+ FontTypeIndex fti = FontTypeIndex{0};
+ FontType *fonts = FontType_GetFonts(fti);
+ // 60
+ PKE_TEST_ASSERT(fti > FontTypeIndex{0}, err_index);
+ PKE_TEST_ASSERT(fonts != nullptr, err_index);
+ PKE_TEST_ASSERT(fonts->h_render > FontRenderIndex{0}, err_index);
+ PKE_TEST_ASSERT(fonts->n_render > FontRenderIndex{0}, err_index);
+ FontRender *fr = &fonts[0].renders[0];
+
+ // 64
+ PKE_TEST_ASSERT(fr->settings.char_scale == 1.f, err_index);
+ PKE_TEST_ASSERT(fr->settings.line_height_scale == 1.f, err_index);
+ PKE_TEST_ASSERT(fr->settings.char_spacing_scale == 1.f, err_index);
+ PKE_TEST_ASSERT(fr->settings.surface_area_size == glm::ivec2(250,250), err_index);
+ PKE_TEST_ASSERT(fr->settings.surface_area_pos == glm::ivec2(0,0), err_index);
+ PKE_TEST_ASSERT(fr->settings.surface_area_type_flags == FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_FLUID, err_index);
+
+ // 70
+ PKE_TEST_ASSERT(fr->uuid == uuid_n[1], err_index);
+ PKE_TEST_ASSERT(fr->text.val != nullptr, err_index);
+ PKE_TEST_ASSERT(fr->text.val[0] == 'a', err_index);
+ PKE_TEST_ASSERT(fr->text.val[1] == 's', err_index);
+ PKE_TEST_ASSERT(fr->text.val[2] == 'd', err_index);
+ PKE_TEST_ASSERT(fr->text.val[3] == 'f', err_index);
+ PKE_TEST_ASSERT(fr->text.val[4] == '\0', err_index);
+
+ pke_deserialize_teardown(h);
+
+ } catch (const std::exception &ex) {
+ pk_bucket_destroy(bkt);
+ throw;
+ }
+ pk_bucket_destroy(bkt);
+ return 0;
+}
+
struct pke_test_group *pke_test_serialization_get_group() {
- static const uint64_t test_count = 5;
+ static const uint64_t test_count = 7;
static struct pke_test tests[test_count] = {
{
.title = "test 999",
@@ -378,6 +597,16 @@ struct pke_test_group *pke_test_serialization_get_group() {
.func = pke_test_deserialization_102,
.expected_result = 0,
},
+ {
+ .title = "test 003",
+ .func = pke_test_serialization_003,
+ .expected_result = 0,
+ },
+ {
+ .title = "test 103",
+ .func = pke_test_deserialization_103,
+ .expected_result = 0,
+ },
};
static struct pke_test_group group = {};
group.title = "de/serialization";
diff --git a/tests/pke-test-static-ui.cpp b/tests/pke-test-static-ui.cpp
index 1e11d97..9a5fb71 100644
--- a/tests/pke-test-static-ui.cpp
+++ b/tests/pke-test-static-ui.cpp
@@ -41,19 +41,19 @@ int pke_test_static_ui_000() {
pke_ui_box *ui_box = pke_ui_box_new_root();
ui_box->flags = PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC;
- ui_box->pos_top_left_x = 10;
- ui_box->pos_top_left_y = 10;
- ui_box->max_width = 500;
- ui_box->max_height = 500;
+ ui_box->pos_top_left.x = 10;
+ ui_box->pos_top_left.y = 10;
+ ui_box->max_size.x = 500;
+ ui_box->max_size.y = 500;
pke_ui_box *c_ui_box = pke_ui_box_new_child(ui_box);
c_ui_box->flags = PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC;
- c_ui_box->pos_top_left_x = 10;
- c_ui_box->pos_top_left_y = 10;
- c_ui_box->max_width = 100;
- c_ui_box->max_height = 100;
+ c_ui_box->pos_top_left.x = 10;
+ c_ui_box->pos_top_left.y = 10;
+ c_ui_box->max_size.x = 100;
+ c_ui_box->max_size.y = 100;
- calculated_offset = ui_box->pos_top_left_x + c_ui_box->pos_top_left_x + built_in_offset;
+ calculated_offset = ui_box->pos_top_left.x + c_ui_box->pos_top_left.x + built_in_offset;
pke_ui_calc_px(arr, nullptr, ui_box);
pke_ui_recalc_sizes_recursive(arr, ui_box, 0);
@@ -87,17 +87,17 @@ int pke_test_static_ui_100() {
pke_ui_box *ui_box = pke_ui_box_new_root();
ui_box->flags = PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC;
- ui_box->pos_top_left_x = 0.1;
- ui_box->pos_top_left_y = 0.1;
- ui_box->max_width = 0.8;
- ui_box->max_height = 0.8;
+ ui_box->pos_top_left.x = 0.1;
+ ui_box->pos_top_left.y = 0.1;
+ ui_box->max_size.x = 0.8;
+ ui_box->max_size.y = 0.8;
pke_ui_box *c_ui_box = pke_ui_box_new_child(ui_box);
c_ui_box->flags = PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC;
- c_ui_box->pos_top_left_x = 0.1;
- c_ui_box->pos_top_left_y = 0.1;
- c_ui_box->max_width = 0.8;
- c_ui_box->max_height = 0.8;
+ c_ui_box->pos_top_left.x = 0.1;
+ c_ui_box->pos_top_left.y = 0.1;
+ c_ui_box->max_size.x = 0.8;
+ c_ui_box->max_size.y = 0.8;
unit = Extent.width * 0.1;
calculated_offset_x = (unit * 8) - (built_in_offset * 2); // padded parent
@@ -147,17 +147,17 @@ int pke_test_static_ui_200() {
pke_ui_box *ui_box = pke_ui_box_new_root();
ui_box->flags = PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC;
- ui_box->pos_top_left_x = 0.1;
- ui_box->pos_top_left_y = 0.1;
- ui_box->max_width = 0.8;
- ui_box->max_height = 0.8;
+ ui_box->pos_top_left.x = 0.1;
+ ui_box->pos_top_left.y = 0.1;
+ ui_box->max_size.x = 0.8;
+ ui_box->max_size.y = 0.8;
pke_ui_box *c_ui_box = pke_ui_box_new_child(ui_box);
c_ui_box->flags = PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC;
- c_ui_box->pos_top_left_x = 1;
- c_ui_box->pos_top_left_y = 1;
- c_ui_box->max_width = 300;
- c_ui_box->max_height = 300;
+ c_ui_box->pos_top_left.x = 1;
+ c_ui_box->pos_top_left.y = 1;
+ c_ui_box->max_size.x = 300;
+ c_ui_box->max_size.y = 300;
unit = Extent.width * 0.1;
calculated_offset_x = unit + 1 + built_in_offset;