From 5685a827a2a54433c709d91df97bd76903662d64 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 21 Oct 2024 07:25:05 +0200 Subject: [PATCH] started fixing previous commit --- compression/Huffman.h | 7 ++-- font/Font.h | 49 ++++++++++++++++------- gpuapi/RenderUtils.h | 80 +++++++++++++++++++++++++------------ models/settings/Settings.h | 2 +- platform/win32/UtilsWin32.h | 17 ++++++++ ui/UIAttribute.h | 3 ++ ui/UITheme.h | 10 +++-- utils/StringUtils.h | 17 ++++++++ 8 files changed, 137 insertions(+), 48 deletions(-) diff --git a/compression/Huffman.h b/compression/Huffman.h index 0c15d6b..bb84d0f 100644 --- a/compression/Huffman.h +++ b/compression/Huffman.h @@ -27,13 +27,12 @@ struct HuffmanNode { struct Huffman { HuffmanNode pool[512]; HuffmanNode priority_queue[511]; - HuffmanNode** pq; + HuffmanNode** pq; // 1 indexed array (see huffman_init) int32 node_count; int32 pq_end; - // Contains the actual table data - char buffer[1024]; - char* code[256]; + char buffer[1024]; // Contains the actual table data + char* code[256]; // Contains a pointer per ASCII character to the huffman code sequence }; HuffmanNode* huffman_node_create(Huffman* hf, int32 frequency, byte character, HuffmanNode* left, HuffmanNode* right) diff --git a/font/Font.h b/font/Font.h index 5376f6c..879b8f0 100644 --- a/font/Font.h +++ b/font/Font.h @@ -4,14 +4,15 @@ #include "../stdlib/Types.h" #include "../memory/BufferMemory.h" #include "../utils/EndianUtils.h" +#include "../utils/Utils.h" #include "../stdlib/simd/SIMD_I32.h" struct GlyphMetrics { - f32 width; // Width of the glyph - f32 height; // Height of the glyph - f32 offset_x; // Horizontal offset from baseline - f32 offset_y; // Vertical offset from baseline - f32 advance_x; // Horizontal advance after drawing the glyph + f32 width; // Width of the glyph + f32 height; // Height of the glyph + f32 offset_x; // Horizontal offset from baseline + f32 offset_y; // Vertical offset from baseline + f32 advance_x; // Horizontal advance after drawing the glyph }; struct GlyphTextureCoords { @@ -29,11 +30,11 @@ struct Glyph { struct Font { uint32 glyph_count; - f32 size; // Default font size - uint32 line_height; + char texture_name[32]; + f32 size; // Default font size at which the font renders best + f32 line_height; // How tall is a single line (mostly important for multiple lines) Glyph* glyphs; - // @question Do we want to have a pointer to the glyph Texture }; inline @@ -74,25 +75,31 @@ void font_from_file_txt( int32 image_width = 0; int32 image_height = 0; + char* texture_pos = font->texture_name; + while (*pos != '\0') { if (start) { // Parsing general data int32 i = 0; - while (*pos != '\0' && *pos != ' ' && *pos != '\n' && i < 31) { + while (*pos != '\0' && *pos != ' ' && *pos != ':' && *pos != '\n' && i < 31) { block_name[i] = *pos; ++pos; ++i; } // Go to value - while (*pos == ' ' || *pos == '\t') { + while (*pos == ' ' || *pos == '\t' || *pos == ':') { ++pos; } - if (strcmp(block_name, "font_size") == 0) { + if (strcmp(block_name, "texture") == 0) { + while (*pos != '\n') { + *texture_pos++ == *pos++; + } + } else if (strcmp(block_name, "font_size") == 0) { font->size = strtof(pos, &pos); } else if (strcmp(block_name, "line_height") == 0) { - font->line_height = strtoul(pos, &pos, 10); + font->line_height = strtof(pos, &pos); } else if (strcmp(block_name, "image_width") == 0) { image_width = strtoul(pos, &pos, 10); } else if (strcmp(block_name, "image_height") == 0) { @@ -118,6 +125,12 @@ void font_from_file_txt( font->glyphs[glyph_index].metrics.width = font->glyphs[glyph_index].coords.x2 - font->glyphs[glyph_index].coords.x1; font->glyphs[glyph_index].metrics.height = font->glyphs[glyph_index].coords.y2 - font->glyphs[glyph_index].coords.y1; + font->glyphs[glyph_index].coords.x1 /= image_width; + font->glyphs[glyph_index].coords.x2 /= image_width; + + font->glyphs[glyph_index].coords.y1 /= image_height; + font->glyphs[glyph_index].coords.y2 /= image_height; + ++glyph_index; // Go to next line @@ -154,12 +167,16 @@ void font_from_file( font->glyph_count = SWAP_ENDIAN_LITTLE(*((uint32 *) pos)); pos += sizeof(font->glyph_count); + // Read texture name + memcpy(font->texture_name, pos, ARRAY_COUNT(font->texture_name) * sizeof(char)); + pos += ARRAY_COUNT(font->texture_name) * sizeof(char); + // Read font size font->size = SWAP_ENDIAN_LITTLE(*((f32 *) pos)); pos += sizeof(font->size); // Read line height - font->line_height = SWAP_ENDIAN_LITTLE(*((uint32 *) pos)); + font->line_height = SWAP_ENDIAN_LITTLE(*((f32 *) pos)); pos += sizeof(font->line_height); memcpy(font->glyphs, pos, font->glyph_count * sizeof(Glyph)); @@ -195,12 +212,16 @@ void font_to_file( *((uint32 *) pos) = font->glyph_count; pos += sizeof(font->glyph_count); + // Texture name + memcpy(pos, font->texture_name, ARRAY_COUNT(font->texture_name) * sizeof(char)); + pos += ARRAY_COUNT(font->texture_name) * sizeof(char); + // Font size *((f32 *) pos) = font->size; pos += sizeof(font->size); // Line height - *((uint32 *) pos) = font->line_height; + *((f32 *) pos) = font->line_height; pos += sizeof(font->line_height); // The glyphs are naturally tightly packed -> we can just store the memory diff --git a/gpuapi/RenderUtils.h b/gpuapi/RenderUtils.h index 7679df6..8cf10cb 100644 --- a/gpuapi/RenderUtils.h +++ b/gpuapi/RenderUtils.h @@ -452,15 +452,29 @@ f32 ui_text_create( return; } - HashEntryVoidP* entry = (HashEntryVoidP *) hashmap_get_entry(&theme->hash_map, element->name, element->id); - UIAttributeGroup* group = (UIAttributeGroup *) entry->value; + // @performance see comment for setup_theme() + + // Load element data + HashEntryVoidP* element_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->primary_scene->hash_map, element->name, element->id); + UIAttributeGroup* element_group = (UIAttributeGroup *) element_entry->value; + + // Load general style + UIAttribute* style = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_STYLE); + HashEntryVoidP* style_entry = NULL; + UIAttributeGroup* style_group = NULL; + + if (style) { + style_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->primary_scene->hash_map, style->value_str); + style_group = (UIAttributeGroup *) style_entry->value; + } UIAttribute* x; UIAttribute* y; - UIAttribute* parent = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_PARENT); + // Load parent data (for position data) + UIAttribute* parent = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_PARENT); if (parent) { - HashEntryVoidP* parent_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->hash_map, parent->value_str); + HashEntryVoidP* parent_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->primary_scene->hash_map, parent->value_str); UIAttributeGroup* parent_group = (UIAttributeGroup *) parent_entry->value; x = ui_attribute_from_group(parent_group, UI_ATTRIBUTE_TYPE_POSITION_X); @@ -469,17 +483,17 @@ f32 ui_text_create( // @question Do we have more values which can be inherited from the parent? // We don't want to inherit implicit stuff like size, background etc. These things should be defined explicitly } else { - x = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_POSITION_X); - y = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_POSITION_Y); + x = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_POSITION_X); + y = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_POSITION_Y); } - UIAttribute* width = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH); - UIAttribute* height = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT); - UIAttribute* align_h = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_ALIGN_H); - UIAttribute* align_v = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_ALIGN_V); - UIAttribute* text = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_CONTENT); - UIAttribute* size = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_FONT_SIZE); - UIAttribute* color_index = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_FONT_COLOR); + UIAttribute* width = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH); + UIAttribute* height = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT); + UIAttribute* align_h = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_ALIGN_H); + UIAttribute* align_v = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_ALIGN_V); + UIAttribute* text = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_CONTENT); + UIAttribute* size = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_FONT_SIZE); + UIAttribute* color_index = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_FONT_COLOR); int32 length = utf8_strlen(text->value_str); float scale = size->value_float / theme->font.size; @@ -560,15 +574,29 @@ void ui_button_create( return; } - HashEntryVoidP* entry = (HashEntryVoidP *) hashmap_get_entry(&theme->hash_map, element->name, element->id); - UIAttributeGroup* group = (UIAttributeGroup *) entry->value; + // @performance see comment for setup_theme() + + // Load element data + HashEntryVoidP* element_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->primary_scene->hash_map, element->name, element->id); + UIAttributeGroup* element_group = (UIAttributeGroup *) element_entry->value; + + // Load general style + UIAttribute* style = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_STYLE); + HashEntryVoidP* style_entry = NULL; + UIAttributeGroup* style_group = NULL; + + if (style) { + style_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->primary_scene->hash_map, style->value_str); + style_group = (UIAttributeGroup *) style_entry->value; + } UIAttribute* x; UIAttribute* y; - UIAttribute* parent = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_PARENT); + // Load parent data (for position data) + UIAttribute* parent = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_PARENT); if (parent) { - HashEntryVoidP* parent_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->hash_map, parent->value_str); + HashEntryVoidP* parent_entry = (HashEntryVoidP *) hashmap_get_entry(&theme->primary_scene->hash_map, parent->value_str); UIAttributeGroup* parent_group = (UIAttributeGroup *) parent_entry->value; x = ui_attribute_from_group(parent_group, UI_ATTRIBUTE_TYPE_POSITION_X); @@ -577,17 +605,17 @@ void ui_button_create( // @question Do we have more values which can be inherited from the parent? // We don't want to inherit implicit stuff like size, background etc. These things should be defined explicitly } else { - x = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_POSITION_X); - y = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_POSITION_Y); + x = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_POSITION_X); + y = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_POSITION_Y); } - UIAttribute* width = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH); - UIAttribute* height = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT); - UIAttribute* align_h = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_ALIGN_H); - UIAttribute* align_v = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_ALIGN_V); - UIAttribute* text = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_CONTENT); - UIAttribute* size = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_FONT_SIZE); - UIAttribute* color_index = ui_attribute_from_group(group, UI_ATTRIBUTE_TYPE_FONT_COLOR); + UIAttribute* width = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_DIMENSION_WIDTH); + UIAttribute* height = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_DIMENSION_HEIGHT); + UIAttribute* align_h = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_ALIGN_H); + UIAttribute* align_v = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_ALIGN_V); + UIAttribute* text = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_CONTENT); + UIAttribute* size = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_FONT_SIZE); + UIAttribute* color_index = ui_attribute_from_group(element_group, UI_ATTRIBUTE_TYPE_FONT_COLOR); // @todo Above we only handle the default values, what about state dependent values like hover, active? // Simply check the state here and load the child_entries based on the state diff --git a/models/settings/Settings.h b/models/settings/Settings.h index f6f6744..4a9bc08 100644 --- a/models/settings/Settings.h +++ b/models/settings/Settings.h @@ -243,7 +243,7 @@ struct CSettings { // UI settings // Themes - uint32 game_ui_theme = 1; + char game_ui_theme[32]; byte game_ui_size = 128; uint32 game_item_icon_theme = 1; diff --git a/platform/win32/UtilsWin32.h b/platform/win32/UtilsWin32.h index c4e51cc..bbfb06b 100644 --- a/platform/win32/UtilsWin32.h +++ b/platform/win32/UtilsWin32.h @@ -101,6 +101,23 @@ uint64 time_ms() return (counter.QuadPart * 1000000) / frequency.QuadPart; } +inline +bool file_exists(const char* path) +{ + DWORD file_attr; + + if (*path == '.') { + char full_path[MAX_PATH]; + relative_to_absolute(path, full_path); + + file_attr = GetFileAttributesA(full_path); + } else { + file_attr = GetFileAttributesA(path); + } + + return file_attr != INVALID_FILE_ATTRIBUTES; +} + inline void file_read(const char* path, FileBody* file, RingMemory* ring = NULL) { diff --git a/ui/UIAttribute.h b/ui/UIAttribute.h index f88c38a..66e1066 100644 --- a/ui/UIAttribute.h +++ b/ui/UIAttribute.h @@ -28,6 +28,7 @@ enum UIAttributeType { UI_ATTRIBUTE_TYPE_CONTENT_ALIGN_H, UI_ATTRIBUTE_TYPE_CONTENT_ALIGN_V, + UI_ATTRIBUTE_TYPE_FONT_NAME, UI_ATTRIBUTE_TYPE_FONT_COLOR_INDEX, UI_ATTRIBUTE_TYPE_FONT_COLOR, UI_ATTRIBUTE_TYPE_FONT_SIZE, @@ -109,6 +110,8 @@ constexpr const char* ui_attribute_type_to_string(int32 e) return "type"; case UI_ATTRIBUTE_TYPE_STYLE: return "style"; + case UI_ATTRIBUTE_TYPE_FONT_NAME: + return "font_name"; case UI_ATTRIBUTE_TYPE_FONT_COLOR: return "font_color"; case UI_ATTRIBUTE_TYPE_FONT_SIZE: diff --git a/ui/UITheme.h b/ui/UITheme.h index 0f69cdd..3a10bde 100644 --- a/ui/UITheme.h +++ b/ui/UITheme.h @@ -104,6 +104,10 @@ void theme_from_file_txt( file_read(path, &file, ring); char* pos = (char *) file.content; + + // move past the version string + pos += 8; + theme->version = strtol(pos, &pos, 10); ++pos; bool block_open = false; @@ -196,7 +200,7 @@ void theme_from_file_txt( } int32 i = 0; - while (*pos != '\0' && *pos != ' ' && *pos != '\n' && i < 31) { + while (*pos != '\0' && *pos != ' ' && *pos != ':' && *pos != '\n' && i < 31) { attribute_name[i] = *pos; ++pos; ++i; @@ -255,13 +259,13 @@ void theme_from_file_txt( attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_SIZE), attribute_name) == 0) { attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_SIZE; - attribute.value_int = strtoul(pos, &pos, 10); ++pos; + attribute.value_float = strtoul(pos, &pos, 10); ++pos; } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_WEIGHT), attribute_name) == 0) { attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_WEIGHT; attribute.value_int = strtoul(pos, &pos, 10); ++pos; } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT), attribute_name) == 0) { attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT; - attribute.value_int = strtoul(pos, &pos, 10); ++pos; + attribute.value_float = strtoul(pos, &pos, 10); ++pos; } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_ALIGN_H), attribute_name) == 0) { attribute.attribute_id = UI_ATTRIBUTE_TYPE_ALIGN_H; attribute.value_int = strtoul(pos, &pos, 10); ++pos; diff --git a/utils/StringUtils.h b/utils/StringUtils.h index ac16a76..24ca65d 100644 --- a/utils/StringUtils.h +++ b/utils/StringUtils.h @@ -244,6 +244,23 @@ inline char* strsep(const char* *sp, const char* sep) return s; } +inline void +str_concat( + const char* src1, + const char* src2, + char* dst +) { + size_t len = strlen(src1); + memcpy(dst, src1, len); + dst += len; + + len = strlen(src2); + memcpy(dst, src2, len); + dst += len; + + *dst = '\0'; +} + inline void str_concat( const char* src1, size_t src1_length,