From 653a14442f8b65162b7530de5c0452df6d793519 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 15 Oct 2024 02:57:20 +0200 Subject: [PATCH] restructured application -> started to use more dlls --- gpuapi/RenderUtils.h | 21 +- gpuapi/opengl/OpenglUtils.h | 2 +- log/Debug.h | 1 - log/DebugMemory.h | 7 +- log/Log.h | 4 + math/matrix/MatrixFloat32.h | 4 +- models/Attrib.h | 32 --- models/extension/ExtensionType.h | 11 + models/settings/Settings.h | 8 + module/Module.h | 26 +++ module/ModuleManager.h | 52 +++++ object/Mesh.h | 2 + object/Object.h | 19 +- stdlib/Types.h | 21 +- ui/UIAttribute.h | 152 +++++++++++++ ui/UIElement.h | 18 +- ui/UIElementType.h | 34 +++ ui/UILayout.h | 46 +--- ui/UITheme.h | 352 +++++++++++++++++++++++++++++++ utils/StringUtils.h | 99 ++++----- 20 files changed, 773 insertions(+), 138 deletions(-) delete mode 100644 models/Attrib.h create mode 100644 models/extension/ExtensionType.h create mode 100644 module/Module.h create mode 100644 module/ModuleManager.h create mode 100644 ui/UIAttribute.h create mode 100644 ui/UITheme.h diff --git a/gpuapi/RenderUtils.h b/gpuapi/RenderUtils.h index 7356f3f..4382de0 100644 --- a/gpuapi/RenderUtils.h +++ b/gpuapi/RenderUtils.h @@ -11,11 +11,15 @@ #include #include +#include "../stdlib/Types.h" +#include "../utils/StringUtils.h" #include "../math/matrix/MatrixFloat32.h" #include "../font/Font.h" +#include "../object/Vertex.h" inline -void vertex_degenerate_create(Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, +void vertex_degenerate_create( + Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, f32 x, f32 y ) { // Degenerate triangles @@ -40,7 +44,8 @@ void vertex_degenerate_create(Vertex3DTextureColorIndex* __restrict vertices, ui } inline -void vertex_line_create(Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, +void vertex_line_create( + Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, f32 x1, f32 y1, f32 x2, f32 y2, f32 thickness, int32 align_h, int32 align_v, uint32 color_index = 0, f32 tex_x1 = 0.0f, f32 tex_y1 = 0.0f, f32 tex_x2 = 0.0f, f32 tex_y2 = 0.0f ) { @@ -118,7 +123,8 @@ void vertex_line_create(Vertex3DTextureColorIndex* __restrict vertices, uint32* } inline -void vertex_rect_create(Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, +void vertex_rect_create( + Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, f32 x, f32 y, f32 width, f32 height, int32 align_h, int32 align_v, uint32 color_index = 0, f32 tex_x1 = 0.0f, f32 tex_y1 = 0.0f, f32 tex_x2 = 0.0f, f32 tex_y2 = 0.0f ) { @@ -171,7 +177,8 @@ void vertex_rect_create(Vertex3DTextureColorIndex* __restrict vertices, uint32* } inline -void vertex_rect_border_create(Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, +void vertex_rect_border_create( + Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, f32 x, f32 y, f32 width, f32 height, f32 thickness, int32 align_h, int32 align_v, uint32 color_index = 0, f32 tex_x1 = 0.0f, f32 tex_y1 = 0.0f, f32 tex_x2 = 0.0f, f32 tex_y2 = 0.0f ) { @@ -320,7 +327,8 @@ void vertex_input(Vertex3DTextureColorIndex* __restrict vertices, uint32* __rest ); } -void text_calculate_dimensions(f32* __restrict width, f32* __restrict height, +void text_calculate_dimensions( + f32* __restrict width, f32* __restrict height, const Font* __restrict font, const char* text, f32 scale, int32 length ) { f32 x = 0; @@ -362,7 +370,8 @@ void text_calculate_dimensions(f32* __restrict width, f32* __restrict height, *height = y; } -void vertex_text_create(Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, +void vertex_text_create( + Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex, f32 x, f32 y, f32 width, f32 height, int32 align_h, int32 align_v, const Font* __restrict font, const char* __restrict text, f32 size, uint32 color_index = 0 ) { diff --git a/gpuapi/opengl/OpenglUtils.h b/gpuapi/opengl/OpenglUtils.h index 7254d69..c1eb8cf 100644 --- a/gpuapi/opengl/OpenglUtils.h +++ b/gpuapi/opengl/OpenglUtils.h @@ -12,9 +12,9 @@ #include "../../stdlib/Types.h" #include "../../memory/RingMemory.h" #include "../../utils/TestUtils.h" -#include "../../models/Attrib.h" #include "../../object/Texture.h" #include "../../utils/StringUtils.h" +#include "../../log/Log.h" #include "../RenderUtils.h" #include "Opengl.h" diff --git a/log/Debug.h b/log/Debug.h index ddcaeb7..9752f49 100644 --- a/log/Debug.h +++ b/log/Debug.h @@ -23,6 +23,5 @@ struct DebugContainer { HANDLE log_fp; #endif }; -global_persist DebugContainer* debug_container; #endif \ No newline at end of file diff --git a/log/DebugMemory.h b/log/DebugMemory.h index ada3bbc..ebcb0c0 100644 --- a/log/DebugMemory.h +++ b/log/DebugMemory.h @@ -13,7 +13,6 @@ #include #include "../stdlib/Types.h" -#include "Debug.h" // required for __rdtsc #if _WIN32 @@ -49,6 +48,12 @@ struct DebugMemoryContainer { }; #if DEBUG || INTERNAL + void debug_memory_init(uint64, uint64); + void debug_memory_read(uint64, uint64, const char*); + void debug_memory_write(uint64, uint64, const char*); + void debug_memory_delete(uint64, uint64, const char*); + void debug_memory_reset(); + #define DEBUG_MEMORY_INIT(start, size) debug_memory_init((start), (size)) #define DEBUG_MEMORY_READ(start, size) debug_memory_read((start), (size), __func__) #define DEBUG_MEMORY_WRITE(start, size) debug_memory_write((start), (size), __func__) diff --git a/log/Log.h b/log/Log.h index d58ad16..44560ea 100644 --- a/log/Log.h +++ b/log/Log.h @@ -51,6 +51,10 @@ struct LogMemory { uint64 end; }; +void log_to_file(); +void log(const char* str, bool should_log, bool save, const char* file, const char* function, int32 line); +void log(const char* format, LogDataType data_type, void* data, bool should_log, bool save, const char* file, const char* function, int32 line); + #if (LOG_LEVEL == 0) // Don't perform any logging at log level 0 #define LOG(str, should_log, save) ((void) 0) diff --git a/math/matrix/MatrixFloat32.h b/math/matrix/MatrixFloat32.h index 4fef0bf..846f562 100644 --- a/math/matrix/MatrixFloat32.h +++ b/math/matrix/MatrixFloat32.h @@ -9,10 +9,12 @@ #ifndef TOS_MATH_MATRIX_FLOAT32_H #define TOS_MATH_MATRIX_FLOAT32_H +#include +#include +#include #include "../../stdlib/Intrinsics.h" #include "../../utils/MathUtils.h" #include "../../utils/TestUtils.h" -#include // @todo Implement intrinsic versions! diff --git a/models/Attrib.h b/models/Attrib.h deleted file mode 100644 index b813664..0000000 --- a/models/Attrib.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Jingga - * - * @copyright Jingga - * @license OMS License 2.0 - * @version 1.0.0 - * @link https://jingga.app - */ -#ifndef TOS_ATTRIB_H -#define TOS_ATTRIB_H - -#if OPENGL - #include "../gpuapi/opengl/Opengl.h" - #include "../object/Vertex.h" - - struct Attrib { - GLuint program; - VertexRef vertices; - GLuint matrix; - GLuint sampler; - GLuint camera; - GLuint timer; - GLuint extra1; - GLuint extra2; - GLuint extra3; - GLuint extra4; - }; -#else - struct Attrib {}; -#endif - -#endif \ No newline at end of file diff --git a/models/extension/ExtensionType.h b/models/extension/ExtensionType.h new file mode 100644 index 0000000..f9e328e --- /dev/null +++ b/models/extension/ExtensionType.h @@ -0,0 +1,11 @@ +#ifndef TOS_EXTENSION_TYPE_H +#define TOS_EXTENSION_TYPE_H + +enum ExtensionType { + EXTENSION_TYPE_NONE, + + EXTENSION_TYPE_HUD, + EXTENSION_TYPE_GENERAL, +}; + +#endif \ No newline at end of file diff --git a/models/settings/Settings.h b/models/settings/Settings.h index 7f1f1e5..f6f6744 100644 --- a/models/settings/Settings.h +++ b/models/settings/Settings.h @@ -12,6 +12,7 @@ #include "../../stdlib/Types.h" #include "../chat/ChatStatus.h" #include "setting_types.h" +#include "../../module/Module.h" #if _WIN32 #include @@ -48,6 +49,8 @@ #define RENDER_PAYER_CHUNK_RADIUS 3 #endif +#define MAX_ACTIVE_EXTENSIONS 15 + // @todo remove default values because we will load them during startup struct SSettings { char path[MAX_PATH]; @@ -355,6 +358,9 @@ struct CSettings { bool input_lock_cursor_to_window = true; bool input_click_to_move = true; + int32 active_module_count; + Module* active_modules; + // Hotkey settings // @todo hotkey combination e.g. alt+1 byte hotkeys_movement_up = 0x57; // W @@ -428,6 +434,8 @@ struct CSettings { byte hotkeys_camera_3 = 0x0; // @todo implement the actual camera settings + + char modules[MAX_ACTIVE_EXTENSIONS * 32]; }; #endif \ No newline at end of file diff --git a/module/Module.h b/module/Module.h new file mode 100644 index 0000000..3f6f906 --- /dev/null +++ b/module/Module.h @@ -0,0 +1,26 @@ +#ifndef TOS_MODULE_H +#define TOS_MODULE_H + +#include "../stdlib/Types.h" + +#ifdef _WIN32 + #include "../../GameEngine/platform/win32/Library.h" +#endif + +enum ModuleType { + MODULE_TYPE_HUD, + MODULE_TYPE_UI, + MODULE_TYPE_WINDOW, // Additional window + MODULE_TYPE_API, // Extracts data and sends it somewhere (website, file, etc.) +}; + +struct Module { + char name[128]; + int32 version; + ModuleType type; + bool is_active; + + Library lib; +}; + +#endif \ No newline at end of file diff --git a/module/ModuleManager.h b/module/ModuleManager.h new file mode 100644 index 0000000..12a7c8d --- /dev/null +++ b/module/ModuleManager.h @@ -0,0 +1,52 @@ +#ifndef TOS_MODULE_MANAGER_H +#define TOS_MODULE_MANAGER_H + +#include "Module.h" + +#if _WIN32 + #include "../platform/win32/UtilsWin32.h" +#endif + +struct ModuleManager { + int module_count; + Module* modules; +}; + +void module_file_parse(const char* path, Module* module, RingMemory* ring) +{ + FileBody file = {}; + file.content = ring_get_memory(ring, MEGABYTE * 1); + file_read(path, &file); + + char *rest = NULL; + char *line = strtok_r((char *) file.content, "\n", &rest); + + const int32 MAX_LENGTH = 128; + char name[MAX_LENGTH]; + char value[MAX_LENGTH]; + const char* space; + + while (line != NULL) { + space = strchr(line, ' '); + if (space != NULL) { + size_t name_length = space - line; + strncpy_s(name, MAX_LENGTH, line, name_length); + name[name_length] = '\0'; + strncpy_s(value, MAX_LENGTH, space + 1, MAX_LENGTH - 1); + value[MAX_LENGTH - 1] = '\0'; + + if (strcmp(name, "name") == 0) { + strncpy_s(module->name, MAX_LENGTH, value, sizeof(module->name) - 1); + module->name[strlen(value)] = '\0'; + } else if (strcmp(name, "version") == 0) { + module->version = (byte) atol(value); + } else if (strcmp(name, "type") == 0) { + module->type = (ModuleType) atol(value); + } + } + + line = strtok_r(rest, "\n", &rest); + } +} + +#endif \ No newline at end of file diff --git a/object/Mesh.h b/object/Mesh.h index b9e5cc7..bc8c222 100644 --- a/object/Mesh.h +++ b/object/Mesh.h @@ -21,6 +21,8 @@ struct Mesh { byte* data; // memory owner that subdevides into the pointers below + // @todo Implement the version into the file, currently not implemented + int32 version; uint32 object; uint32 group_count; diff --git a/object/Object.h b/object/Object.h index bc43b8e..bd8885c 100644 --- a/object/Object.h +++ b/object/Object.h @@ -9,11 +9,11 @@ #ifndef TOS_OBJECT_H #define TOS_OBJECT_H -#include "Vertex.h" #include "../stdlib/Types.h" #include "../memory/RingMemory.h" #include "../utils/EndianUtils.h" -#include "../compression/LZP.h" + +#include "Vertex.h" #if _WIN32 #include "../platform/win32/UtilsWin32.h" @@ -24,7 +24,12 @@ #include "Mesh.h" #include "../stdlib/simd/SIMD_I32.h" +#define MESH_VERSION 1 + +// @todo The name Object.h is stupid, copy content to Mesh.h + // @todo also handle textures etc. +// WARNING: mesh needs to have memory already reserved and asigned to data void object_from_file_txt( RingMemory* ring, const char* path, @@ -35,6 +40,7 @@ void object_from_file_txt( file_read(path, &file, ring); char* pos = (char *) file.content; + mesh->version = strtol(pos, &pos, 10); ++pos; int32 object_index = 0; int32 group_index = 0; @@ -366,6 +372,10 @@ int32 object_from_file( byte* pos = file.content; + // Read version + //mesh->version = *((int32 *) pos); + //pos += sizeof(mesh->version); + // Read base data mesh->vertex_type = *((int32 *) pos); pos += sizeof(mesh->vertex_type); @@ -383,6 +393,7 @@ int32 object_from_file( pos += sizeof(mesh->color_count); #if !_WIN32 && !__LITTLE_ENDIAN + mesh->version = endian_swap(mesh->version); mesh->vertex_type = endian_swap(mesh->vertex_type); mesh->verted_count = endian_swap(mesh->verted_count); mesh->normal_count = endian_swap(mesh->normal_count); @@ -546,6 +557,10 @@ void object_to_file( file.content = ring_get_memory(ring, file.size, 64); byte* pos = file.content; + // version + memcpy(pos, &mesh->version, sizeof(mesh->version)); + pos += sizeof(mesh->version); + // vertices memcpy(pos, &vertex_save_format, sizeof(vertex_save_format)); pos += sizeof(vertex_save_format); diff --git a/stdlib/Types.h b/stdlib/Types.h index 4b083f8..dceb6d5 100644 --- a/stdlib/Types.h +++ b/stdlib/Types.h @@ -179,10 +179,23 @@ struct v3_f32 { struct v4_f32 { union { struct { - f32 x; - f32 y; - f32 z; - f32 w; + union { + f32 x; + f32 r; + }; + union { + f32 y; + f32 g; + }; + + union { + f32 z; + f32 b; + }; + union { + f32 w; + f32 a; + }; }; f32 vec[4]; diff --git a/ui/UIAttribute.h b/ui/UIAttribute.h new file mode 100644 index 0000000..0c9dbd1 --- /dev/null +++ b/ui/UIAttribute.h @@ -0,0 +1,152 @@ +#ifndef TOS_UI_STYLE_H +#define TOS_UI_STYLE_H + +#include "../stdlib/Types.h" + +struct UIAttribute { + // Attributes use ids instead of strings + int32 attribute_id; + + union { + char value_str[32]; + int32 value_int; + f32 value_float; + v4_f32 value_v4_f32; + }; +}; + +struct UIAttributeGroup { + int32 attribute_count; + UIAttribute* attributes; +}; + +enum UIAttributeType { + UI_ATTRIBUTE_TYPE_FONT_COLOR, + UI_ATTRIBUTE_TYPE_FONT_SIZE, + UI_ATTRIBUTE_TYPE_FONT_WEIGHT, + UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT, + + UI_ATTRIBUTE_TYPE_ALIGN_H, + UI_ATTRIBUTE_TYPE_ALIGN_V, + + UI_ATTRIBUTE_TYPE_ZINDEX, + + UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR, + UI_ATTRIBUTE_TYPE_BACKGROUND_IMG, + UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY, + UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_V, + UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_H, + UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_STYLE, + + UI_ATTRIBUTE_TYPE_BORDER_COLOR, + UI_ATTRIBUTE_TYPE_BORDER_WIDTH, + UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR, + UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH, + UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR, + UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH, + UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR, + UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH, + UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR, + UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH, + + UI_ATTRIBUTE_TYPE_PADDING, + UI_ATTRIBUTE_TYPE_PADDING_TOP, + UI_ATTRIBUTE_TYPE_PADDING_RIGHT, + UI_ATTRIBUTE_TYPE_PADDING_BOTTOM, + UI_ATTRIBUTE_TYPE_PADDING_LEFT, + + UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR, + UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE, + UI_ATTRIBUTE_TYPE_SHADOW_INNER_DISTANCE, + + UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR, + UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE, + UI_ATTRIBUTE_TYPE_SHADOW_OUTER_DISTANCE, + + UI_ATTRIBUTE_TYPE_TRANSITION_ANIMATION, + UI_ATTRIBUTE_TYPE_TRANSITION_DURATION, + + UI_ATTRIBUTE_TYPE_SIZE, +}; + +constexpr const char* ui_attribute_type_to_string(int32 e) +{ + switch (e) { + case UI_ATTRIBUTE_TYPE_FONT_COLOR: + return "font_color"; + case UI_ATTRIBUTE_TYPE_FONT_SIZE: + return "font_size"; + case UI_ATTRIBUTE_TYPE_FONT_WEIGHT: + return "font_weight"; + case UI_ATTRIBUTE_TYPE_FONT_LINE_HEIGHT: + return "font_line_height"; + case UI_ATTRIBUTE_TYPE_ALIGN_H: + return "align_h"; + case UI_ATTRIBUTE_TYPE_ALIGN_V: + return "align_v"; + case UI_ATTRIBUTE_TYPE_ZINDEX: + return "zindex"; + case UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR: + return "background_color"; + case UI_ATTRIBUTE_TYPE_BACKGROUND_IMG: + return "background_img"; + case UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY: + return "background_img_opacity"; + case UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_V: + return "background_img_position_v"; + case UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_H: + return "background_img_position_h"; + case UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_STYLE: + return "background_img_style"; + case UI_ATTRIBUTE_TYPE_BORDER_COLOR: + return "border_color"; + case UI_ATTRIBUTE_TYPE_BORDER_WIDTH: + return "border_width"; + case UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR: + return "border_top_color"; + case UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH: + return "border_top_width"; + case UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR: + return "border_right_color"; + case UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH: + return "border_right_width"; + case UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR: + return "border_bottom_color"; + case UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH: + return "border_bottom_width"; + case UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR: + return "border_left_color"; + case UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH: + return "border_left_width"; + case UI_ATTRIBUTE_TYPE_PADDING: + return "padding"; + case UI_ATTRIBUTE_TYPE_PADDING_TOP: + return "padding_top"; + case UI_ATTRIBUTE_TYPE_PADDING_RIGHT: + return "padding_right"; + case UI_ATTRIBUTE_TYPE_PADDING_BOTTOM: + return "padding_bottom"; + case UI_ATTRIBUTE_TYPE_PADDING_LEFT: + return "padding_left"; + case UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR: + return "shadow_inner_color"; + case UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE: + return "shadow_inner_angle"; + case UI_ATTRIBUTE_TYPE_SHADOW_INNER_DISTANCE: + return "shadow_inner_distance"; + case UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR: + return "shadow_outer_color"; + case UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE: + return "shadow_outer_angle"; + case UI_ATTRIBUTE_TYPE_SHADOW_OUTER_DISTANCE: + return "shadow_outer_distance"; + case UI_ATTRIBUTE_TYPE_TRANSITION_ANIMATION: + return "transition_animation"; + case UI_ATTRIBUTE_TYPE_TRANSITION_DURATION: + return "transition_duration"; + } + + return NULL; +} + +#endif \ No newline at end of file diff --git a/ui/UIElement.h b/ui/UIElement.h index 7f4f0cb..4aca7a5 100644 --- a/ui/UIElement.h +++ b/ui/UIElement.h @@ -6,6 +6,13 @@ #include "UIAnchor.h" #include "../stdlib/Types.h" +struct UIElementDimension { + int16 x1; + int16 y1; + int16 x2; + int16 y2; +}; + struct UIElement { int id; UIElementType type; @@ -13,10 +20,7 @@ struct UIElement { int window_id; int panel_id; - float x; - float y; - float width; - float height; + UIElementDimension dimension; UIAlignH align_h; UIAlignV align_v; @@ -26,8 +30,10 @@ struct UIElement { bool is_active; bool is_focused; - v4_f32 color; - v4_f32 background_color; + int16 scroll_x; + int16 scroll_y; + + // @todo animation state }; #endif \ No newline at end of file diff --git a/ui/UIElementType.h b/ui/UIElementType.h index 6eb01e5..c5d0adf 100644 --- a/ui/UIElementType.h +++ b/ui/UIElementType.h @@ -15,6 +15,40 @@ enum UIElementType { UI_ELEMENT_TYPE_VIEW_WINDOW, UI_ELEMENT_TYPE_VIEW_PANEL, UI_ELEMENT_TYPE_VIEW_TAB, + + UI_ELEMENT_TYPE_SIZE, }; +constexpr const char* ui_element_type_to_string(UIElementType e) +{ + switch (e) { + case UI_ELEMENT_TYPE_BUTTON: + return "button"; + case UI_ELEMENT_TYPE_SELECT: + return "select"; + case UI_ELEMENT_TYPE_DROPDOWN: + return "dropdown"; + case UI_ELEMENT_TYPE_TEXTFIELD: + return "textfield"; + case UI_ELEMENT_TYPE_TEXTAREA: + return "textarea"; + case UI_ELEMENT_TYPE_IMAGE: + return "image"; + case UI_ELEMENT_TYPE_TEXT: + return "text"; + case UI_ELEMENT_TYPE_LINK: + return "link"; + case UI_ELEMENT_TYPE_TABLE: + return "table"; + case UI_ELEMENT_TYPE_VIEW_WINDOW: + return "view_window"; + case UI_ELEMENT_TYPE_VIEW_PANEL: + return "view_panel"; + case UI_ELEMENT_TYPE_VIEW_TAB: + return "view_tab"; + } + + return NULL; +} + #endif \ No newline at end of file diff --git a/ui/UILayout.h b/ui/UILayout.h index 4cad065..09d46ab 100644 --- a/ui/UILayout.h +++ b/ui/UILayout.h @@ -3,49 +3,21 @@ #include "../stdlib/Types.h" -#include "UIPosition.h" +#include "UIElement.h" #include "UILocation.h" struct UILayout { - int x; - int y; + int32 ui_deadzone_count = 5; + UIElementDimension ui_deadzone[5]; - int width; - int height; + int32 element_hoverable_count; + UIElementDimension* elements_hoverable; - UIPosition position; + int32 element_interactible_count; + UIElementDimension* elements_interactible; - UILocation self; - UILocation children; - - int margin[4]; - int padding[4]; - - int border_width[4]; - v3_int32 border_color; - - v3_int32 color_background; - v3_int32 color_foreground; - - int image_background; - int image_width; - int image_height; - - // Horizontal and vertical scaling can have 2 scalable areas - int image_horizontal_area1[4]; - int image_horizontal_area2[4]; - - int image_vertical_area1[4]; - int image_vertical_area2[4]; - bool image_repeatable; - - int shadow_outer_width[4]; - int shadow_outer_color; - - int shadow_inner_width[4]; - int shadow_inner_color; - - int curser_style; + int32 element_count; + UIElement* element; }; #endif \ No newline at end of file diff --git a/ui/UITheme.h b/ui/UITheme.h new file mode 100644 index 0000000..c663434 --- /dev/null +++ b/ui/UITheme.h @@ -0,0 +1,352 @@ +#ifndef TOS_UI_THEME_H +#define TOS_UI_THEME_H + +#include "../stdlib/Types.h" +#include "../memory/RingMemory.h" +#include "../utils/EndianUtils.h" +#include "../stdlib/HashMap.h" +#include "../font/Font.h" + +#include "UIAttribute.h" +#include "UIElementType.h" + +#if _WIN32 + #include "../platform/win32/UtilsWin32.h" +#else + #include "../platform/linux/UtilsLinux.h" +#endif + +#define UI_THEME_VERSION 1 + +struct UITheme { + byte* data; + + int32 version; + char name[32]; + bool is_active; + + // Every element has all the style attributes + UIAttribute styles_global[UI_ELEMENT_TYPE_SIZE * UI_ATTRIBUTE_TYPE_SIZE]; + + // A theme may have N named styles + // @todo We should probably create a hashmap + // key = name + // value = pointer to group (in the file we store the offset when we load it into memory convert it to pointer) + HashMap hash_map; + + int32 style_group_count; + UIAttributeGroup* style_groups; + + Font font; + + // @todo add cursor styles +}; + +// WARNING: theme needs to have memory already reserved and asigned to data +void theme_from_file_txt( + RingMemory* ring, + const char* path, + UITheme* theme +) { + FileBody file; + file_read(path, &file, ring); + + char* pos = (char *) file.content; + theme->version = strtol(pos, &pos, 10); ++pos; + + bool block_open = false; + char block_name[32]; + char attribute_name[32]; + bool last_token_newline = false; + + while (*pos != '\0') { + while (*pos == ' ' || *pos == '\t') { + ++pos; + } + + if (*pos == '\n') { + ++pos; + + // 2 new lines => closing block + if (last_token_newline) { + block_open = false; + last_token_newline = false; + } else { + last_token_newline = true; + } + + continue; + } + + last_token_newline = false; + + if (!block_open) { + int32 i = 0; + while (*pos != '\0' && *pos != ' ' && *pos != '\n' && i < 31) { + block_name[i] = *pos; + ++pos; + ++i; + } + + block_name[i] = '\0'; + + if (*block_name == '#') { + // Named style + // @todo create new style + } + + continue; + } + + int32 i = 0; + while (*pos != '\0' && *pos != ' ' && *pos != '\n' && i < 31) { + attribute_name[i] = *pos; + ++pos; + ++i; + } + + attribute_name[i] = '\0'; + + // Skip any white spaces or other delimeters + while (*pos == ' ' || *pos == ':') { + ++pos; + } + + ASSERT_SIMPLE((*pos != '\0' && *pos != '\n')); + + // Handle different attribute types + UIAttribute attribute; + if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_FONT_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + 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; + } 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; + } 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; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_ALIGN_V), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_ALIGN_V; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_ZINDEX), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_ZINDEX; + attribute.value_float = SWAP_ENDIAN_LITTLE(strtof(pos, &pos)); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG; + + i = 0; + while (*pos != '\0' && *pos != '\n') { + attribute.value_str[i] = *pos++; + } + + attribute.value_str[i] = '\0'; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY; + attribute.value_float = SWAP_ENDIAN_LITTLE(strtof(pos, &pos)); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_V), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_V; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_H), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_POSITION_H; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_STYLE), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_STYLE; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_WIDTH), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_WIDTH; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_TOP), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_TOP; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_RIGHT), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_RIGHT; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_BOTTOM), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_BOTTOM; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_PADDING_LEFT), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_PADDING_LEFT; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE; + attribute.value_float = strtof(pos, &pos); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_INNER_DISTANCE), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_DISTANCE; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR), attribute_name) == 0) { + ++pos; // Skip '#' + + attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR; + uint32 value = (uint32) strtoul(pos, &pos, 16); + pos += 4; + + attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f; + attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f; + attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f; + attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE; + attribute.value_float = strtof(pos, &pos); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_SHADOW_OUTER_DISTANCE), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_DISTANCE; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_TRANSITION_ANIMATION), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_TRANSITION_ANIMATION; + attribute.value_int = strtoul(pos, &pos, 10); ++pos; + } else if (strcmp(ui_attribute_type_to_string(UI_ATTRIBUTE_TYPE_TRANSITION_DURATION), attribute_name) == 0) { + attribute.attribute_id = UI_ATTRIBUTE_TYPE_TRANSITION_DURATION; + attribute.value_float = strtof(pos, &pos); ++pos; + } else { + continue; + } + + if (block_name[0] == '#') { + // Named block + } else { + // Global default elements and their attributes + int32 element_type = -1; + for (int j = 0; j < UI_ELEMENT_TYPE_SIZE; ++j) { + if (strcmp(ui_element_type_to_string((UIElementType) j), block_name) == 0) { + element_type = j; + break; + } + } + + if (element_type < 0) { + continue; + } + + memcpy( + theme->styles_global + element_type * UI_ATTRIBUTE_TYPE_SIZE, + &attribute, + sizeof(attribute) + ); + } + } +} + +void theme_from_file( + RingMemory* ring, + const char* path, + UITheme* theme +) { + // version + // global definitions + // names count + // +} + +void theme_to_file(RingMemory* ring, + const char* path, + const UITheme* theme +) { + +} + +#endif \ No newline at end of file diff --git a/utils/StringUtils.h b/utils/StringUtils.h index e1bb11a..b056315 100644 --- a/utils/StringUtils.h +++ b/utils/StringUtils.h @@ -15,6 +15,16 @@ #include "../stdlib/Types.h" +constexpr +size_t strlen_compile_time(const char* str) { + size_t len = 0; + while (str[len] != '\0') { + ++len; + } + + return len; +} + inline int32 utf8_encode(uint32 codepoint, char* out) { @@ -50,8 +60,8 @@ int32 utf8_encode(uint32 codepoint, char* out) } inline -int32 utf8_decode(const char* in, uint32* codepoint) { - unsigned char ch = (unsigned char) in[0]; +int32 utf8_decode(const char* __restrict in, uint32* __restrict codepoint) { + unsigned char ch = (unsigned char) *in; if (ch <= 0x7F) { // 1-byte sequence (ASCII) @@ -134,9 +144,30 @@ int32 utf8_get_char_at(const char* in, int32 index) { } inline -void wchar_to_char(const wchar_t* src, char* dest, int32 length = 0) +void wchar_to_char(wchar_t* str, int32 length = 0) +{ + char *dest = (char *) str; + size_t len = wcslen(str) * sizeof(wchar_t); + + if (length > 0 && length < len) { + len = length; + } + + for (int32 i = 0; i < len; ++i) { + if (*str != '\0') { + *dest = (char) *str; + ++dest; + } + + ++str; + } + + *dest = '\0'; +} + +inline +void wchar_to_char(const wchar_t* __restrict src, char* __restrict dest, int32 length = 0) { - char* temp = (char* ) src; size_t len = wcslen(src) * sizeof(wchar_t); if (length > 0 && length < len) { @@ -144,12 +175,12 @@ void wchar_to_char(const wchar_t* src, char* dest, int32 length = 0) } for (int32 i = 0; i < len; ++i) { - if (*temp != '\0') { - *dest = (char) *temp; + if (*src != '\0') { + *dest = (char) *src; ++dest; } - ++temp; + ++src; } *dest = '\0'; @@ -176,7 +207,7 @@ int32 str_to_int(const char *str) return result * sign; } -inline size_t str_count(const char* str, const char* substr) +inline size_t str_count(const char* __restrict str, const char* __restrict substr) { size_t l1 = strlen(str); size_t l2 = strlen(substr); @@ -228,27 +259,27 @@ str_concat( *dst = '\0'; } -char* strtok(char* str, const char* delim, char* *saveptr) -{ +char* strtok(char* str, const char* __restrict delim, char* *key) { + char* result; if (str == NULL) { - str = *saveptr; + str = *key; } - if (str == NULL || *str == '\0') { + str += strspn(str, delim); + if (*str == '\0') { return NULL; } - char* token_start = str; - char* token_end = strpbrk(token_start, delim); + result = str; + str += strcspn(str, delim); - if (token_end == NULL) { - *saveptr = NULL; - } else { - *token_end = '\0'; - *saveptr = token_end + 1; + if (*str) { + *str++ = '\0'; } - return token_start; + *key = str; + + return result; } inline @@ -316,32 +347,6 @@ void create_const_name(const unsigned char* name, char* modified_name) } } -/** - * Custom implementation of strtok_r/strtok_s - */ -char* strtok_(char* str, const char* delim, char* *key) { - char* result; - if (str == NULL) { - str = *key; - } - - str += strspn(str, delim); - if (*str == '\0') { - return NULL; - } - - result = str; - str += strcspn(str, delim); - - if (*str) { - *str++ = '\0'; - } - - *key = str; - - return result; -} - bool str_ends_with(const char* str, const char* suffix) { if (!str || !suffix) { return false; @@ -358,7 +363,7 @@ bool str_ends_with(const char* str, const char* suffix) { } // WARNING: result needs to have the correct length -void str_replace(const char* str, const char* search, const char* replace, char* result) { +void str_replace(const char* str, const char* __restrict search, const char* __restrict replace, char* result) { if (str == NULL || search == NULL || replace == NULL || result == NULL) { return; }