diff --git a/asset/AssetManagementSystem.h b/asset/AssetManagementSystem.h index 0a10963..a71ab1d 100644 --- a/asset/AssetManagementSystem.h +++ b/asset/AssetManagementSystem.h @@ -15,6 +15,7 @@ #include "../memory/ChunkMemory.h" #include "../utils/TestUtils.h" #include "../stdlib/HashMap.h" +#include "../log/DebugMemory.h" // The major asset types should have their own asset component system // All other entities are grouped together in one asset component system @@ -47,21 +48,39 @@ void ams_create(AssetManagementSystem* ams, BufferMemory* buf, int32 chunk_size, // setup hash_map hashmap_create(&ams->hash_map, count, sizeof(HashEntryInt64), buf); + // setup asset_memory + chunk_init(&ams->asset_memory, buf, count, sizeof(Asset), 1); + + // setup asset_data_memory + chunk_init(&ams->asset_data_memory, buf, count, chunk_size, 1); + + ams->first = NULL; + ams->last = NULL; +} + +// WARNING: buf size see ams_get_buffer_size +void ams_create(AssetManagementSystem* ams, byte* buf, int chunk_size, int count) +{ + ASSERT_SIMPLE(chunk_size); + + // setup hash_map + hashmap_create(&ams->hash_map, count, sizeof(HashEntryInt64), buf); + // setup asset_memory ams->asset_memory.count = count; ams->asset_memory.chunk_size = sizeof(Asset); ams->asset_memory.last_pos = -1; ams->asset_memory.alignment = 1; - ams->asset_memory.memory = buffer_get_memory(buf, sizeof(Asset) * count); - ams->asset_memory.free = (uint64 *) buffer_get_memory(buf, CEIL_DIV(count, 64) * sizeof(uint64)); + ams->asset_memory.memory = buf; + ams->asset_memory.free = (uint64 *) (ams->asset_memory.memory + ams->asset_memory.chunk_size * count); // setup asset_data_memory ams->asset_data_memory.count = count; ams->asset_data_memory.chunk_size = chunk_size; ams->asset_data_memory.last_pos = -1; ams->asset_data_memory.alignment = 1; - ams->asset_data_memory.memory = buffer_get_memory(buf, chunk_size * count, 64); - ams->asset_data_memory.free = (uint64 *) buffer_get_memory(buf, CEIL_DIV(count, 64) * sizeof(uint64)); + ams->asset_data_memory.memory = (byte *) (ams->asset_memory.free + CEIL_DIV(count, 64)); + ams->asset_data_memory.free = (uint64 *) (ams->asset_data_memory.memory + ams->asset_data_memory.chunk_size * count); ams->first = NULL; ams->last = NULL; @@ -81,32 +100,6 @@ int64 ams_get_buffer_size(int count, int chunk_size) + chunk_size * count + CEIL_DIV(count, 64) * sizeof(uint64); // asset_data_memory } -// WARNING: buf size see ams_get_buffer_size -void ams_create(AssetManagementSystem* ams, byte* buf, int chunk_size, int count) -{ - // setup hash_map - hashmap_create(&ams->hash_map, count, sizeof(HashEntryInt64), buf); - - // setup asset_memory - ams->asset_memory.count = count; - ams->asset_memory.chunk_size = sizeof(Asset); - ams->asset_memory.last_pos = -1; - ams->asset_memory.alignment = 1; - ams->asset_memory.memory = buf; - ams->asset_memory.free = (uint64 *) (ams->asset_memory.memory + sizeof(Asset) * count); - - // setup asset_data_memory - ams->asset_data_memory.count = count; - ams->asset_data_memory.chunk_size = chunk_size; - ams->asset_data_memory.last_pos = -1; - ams->asset_data_memory.alignment = 1; - ams->asset_data_memory.memory = (byte *) (ams->asset_data_memory.free + CEIL_DIV(count, 64)); - ams->asset_data_memory.free = (uint64 *) (ams->asset_data_memory.memory + chunk_size * count); - - ams->first = NULL; - ams->last = NULL; -} - inline void ams_update_stats(AssetManagementSystem* ams) { @@ -232,7 +225,9 @@ Asset* ams_reserve_asset(AssetManagementSystem* ams, const char* name, uint32 el chunk_reserve_index(&ams->asset_data_memory, free_asset, elements, true); asset->self = chunk_get_element(&ams->asset_data_memory, free_asset); asset->size = elements; // Curcial for freeing - asset->ram_size = ams->asset_memory.chunk_size * elements; + asset->ram_size = (ams->asset_memory.chunk_size + ams->asset_data_memory.chunk_size) * elements; + + DEBUG_MEMORY_RESERVE((uint64) asset->self, elements * ams->asset_data_memory.chunk_size, 180); // @performance Do we really want a double linked list. Are we really using this feature or is the free_index enough? if (free_asset > 0 && free_asset < ams->asset_memory.count - 1) { diff --git a/gpuapi/opengl/Shader.h b/gpuapi/opengl/Shader.h new file mode 100644 index 0000000..acb0776 --- /dev/null +++ b/gpuapi/opengl/Shader.h @@ -0,0 +1,19 @@ +/** + * Jingga + * + * @copyright Jingga + * @license OMS License 2.0 + * @version 1.0.0 + * @link https://jingga.app + */ +#ifndef TOS_GPUAPI_OPENGL_SHADER_H +#define TOS_GPUAPI_OPENGL_SHADER_H + +#include "../../stdlib/Types.h" + +struct Shader { + uint32 shader_id; + uint32 shader_locations[10]; +}; + +#endif \ No newline at end of file diff --git a/gpuapi/opengl/ShaderUtils.h b/gpuapi/opengl/ShaderUtils.h index 2a00a13..642ab81 100644 --- a/gpuapi/opengl/ShaderUtils.h +++ b/gpuapi/opengl/ShaderUtils.h @@ -13,6 +13,7 @@ #include "../../math/matrix/MatrixFloat32.h" #include "Opengl.h" +// Set value based on shader uniform name inline void shader_set_value(uint32 id, const char* name, bool value) { @@ -67,6 +68,61 @@ void shader_set_m4(uint32 id, const char* name, const f32* value) glUniformMatrix4fv(glGetUniformLocation(id, name), 1, GL_FALSE, value); } +// Set value based on uniform location +inline +void shader_set_value(uint32 location, bool value) +{ + glUniform1i(location, (int32) value); +} + +inline +void shader_set_value(uint32 location, int32 value) +{ + glUniform1i(location, value); +} + +inline +void shader_set_value(uint32 location, f32 value) +{ + glUniform1f(location, value); +} + +inline +void shader_set_v2(uint32 location, const f32* value) +{ + glUniform2fv(location, 1, value); +} + +inline +void shader_set_v3(uint32 location, const f32* value) +{ + glUniform3fv(location, 1, value); +} + +inline +void shader_set_v4(uint32 location, const f32* value) +{ + glUniform4fv(location, 1, value); +} + +inline +void shader_set_m2(uint32 location, const f32* value) +{ + glUniformMatrix2fv(location, 1, GL_FALSE, value); +} + +inline +void shader_set_m3(uint32 location, const f32* value) +{ + glUniformMatrix3fv(location, 1, GL_FALSE, value); +} + +inline +void shader_set_m4(uint32 location, const f32* value) +{ + glUniformMatrix4fv(location, 1, GL_FALSE, value); +} + inline uint32 shader_get_attrib_location(uint32 id, const char* name) { diff --git a/log/Debug.cpp b/log/Debug.cpp index efabe34..15506f8 100644 --- a/log/Debug.cpp +++ b/log/Debug.cpp @@ -6,6 +6,7 @@ #include "DebugMemory.h" #include "Log.h" #include "TimingStat.h" +#include "../utils/StringUtils.h" global_persist DebugContainer* debug_container = NULL; @@ -51,7 +52,7 @@ void log_counter(int32 id, int32 value) // @todo don't use a pointer to this should be in a global together with other logging data (see Log.h) inline -DebugMemory* debug_memory_find(uint64 start, uint64 size) +DebugMemory* debug_memory_find(uint64 start) { for (int32 i = 0; i < debug_container->dmc.memory_size; ++i) { if (debug_container->dmc.memory_stats[i].start <= start @@ -70,7 +71,7 @@ void debug_memory_init(uint64 start, uint64 size) return; } - const DebugMemory* mem = debug_memory_find(start, size); + const DebugMemory* mem = debug_memory_find(start); if (mem) { return; } @@ -94,13 +95,13 @@ void debug_memory_init(uint64 start, uint64 size) ++debug_container->dmc.memory_element_idx; } -void debug_memory_write(uint64 start, uint64 size, const char* function) +void debug_memory_log(uint64 start, uint64 size, int32 type, const char* function) { if (!start || !debug_container) { return; } - DebugMemory* mem = debug_memory_find(start, size); + DebugMemory* mem = debug_memory_find(start); if (!mem) { return; } @@ -109,7 +110,7 @@ void debug_memory_write(uint64 start, uint64 size, const char* function) mem->action_idx = 0; } - mem->last_action[mem->action_idx].type = 1; + mem->last_action[mem->action_idx].type = type; mem->last_action[mem->action_idx].start = start - mem->start; mem->last_action[mem->action_idx].size = size; @@ -118,60 +119,33 @@ void debug_memory_write(uint64 start, uint64 size, const char* function) mem->last_action[mem->action_idx].function_name = function; ++mem->action_idx; - mem->usage += size; + mem->usage += size * type; } -void debug_memory_read(uint64 start, uint64 size, const char* function) +void debug_memory_reserve(uint64 start, uint64 size, int32 type, const char* function) { if (!start || !debug_container) { return; } - DebugMemory* mem = debug_memory_find(start, size); + DebugMemory* mem = debug_memory_find(start); if (!mem) { return; } - if (mem->action_idx == DEBUG_MEMORY_RANGE_MAX) { - mem->action_idx = 0; + if (mem->reserve_action_idx == DEBUG_MEMORY_RANGE_MAX) { + mem->reserve_action_idx = 0; } - mem->last_action[mem->action_idx].type = 0; - mem->last_action[mem->action_idx].start = start - mem->start; - mem->last_action[mem->action_idx].size = size; + mem->reserve_action[mem->reserve_action_idx].type = type; + mem->reserve_action[mem->reserve_action_idx].start = start - mem->start; + mem->reserve_action[mem->reserve_action_idx].size = size; // @question consider to use other time_ms() since __rdtsc is variable (boost, power saving) - mem->last_action[mem->action_idx].time = __rdtsc(); - mem->last_action[mem->action_idx].function_name = function; + mem->reserve_action[mem->reserve_action_idx].time = __rdtsc(); + mem->reserve_action[mem->reserve_action_idx].function_name = function; - ++mem->action_idx; -} - -void debug_memory_delete(uint64 start, uint64 size, const char* function) -{ - if (!debug_container) { - return; - } - - DebugMemory* mem = debug_memory_find(start, size); - if (!mem) { - return; - } - - if (mem->action_idx == DEBUG_MEMORY_RANGE_MAX) { - mem->action_idx = 0; - } - - mem->last_action[mem->action_idx].type = -1; - mem->last_action[mem->action_idx].start = start - mem->start; - mem->last_action[mem->action_idx].size = size; - - // @question consider to use other time_ms() since __rdtsc is variable (boost, power saving) - mem->last_action[mem->action_idx].time = __rdtsc(); - mem->last_action[mem->action_idx].function_name = function; - - ++mem->action_idx; - mem->usage -= size; + ++mem->reserve_action_idx; } inline @@ -252,11 +226,29 @@ byte* log_get_memory(uint64 size, byte aligned = 1, bool zeroed = false) return; } - size_t length = strlen(str); - ASSERT_SIMPLE(length < MAX_LOG_LENGTH); + size_t str_len = strlen(str); + size_t file_len = strlen(file); + size_t function_len = strlen(function); - char* temp = (char *) log_get_memory(length + 1); - memcpy(temp, str, length + 1); + char line_str[10]; + int_to_str(line, line_str, '\0'); + + size_t line_len = strlen(line_str); + + ASSERT_SIMPLE(str_len + file_len + function_len + line_len + 3 < MAX_LOG_LENGTH); + + char* temp = (char *) log_get_memory(str_len + file_len + function_len + line_len + 3 + 1); + memcpy(temp, file, file_len); + temp[file_len] = ';'; + + memcpy(&temp[file_len], function, function_len); + temp[file_len + 1 + function_len] = ';'; + + memcpy(&temp[file_len + 1 + function_len], line_str, line_len); + temp[file_len + 1 + function_len + 1 + line_len] = ';'; + + memcpy(&temp[file_len + 1 + function_len + 1 + line_len + 1], str, str_len); + temp[file_len + 1 + function_len + 1 + line_len + 1 + str_len] = '\0'; if (save || debug_container->log_memory.size - debug_container->log_memory.pos < MAX_LOG_LENGTH) { log_to_file(); diff --git a/log/DebugMemory.h b/log/DebugMemory.h index ebcb0c0..f208af3 100644 --- a/log/DebugMemory.h +++ b/log/DebugMemory.h @@ -21,7 +21,8 @@ #include #endif -#define DEBUG_MEMORY_RANGE_MAX 1000 +#define DEBUG_MEMORY_RANGE_MAX 500 +#define DEBUG_MEMORY_RANGE_RES_MAX 100 struct DebugMemoryRange { int32 type; @@ -39,6 +40,9 @@ struct DebugMemory { uint64 action_idx; DebugMemoryRange last_action[DEBUG_MEMORY_RANGE_MAX]; + + uint64 reserve_action_idx; + DebugMemoryRange reserve_action[DEBUG_MEMORY_RANGE_RES_MAX]; }; struct DebugMemoryContainer { @@ -49,21 +53,22 @@ 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_log(uint64, uint64, int32, const char*); + void debug_memory_reserve(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__) - #define DEBUG_MEMORY_DELETE(start, size) debug_memory_delete((start), (size), __func__) + #define DEBUG_MEMORY_READ(start, size) debug_memory_log((start), (size), 0, __func__) + #define DEBUG_MEMORY_WRITE(start, size) debug_memory_log((start), (size), 1, __func__) + #define DEBUG_MEMORY_DELETE(start, size) debug_memory_log((start), (size), -1, __func__) + #define DEBUG_MEMORY_RESERVE(start, size, type) debug_memory_reserve((start), (size), (type), __func__) #define DEBUG_MEMORY_RESET() debug_memory_reset() #else #define DEBUG_MEMORY_INIT(start, size) ((void) 0) #define DEBUG_MEMORY_READ(start, size) ((void) 0) #define DEBUG_MEMORY_WRITE(start, size) ((void) 0) #define DEBUG_MEMORY_DELETE(start, size) ((void) 0) + #define DEBUG_MEMORY_RESERVE(start, size, type) ((void) 0) #define DEBUG_MEMORY_RESET() ((void) 0) #endif diff --git a/log/Log.h b/log/Log.h index 3710c48..15617af 100644 --- a/log/Log.h +++ b/log/Log.h @@ -40,6 +40,7 @@ enum LogDataType { LOG_DATA_FLOAT32, LOG_DATA_FLOAT64 }; + struct LogMemory { byte* memory; diff --git a/memory/BufferMemory.h b/memory/BufferMemory.h index 0643d9a..2b3c787 100644 --- a/memory/BufferMemory.h +++ b/memory/BufferMemory.h @@ -31,6 +31,8 @@ struct BufferMemory { inline void buffer_alloc(BufferMemory* buf, uint64 size, int32 alignment = 64) { + ASSERT_SIMPLE(size); + buf->memory = alignment < 2 ? (byte *) playform_alloc(size) : (byte *) playform_alloc_aligned(size, alignment); @@ -58,6 +60,8 @@ void buffer_free(BufferMemory* buf) inline void buffer_init(BufferMemory* buf, byte* data, uint64 size, int32 alignment = 64) { + ASSERT_SIMPLE(size); + // @bug what if an alignment is defined? buf->memory = data; @@ -67,6 +71,7 @@ void buffer_init(BufferMemory* buf, byte* data, uint64 size, int32 alignment = 6 buf->element_alignment = 0; DEBUG_MEMORY_INIT((uint64) buf->memory, buf->size); + DEBUG_MEMORY_RESERVE((uint64) buf->memory, buf->size, 187); } inline diff --git a/memory/ChunkMemory.h b/memory/ChunkMemory.h index 0eb74a7..140d71a 100644 --- a/memory/ChunkMemory.h +++ b/memory/ChunkMemory.h @@ -33,6 +33,9 @@ struct ChunkMemory { inline void chunk_alloc(ChunkMemory* buf, uint64 count, uint64 chunk_size, int32 alignment = 64) { + ASSERT_SIMPLE(chunk_size); + ASSERT_SIMPLE(count); + buf->memory = alignment < 2 ? (byte *) playform_alloc(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64)) : (byte *) playform_alloc_aligned(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64), alignment); @@ -63,13 +66,16 @@ void chunk_free(ChunkMemory* buf) } inline -void chunk_init(ChunkMemory* buf, byte* data, uint64 count, uint64 chunk_size, int32 alignment = 64) +void chunk_init(ChunkMemory* buf, BufferMemory* data, uint64 count, uint64 chunk_size, int32 alignment = 64) { + ASSERT_SIMPLE(chunk_size); + ASSERT_SIMPLE(count); + // @bug what if an alignment is defined? - buf->memory = data; + buf->memory = buffer_get_memory(data, count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64)); buf->count = count; - buf->size = chunk_size * count + sizeof(buf->free) * CEIL_DIV(count, 64); + buf->size = count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64); buf->chunk_size = chunk_size; buf->last_pos = -1; buf->alignment = alignment; @@ -80,6 +86,31 @@ void chunk_init(ChunkMemory* buf, byte* data, uint64 count, uint64 chunk_size, i buf->free = (uint64 *) (buf->memory + count * chunk_size); DEBUG_MEMORY_INIT((uint64) buf->memory, buf->size); + DEBUG_MEMORY_RESERVE((uint64) buf->memory, buf->size, 187); +} + +inline +void chunk_init(ChunkMemory* buf, byte* data, uint64 count, uint64 chunk_size, int32 alignment = 64) +{ + ASSERT_SIMPLE(chunk_size); + ASSERT_SIMPLE(count); + + // @bug what if an alignment is defined? + buf->memory = data; + + buf->count = count; + buf->size = count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64); + buf->chunk_size = chunk_size; + buf->last_pos = -1; + buf->alignment = alignment; + + // @question Could it be beneficial to have this before the element data? + // On the other hand the way we do it right now we never have to move past the free array since it is at the end + // On another hand we could by accident overwrite the values in free if we are not careful + buf->free = (uint64 *) (buf->memory + count * chunk_size); + + DEBUG_MEMORY_INIT((uint64) buf->memory, buf->size); + DEBUG_MEMORY_RESERVE((uint64) buf->memory, buf->size, 187); } inline diff --git a/memory/RingMemory.h b/memory/RingMemory.h index 804d07f..66f92f6 100644 --- a/memory/RingMemory.h +++ b/memory/RingMemory.h @@ -43,6 +43,8 @@ struct RingMemory { inline void ring_alloc(RingMemory* ring, uint64 size, int32 alignment = 64) { + ASSERT_SIMPLE(size); + ring->memory = alignment < 2 ? (byte *) playform_alloc(size) : (byte *) playform_alloc_aligned(size, alignment); @@ -62,6 +64,8 @@ void ring_alloc(RingMemory* ring, uint64 size, int32 alignment = 64) inline void ring_init(RingMemory* ring, BufferMemory* buf, uint64 size, int32 alignment = 64) { + ASSERT_SIMPLE(size); + ring->memory = buffer_get_memory(buf, size, alignment, true); ring->size = size; @@ -72,11 +76,14 @@ void ring_init(RingMemory* ring, BufferMemory* buf, uint64 size, int32 alignment ring->end = 0; DEBUG_MEMORY_INIT((uint64) ring->memory, ring->size); + DEBUG_MEMORY_RESERVE((uint64) ring->memory, ring->size, 187); } inline void ring_init(RingMemory* ring, byte* buf, uint64 size, int32 alignment = 64) { + ASSERT_SIMPLE(size); + // @bug what if an alignment is defined? ring->memory = buf; @@ -90,6 +97,7 @@ void ring_init(RingMemory* ring, byte* buf, uint64 size, int32 alignment = 64) memset(ring->memory, 0, ring->size); DEBUG_MEMORY_INIT((uint64) ring->memory, ring->size); + DEBUG_MEMORY_RESERVE((uint64) ring->memory, ring->size, 187); } inline diff --git a/models/settings/Settings.h b/models/settings/Settings.h index 90c47fb..4c9082e 100644 --- a/models/settings/Settings.h +++ b/models/settings/Settings.h @@ -69,11 +69,11 @@ struct SSettings { byte distance_npc = RENDER_NPC_CHUNK_RADIUS; byte distance_player = RENDER_PAYER_CHUNK_RADIUS; - uint32 player_cache = 8192; // = max active players on a server - uint32 monster_cache = 8192; - uint32 npc_cache = 8192; - uint32 guild_cache = 128; - uint32 message_cache = 1024; + uint32 cache_player = 8192; // = max active players on a server + uint32 cache_monster = 8192; + uint32 cache_npc = 8192; + uint32 cache_guild = 128; + uint32 cache_message = 1024; uint32 interpolation_buffer; @@ -97,30 +97,31 @@ struct PSettings { }; struct CSettings { + // Evaluated during startup char path[MAX_PATH]; bool is_changed = false; byte simd_version; + bool supports_abm; + // Network data char network_hostname[64]; uint16 network_port; byte gpu_api = SETTING_TYPE_GPU_API_NONE; byte gpu_type = SETTING_TYPE_GPU_MEDIUM; byte gpu_fps = SETTING_TYPE_UNLIMITED; - byte gpu_memory = 4; // how much vram are we using on the gpu + byte gpu_memory; // how much vram are we using on the gpu + byte system_ram; // how much ram are we using + byte system_threads; // how much ram are we using + byte system_cache; // how much hard drive cache do we want to allow? (oldest files will be deleted) - byte gpu_aspect_ratio; - byte gpu_resolution; + f32 gpu_aspect_ratio; byte gpu_brightness; byte gpu_contrast; byte gpu_gamma; - byte gpu_fov; + f32 gpu_fov; byte gpu_sync = SETTING_TYPE_DISABLED; - uint32 gpu_number_of_npc_characters = 128; - uint32 gpu_number_of_player_characters = 512; - uint32 gpu_number_of_monster_characters = 128; - byte gpu_render_distance_terrain = 10; byte gpu_render_distance_terrain_secondary = 10; byte gpu_render_distance_terrain_tertiary = 1; @@ -129,6 +130,8 @@ struct CSettings { byte gpu_render_distance_npc = 3; byte gpu_render_distance_player = 3; + int32 gpu_render_count_mob = 1000; + uint32 player_cache = 512; uint32 monster_cache = 128; uint32 npc_cache = 128; @@ -181,7 +184,6 @@ struct CSettings { bool gpu_chromatic_aberration = true; bool gpu_vignetting = true; bool gpu_light_shafts = true; - bool gpu_camera_shake = false; byte audio_volume_master = 128; byte audio_volume_game = 128; @@ -189,28 +191,16 @@ struct CSettings { byte audio_volume_music = 128; byte audio_volume_speech = 128; - uint16 game_window1_dim[2] = {1024, 768}; + uint16 game_window1_dim[2]; uint16 game_window1_pos[2]; byte game_window1_mode = SETTING_TYPE_WINDOW_MODE_FULLSCREEN; - byte game_zoom; byte game_view = SETTING_TYPE_PERSPECTIVE_FIRST; + byte game_camera_zoom; + bool game_camera_shake = false; // General game UI - bool game_crosshair = false; - - bool game_healthbar_self = false; - bool game_healthbar_group = false; - bool game_healthbar_players = false; - bool game_healthbar_npc = false; - bool game_healthbar_monsters = false; - - bool game_name_monsters = false; - bool game_name_npc = false; - bool game_name_mobs = false; - - bool game_show_auras = true; - bool game_show_helmets = true; + byte game_crosshair; uint32 game_interpolation_buffer; @@ -246,60 +236,18 @@ struct CSettings { // Themes char game_language[2]; - char game_ui_theme[32]; - byte game_ui_size = 128; + char game_theme[32]; - uint32 game_item_icon_theme = 1; - - uint32 game_menu_theme = 1; - byte game_menu_size = 128; - - uint32 game_map_mini_theme = 1; - byte game_map_mini_size = 128; - int32 game_map_mini_pos[2] = { -1, -1 }; - - uint32 game_quest_theme = 1; - byte game_quest_size = 128; - int32 game_quest_pos[2] = { -1, -1 }; - - uint32 game_skill_bar_theme = 1; - bool game_skill_bar_animated = false; - byte game_skill_bar_size = 128; - int32 game_skill_bar_pos[2] = { -1, -1 }; - - uint32 game_health_theme = 1; - bool game_health_animated = false; - byte game_health_size = 128; - int32 game_health_pos[2] = { -1, -1 }; - - uint32 game_resource_theme = 1; - bool game_resource_animated = false; - byte game_resource_size = 128; - int32 game_resource_pos[2] = { -1, -1 }; - - uint32 game_party_theme = 1; - bool game_party_animated = false; - byte game_party_size = 128; - int32 game_party_pos[2] = { -1, -1 }; - - uint32 game_enemy_theme = 1; - bool game_enemy_animated = false; - byte game_enemy_size = 128; - int32 game_enemy_pos[2] = { -1, -1 }; - - uint32 game_select_info_theme = 1; - byte game_select_info_size = 128; - int32 game_select_info_pos[2] = { -1, -1 }; - - uint32 game_chat_theme = 1; - byte game_chat_size = 128; - int32 game_chat_pos[2] = { -1, -1 }; + v4_f32* game_ui_dim[50]; // @todo replace settings below with bit flag // UI uint64 ui_visibility_flags = 0; // HUD + bool game_hud_animated; + bool game_ui_show_hotkeys; + bool game_show_health_bar_self = false; bool game_show_health_bar_player = false; bool game_show_health_bar_monster = false; @@ -341,7 +289,6 @@ struct CSettings { // Game behavior bool game_error_audio = true; bool game_error_text = true; - byte game_default_zoom = 128; bool game_block_trade = false; bool game_block_group_invite = false; bool game_block_guild_invite = false; @@ -349,7 +296,6 @@ struct CSettings { bool game_block_friend_invite = false; bool game_automatically_track_newest_quest = false; - byte game_interact_direction = 0; byte game_interact_radius = 1; // Game pad settings @@ -358,10 +304,9 @@ struct CSettings { byte stick_left_deadzone = 0; byte stick_right_deadzone = 0; - byte input_look_speed = 0; + f32 input_camera_speed; + f32 input_look_sensitivity; bool input_invert_mouse = false; - bool input_lock_cursor_to_window = true; - bool input_click_to_move = true; int32 active_module_count; Module* active_modules; @@ -409,20 +354,21 @@ struct CSettings { byte hotkeys_skills = 0x53; // S byte hotkeys_map = 0x4D; // M byte hotkeys_quest = 0x51; // Q - byte hotkeys_teleport = 0x54; // T byte hotkeys_attack_move = 0x52; // R byte hotkeys_force_move = 0x46; // F byte hotkeys_courser_move = 0x58; // X (move to where courser is) byte hotkeys_chat = 0x0D; // ENTER - byte hotkeys_hide_ui = 0x48; // H + byte hotkeys_toggle_hud = 0x48; // H + byte hotkeys_close_active_window = 0x48; // H + byte hotkeys_toggle_all_windows = 0x48; // H - byte hotkey_zoom_in = 0x21; // Page up (@todo make mouse scroll up) - byte hotkey_zoom_out = 0x22; // page down (@todo make mouse scroll down) - byte hotkey_camera_look = 0x00; // @todo make right mouse hold + byte hotkeys_zoom_in = 0x21; // Page up (@todo make mouse scroll up) + byte hotkeys_zoom_out = 0x22; // page down (@todo make mouse scroll down) + byte hotkeys_camera_look = 0x00; // @todo make right mouse hold + byte hotkeys_camera_fly_mode = 0x00; // @todo make right mouse hold byte hotkeys_menu = 0x1B; // ESC - byte hotkeys_window_close = 0x1B; // ESC byte hotkeys_marker_1 = 0x31; byte hotkeys_marker_2 = 0x32; @@ -438,9 +384,336 @@ struct CSettings { byte hotkeys_camera_2 = 0x0; byte hotkeys_camera_3 = 0x0; - // @todo implement the actual camera settings - char modules[MAX_ACTIVE_EXTENSIONS * 32]; }; +void load_settings(CSettings* __restrict client_settings, char* data) +{ + char* pos = data; + char* name; + + while (*pos != '\0') { + // Skip all whitespaces and new lines + int32 skip; + while ((skip = is_eol(pos)) || (skip = (int32) is_whitespace(*pos))) { + pos += skip; + } + + // Skip comment + if (*pos == '/' && pos[1] == '/') { + while (*pos != '\n' && *pos != '\0') { + ++pos; + } + + continue; + } + + // Get name + name = pos; + while (!is_eol(pos) && *pos != '\0' && !is_whitespace(*pos)) { + ++pos; + } + + // Move to value + while (is_whitespace(*pos)) { + ++pos; + } + + // Is there a value? + if (is_eol(pos) || *pos == '\0') { + continue; + } + + // Parse value + // We use grouping for faster handling + if (strncmp(name, "gpu", sizeof("gpu") - 1) == 0) { + name += sizeof("gpu") - 1; + + if (strncmp(name, "_ambient_occlusion", sizeof("_ambient_occlusion") - 1) == 0) { + } else if (strncmp(name, "_animation_quality", sizeof("_animation_quality") - 1) == 0) { + } else if (strncmp(name, "_anti_aliasing_detail", sizeof("_anti_aliasing_detail") - 1) == 0) { + } else if (strncmp(name, "_anti_aliasing", sizeof("_anti_aliasing") - 1) == 0) { + } else if (strncmp(name, "_api", sizeof("_api") - 1) == 0) { + } else if (strncmp(name, "_aspect_ratio", sizeof("_aspect_ratio") - 1) == 0) { + client_settings->gpu_aspect_ratio = (f32) atof(pos); + } else if (strncmp(name, "_attack_effect_quality", sizeof("_attack_effect_quality") - 1) == 0) { + } else if (strncmp(name, "_blur", sizeof("_blur") - 1) == 0) { + } else if (strncmp(name, "_brightness", sizeof("_brightness") - 1) == 0) { + } else if (strncmp(name, "_camera_shake", sizeof("_camera_shake") - 1) == 0) { + } else if (strncmp(name, "_caustics_quality", sizeof("_caustics_quality") - 1) == 0) { + } else if (strncmp(name, "_chromatic_aberration", sizeof("_chromatic_aberration") - 1) == 0) { + } else if (strncmp(name, "_contrast", sizeof("_contrast") - 1) == 0) { + } else if (strncmp(name, "_depth_of_field", sizeof("_depth_of_field") - 1) == 0) { + } else if (strncmp(name, "_detail_level", sizeof("_detail_level") - 1) == 0) { + } else if (strncmp(name, "_fog_effect", sizeof("_fog_effect") - 1) == 0) { + } else if (strncmp(name, "_foliage_distance", sizeof("_foliage_distance") - 1) == 0) { + } else if (strncmp(name, "_footprint_quality", sizeof("_footprint_quality") - 1) == 0) { + } else if (strncmp(name, "_fov", sizeof("_fov") - 1) == 0) { + client_settings->gpu_fov = (f32) atof(pos); + } else if (strncmp(name, "_fps", sizeof("_fps") - 1) == 0) { + } else if (strncmp(name, "_gamma_correction", sizeof("_gamma_correction") - 1) == 0) { + } else if (strncmp(name, "_gamma", sizeof("_gamma") - 1) == 0) { + } else if (strncmp(name, "_grass_density", sizeof("_grass_density") - 1) == 0) { + } else if (strncmp(name, "_lense_effect", sizeof("_lense_effect") - 1) == 0) { + } else if (strncmp(name, "_light_bloom", sizeof("_light_bloom") - 1) == 0) { + } else if (strncmp(name, "_light_shafts", sizeof("_light_shafts") - 1) == 0) { + } else if (strncmp(name, "_light_ssao", sizeof("_light_ssao") - 1) == 0) { + } else if (strncmp(name, "_memory", sizeof("_memory") - 1) == 0) { + } else if (strncmp(name, "_model_quality", sizeof("_model_quality") - 1) == 0) { + } else if (strncmp(name, "_motion_blur", sizeof("_motion_blur") - 1) == 0) { + } else if (strncmp(name, "_normal_mapping", sizeof("_normal_mapping") - 1) == 0) { + } else if (strncmp(name, "_parallax_mapping", sizeof("_parallax_mapping") - 1) == 0) { + } else if (strncmp(name, "_particles_environment", sizeof("_particles_environment") - 1) == 0) { + } else if (strncmp(name, "_particles_monster", sizeof("_particles_monster") - 1) == 0) { + } else if (strncmp(name, "_particles_players", sizeof("_particles_players") - 1) == 0) { + } else if (strncmp(name, "_particles_skills", sizeof("_particles_skills") - 1) == 0) { + } else if (strncmp(name, "_particles_ui", sizeof("_particles_ui") - 1) == 0) { + } else if (strncmp(name, "_particles_weapons", sizeof("_particles_weapons") - 1) == 0) { + } else if (strncmp(name, "_raytracing", sizeof("_raytracing") - 1) == 0) { + } else if (strncmp(name, "_reflection_blur", sizeof("_reflection_blur") - 1) == 0) { + } else if (strncmp(name, "_reflection_quality", sizeof("_reflection_quality") - 1) == 0) { + } else if (strncmp(name, "_refraction_quality", sizeof("_refraction_quality") - 1) == 0) { + } else if (strncmp(name, "_render_count_mob", sizeof("_render_count_mob") - 1) == 0) { + } else if (strncmp(name, "_render_distance_models", sizeof("_render_distance_models") - 1) == 0) { + } else if (strncmp(name, "_render_distance_monster", sizeof("_render_distance_monster") - 1) == 0) { + } else if (strncmp(name, "_render_distance_npc", sizeof("_render_distance_npc") - 1) == 0) { + } else if (strncmp(name, "_render_distance_player", sizeof("_render_distance_player") - 1) == 0) { + } else if (strncmp(name, "_render_distance_terrain_secondary", sizeof("_render_distance_terrain_secondary") - 1) == 0) { + } else if (strncmp(name, "_render_distance_terrain_tertiary", sizeof("_render_distance_terrain_tertiary") - 1) == 0) { + } else if (strncmp(name, "_render_distance_terrain", sizeof("_render_distance_terrain") - 1) == 0) { + } else if (strncmp(name, "_screen_effects", sizeof("_screen_effects") - 1) == 0) { + } else if (strncmp(name, "_shadow_quality", sizeof("_shadow_quality") - 1) == 0) { + } else if (strncmp(name, "_shadow_type", sizeof("_shadow_type") - 1) == 0) { + } else if (strncmp(name, "_sharpening", sizeof("_sharpening") - 1) == 0) { + } else if (strncmp(name, "_sync", sizeof("_sync") - 1) == 0) { + } else if (strncmp(name, "_terrain_quality", sizeof("_terrain_quality") - 1) == 0) { + } else if (strncmp(name, "_texture_quality", sizeof("_texture_quality") - 1) == 0) { + } else if (strncmp(name, "_type", sizeof("_type") - 1) == 0) { + } else if (strncmp(name, "_vignetting", sizeof("_vignetting") - 1) == 0) { + } else if (strncmp(name, "_water_quality", sizeof("_water_quality") - 1) == 0) { + } + } else if (strncmp(name, "game", sizeof("game") - 1) == 0) { + name += sizeof("game") - 1; + + if (strncmp(name, "_automatically_track_newest_quest", sizeof("_automatically_track_newest_quest") - 1) == 0) { + } else if (strncmp(name, "_block_chat_invite", sizeof("_block_chat_invite") - 1) == 0) { + } else if (strncmp(name, "_block_friend_invite", sizeof("_block_friend_invite") - 1) == 0) { + } else if (strncmp(name, "_block_group_invite", sizeof("_block_group_invite") - 1) == 0) { + } else if (strncmp(name, "_block_guild_invite", sizeof("_block_guild_invite") - 1) == 0) { + } else if (strncmp(name, "_block_trade", sizeof("_block_trade") - 1) == 0) { + } else if (strncmp(name, "_camera_shake", sizeof("_camera_shake") - 1) == 0) { + } else if (strncmp(name, "_camera_zoom", sizeof("_camera_zoom") - 1) == 0) { + } else if (strncmp(name, "_chat_status", sizeof("_chat_status") - 1) == 0) { + } else if (strncmp(name, "_crosshair", sizeof("_crosshair") - 1) == 0) { + } else if (strncmp(name, "_default_mount", sizeof("_default_mount") - 1) == 0) { + } else if (strncmp(name, "_hud_animated", sizeof("_hud_animated") - 1) == 0) { + } else if (strncmp(name, "_interact_radius", sizeof("_interact_radius") - 1) == 0) { + } else if (strncmp(name, "_language", sizeof("_language") - 1) == 0) { + } else if (strncmp(name, "_map_show_dungeons", sizeof("_map_show_dungeons") - 1) == 0) { + } else if (strncmp(name, "_map_show_merchants", sizeof("_map_show_merchants") - 1) == 0) { + } else if (strncmp(name, "_map_show_names", sizeof("_map_show_names") - 1) == 0) { + } else if (strncmp(name, "_map_show_quest", sizeof("_map_show_quest") - 1) == 0) { + } else if (strncmp(name, "_minimap_show_dungeons", sizeof("_minimap_show_dungeons") - 1) == 0) { + } else if (strncmp(name, "_minimap_show_merchants", sizeof("_minimap_show_merchants") - 1) == 0) { + } else if (strncmp(name, "_minimap_show_names", sizeof("_minimap_show_names") - 1) == 0) { + } else if (strncmp(name, "_minimap_show_quest", sizeof("_minimap_show_quest") - 1) == 0) { + } else if (strncmp(name, "_minion_visibility_player", sizeof("_minion_visibility_player") - 1) == 0) { + } else if (strncmp(name, "_minion_visibility_self", sizeof("_minion_visibility_self") - 1) == 0) { + } else if (strncmp(name, "_player_chat", sizeof("_player_chat") - 1) == 0) { + } else if (strncmp(name, "_show_buffs", sizeof("_show_buffs") - 1) == 0) { + } else if (strncmp(name, "_show_cooldown_times", sizeof("_show_cooldown_times") - 1) == 0) { + } else if (strncmp(name, "_show_dmg_numbers", sizeof("_show_dmg_numbers") - 1) == 0) { + } else if (strncmp(name, "_show_dodge", sizeof("_show_dodge") - 1) == 0) { + } else if (strncmp(name, "_show_effect_gains", sizeof("_show_effect_gains") - 1) == 0) { + } else if (strncmp(name, "_show_health_bar_monster", sizeof("_show_health_bar_monster") - 1) == 0) { + } else if (strncmp(name, "_show_health_bar_player", sizeof("_show_health_bar_player") - 1) == 0) { + } else if (strncmp(name, "_show_health_bar_self", sizeof("_show_health_bar_self") - 1) == 0) { + } else if (strncmp(name, "_show_health_numbers", sizeof("_show_health_numbers") - 1) == 0) { + } else if (strncmp(name, "_show_name_monster", sizeof("_show_name_monster") - 1) == 0) { + } else if (strncmp(name, "_show_name_npc", sizeof("_show_name_npc") - 1) == 0) { + } else if (strncmp(name, "_show_name_player", sizeof("_show_name_player") - 1) == 0) { + } else if (strncmp(name, "_show_name_self", sizeof("_show_name_self") - 1) == 0) { + } else if (strncmp(name, "_show_resource_numbers", sizeof("_show_resource_numbers") - 1) == 0) { + } else if (strncmp(name, "_show_subtitles", sizeof("_show_subtitles") - 1) == 0) { + } else if (strncmp(name, "_show_title_other", sizeof("_show_title_other") - 1) == 0) { + } else if (strncmp(name, "_show_title_self", sizeof("_show_title_self") - 1) == 0) { + } else if (strncmp(name, "_show_xp_bar_numbers", sizeof("_show_xp_bar_numbers") - 1) == 0) { + } else if (strncmp(name, "_theme", sizeof("_theme") - 1) == 0) { + } else if (strncmp(name, "_ui_dim", sizeof("_ui_dim") - 1) == 0) { + } else if (strncmp(name, "_ui_show_hotkeys", sizeof("_ui_show_hotkeys") - 1) == 0) { + } else if (strncmp(name, "_view", sizeof("_view") - 1) == 0) { + } else if (strncmp(name, "_window1_dim", sizeof("_window1_dim") - 1) == 0) { + client_settings->game_window1_dim[0] = (uint16) strtoul(pos, &pos, 10); ++pos; + client_settings->game_window1_dim[1] = (uint16) atoi(pos); + } else if (strncmp(name, "_window1_pos", sizeof("_window1_pos") - 1) == 0) { + } else if (strncmp(name, "_window2_dim", sizeof("_window2_dim") - 1) == 0) { + } else if (strncmp(name, "_window2_pos", sizeof("_window2_pos") - 1) == 0) { + } else if (strncmp(name, "_window3_dim", sizeof("_window3_dim") - 1) == 0) { + } else if (strncmp(name, "_window3_pos", sizeof("_window3_pos") - 1) == 0) { + } else if (strncmp(name, "_window4_dim", sizeof("_window4_dim") - 1) == 0) { + } else if (strncmp(name, "_window4_pos", sizeof("_window4_pos") - 1) == 0) { + } else if (strncmp(name, "_window5_dim", sizeof("_window5_dim") - 1) == 0) { + } else if (strncmp(name, "_window5_pos", sizeof("_window5_pos") - 1) == 0) { + } + } else if (strncmp(name, "hotkeys", sizeof("hotkeys") - 1) == 0) { + name += sizeof("hotkeys") - 1; + + if (strncmp(name, "_camera_fly_mode", sizeof("_camera_fly_mode") - 1) == 0) { + } else if (strncmp(name, "_camera_look", sizeof("_camera_look") - 1) == 0) { + } else if (strncmp(name, "_zoom_in", sizeof("_zoom_in") - 1) == 0) { + } else if (strncmp(name, "_zoom_out", sizeof("_zoom_out") - 1) == 0) { + } else if (strncmp(name, "_attack_move", sizeof("_attack_move") - 1) == 0) { + } else if (strncmp(name, "_auction_house", sizeof("_auction_house") - 1) == 0) { + } else if (strncmp(name, "_bar_active_1", sizeof("_bar_active_1") - 1) == 0) { + } else if (strncmp(name, "_bar_active_2", sizeof("_bar_active_2") - 1) == 0) { + } else if (strncmp(name, "_bar_active_3", sizeof("_bar_active_3") - 1) == 0) { + } else if (strncmp(name, "_bar_active_4", sizeof("_bar_active_4") - 1) == 0) { + } else if (strncmp(name, "_bar_active_5", sizeof("_bar_active_5") - 1) == 0) { + } else if (strncmp(name, "_bar_global_1", sizeof("_bar_global_1") - 1) == 0) { + } else if (strncmp(name, "_bar_global_10", sizeof("_bar_global_10") - 1) == 0) { + } else if (strncmp(name, "_bar_global_11", sizeof("_bar_global_11") - 1) == 0) { + } else if (strncmp(name, "_bar_global_12", sizeof("_bar_global_12") - 1) == 0) { + } else if (strncmp(name, "_bar_global_13", sizeof("_bar_global_13") - 1) == 0) { + } else if (strncmp(name, "_bar_global_14", sizeof("_bar_global_14") - 1) == 0) { + } else if (strncmp(name, "_bar_global_15", sizeof("_bar_global_15") - 1) == 0) { + } else if (strncmp(name, "_bar_global_16", sizeof("_bar_global_16") - 1) == 0) { + } else if (strncmp(name, "_bar_global_17", sizeof("_bar_global_17") - 1) == 0) { + } else if (strncmp(name, "_bar_global_18", sizeof("_bar_global_18") - 1) == 0) { + } else if (strncmp(name, "_bar_global_19", sizeof("_bar_global_19") - 1) == 0) { + } else if (strncmp(name, "_bar_global_2", sizeof("_bar_global_2") - 1) == 0) { + } else if (strncmp(name, "_bar_global_20", sizeof("_bar_global_20") - 1) == 0) { + } else if (strncmp(name, "_bar_global_21", sizeof("_bar_global_21") - 1) == 0) { + } else if (strncmp(name, "_bar_global_22", sizeof("_bar_global_22") - 1) == 0) { + } else if (strncmp(name, "_bar_global_23", sizeof("_bar_global_23") - 1) == 0) { + } else if (strncmp(name, "_bar_global_24", sizeof("_bar_global_24") - 1) == 0) { + } else if (strncmp(name, "_bar_global_25", sizeof("_bar_global_25") - 1) == 0) { + } else if (strncmp(name, "_bar_global_3", sizeof("_bar_global_3") - 1) == 0) { + } else if (strncmp(name, "_bar_global_4", sizeof("_bar_global_4") - 1) == 0) { + } else if (strncmp(name, "_bar_global_5", sizeof("_bar_global_5") - 1) == 0) { + } else if (strncmp(name, "_bar_global_6", sizeof("_bar_global_6") - 1) == 0) { + } else if (strncmp(name, "_bar_global_7", sizeof("_bar_global_7") - 1) == 0) { + } else if (strncmp(name, "_bar_global_8", sizeof("_bar_global_8") - 1) == 0) { + } else if (strncmp(name, "_bar_global_9", sizeof("_bar_global_9") - 1) == 0) { + } else if (strncmp(name, "_bar_tab_1", sizeof("_bar_tab_1") - 1) == 0) { + } else if (strncmp(name, "_bar_tab_2", sizeof("_bar_tab_2") - 1) == 0) { + } else if (strncmp(name, "_bar_tab_3", sizeof("_bar_tab_3") - 1) == 0) { + } else if (strncmp(name, "_bar_tab_4", sizeof("_bar_tab_4") - 1) == 0) { + } else if (strncmp(name, "_bar_tab_5", sizeof("_bar_tab_5") - 1) == 0) { + } else if (strncmp(name, "_camera_1", sizeof("_camera_1") - 1) == 0) { + } else if (strncmp(name, "_camera_2", sizeof("_camera_2") - 1) == 0) { + } else if (strncmp(name, "_camera_3", sizeof("_camera_3") - 1) == 0) { + } else if (strncmp(name, "_cancel_action", sizeof("_cancel_action") - 1) == 0) { + } else if (strncmp(name, "_character", sizeof("_character") - 1) == 0) { + } else if (strncmp(name, "_chat_send", sizeof("_chat_send") - 1) == 0) { + } else if (strncmp(name, "_close_active_window", sizeof("_close_active_window") - 1) == 0) { + } else if (strncmp(name, "_compare_item", sizeof("_compare_item") - 1) == 0) { + } else if (strncmp(name, "_courser_move", sizeof("_courser_move") - 1) == 0) { + } else if (strncmp(name, "_crouch", sizeof("_crouch") - 1) == 0) { + } else if (strncmp(name, "_dodge", sizeof("_dodge") - 1) == 0) { + } else if (strncmp(name, "_element_down", sizeof("_element_down") - 1) == 0) { + } else if (strncmp(name, "_element_left", sizeof("_element_left") - 1) == 0) { + } else if (strncmp(name, "_element_next", sizeof("_element_next") - 1) == 0) { + } else if (strncmp(name, "_element_prev", sizeof("_element_prev") - 1) == 0) { + } else if (strncmp(name, "_element_right", sizeof("_element_right") - 1) == 0) { + } else if (strncmp(name, "_element_up", sizeof("_element_up") - 1) == 0) { + } else if (strncmp(name, "_emote", sizeof("_emote") - 1) == 0) { + } else if (strncmp(name, "_force_move", sizeof("_force_move") - 1) == 0) { + } else if (strncmp(name, "_guild", sizeof("_guild") - 1) == 0) { + } else if (strncmp(name, "_interact", sizeof("_interact") - 1) == 0) { + } else if (strncmp(name, "_inventory", sizeof("_inventory") - 1) == 0) { + } else if (strncmp(name, "_jump", sizeof("_jump") - 1) == 0) { + } else if (strncmp(name, "_map", sizeof("_map") - 1) == 0) { + } else if (strncmp(name, "_marker_1", sizeof("_marker_1") - 1) == 0) { + } else if (strncmp(name, "_marker_2", sizeof("_marker_2") - 1) == 0) { + } else if (strncmp(name, "_marker_3", sizeof("_marker_3") - 1) == 0) { + } else if (strncmp(name, "_marker_4", sizeof("_marker_4") - 1) == 0) { + } else if (strncmp(name, "_marker_5", sizeof("_marker_5") - 1) == 0) { + } else if (strncmp(name, "_marker_6", sizeof("_marker_6") - 1) == 0) { + } else if (strncmp(name, "_menu", sizeof("_menu") - 1) == 0) { + } else if (strncmp(name, "_movement_down", sizeof("_movement_down") - 1) == 0) { + } else if (strncmp(name, "_movement_left", sizeof("_movement_left") - 1) == 0) { + } else if (strncmp(name, "_movement_pitch_down", sizeof("_movement_pitch_down") - 1) == 0) { + } else if (strncmp(name, "_movement_pitch_up", sizeof("_movement_pitch_up") - 1) == 0) { + } else if (strncmp(name, "_movement_right", sizeof("_movement_right") - 1) == 0) { + } else if (strncmp(name, "_movement_roll_left", sizeof("_movement_roll_left") - 1) == 0) { + } else if (strncmp(name, "_movement_roll_right", sizeof("_movement_roll_right") - 1) == 0) { + } else if (strncmp(name, "_movement_up", sizeof("_movement_up") - 1) == 0) { + } else if (strncmp(name, "_movement_vertical_down", sizeof("_movement_vertical_down") - 1) == 0) { + } else if (strncmp(name, "_movement_vertical_up", sizeof("_movement_vertical_up") - 1) == 0) { + } else if (strncmp(name, "_movement_yaw_left", sizeof("_movement_yaw_left") - 1) == 0) { + } else if (strncmp(name, "_movement_yaw_right", sizeof("_movement_yaw_right") - 1) == 0) { + } else if (strncmp(name, "_ping", sizeof("_ping") - 1) == 0) { + } else if (strncmp(name, "_quest", sizeof("_quest") - 1) == 0) { + } else if (strncmp(name, "_skills", sizeof("_skills") - 1) == 0) { + } else if (strncmp(name, "_sneak", sizeof("_sneak") - 1) == 0) { + } else if (strncmp(name, "_toggle_all_windows", sizeof("_toggle_all_windows") - 1) == 0) { + } else if (strncmp(name, "_toggle_hud", sizeof("_toggle_hud") - 1) == 0) { + } else if (strncmp(name, "_view_next", sizeof("_view_next") - 1) == 0) { + } else if (strncmp(name, "_view_prv", sizeof("_view_prv") - 1) == 0) { + } else if (strncmp(name, "_walk", sizeof("_walk") - 1) == 0) { + } + } else if (strncmp(name, "input", sizeof("input") - 1) == 0) { + name += sizeof("input") - 1; + + if (strncmp(name, "_camera_speed", sizeof("_camera_speed") - 1) == 0) { + client_settings->input_camera_speed = (f32) atof(pos); + } else if (strncmp(name, "_controller1_gyro_x_deadzone", sizeof("_controller1_gyro_x_deadzone") - 1) == 0) { + } else if (strncmp(name, "_controller1_gyro_x_zero", sizeof("_controller1_gyro_x_zero") - 1) == 0) { + } else if (strncmp(name, "_controller1_gyro_y_deadzone", sizeof("_controller1_gyro_y_deadzone") - 1) == 0) { + } else if (strncmp(name, "_controller1_gyro_y_zero", sizeof("_controller1_gyro_y_zero") - 1) == 0) { + } else if (strncmp(name, "_controller1_gyro_z_deadzone", sizeof("_controller1_gyro_z_deadzone") - 1) == 0) { + } else if (strncmp(name, "_controller1_gyro_z_zero", sizeof("_controller1_gyro_z_zero") - 1) == 0) { + } else if (strncmp(name, "_controller1_stick_left_deadzone", sizeof("_controller1_stick_left_deadzone") - 1) == 0) { + } else if (strncmp(name, "_controller1_stick_right_deadzone", sizeof("_controller1_stick_right_deadzone") - 1) == 0) { + } else if (strncmp(name, "_controller1_trigger_left_deadzone", sizeof("_controller1_trigger_left_deadzone") - 1) == 0) { + } else if (strncmp(name, "_controller1_trigger_right_deadzone", sizeof("_controller1_trigger_right_deadzone") - 1) == 0) { + } else if (strncmp(name, "_device", sizeof("_device") - 1) == 0) { + } else if (strncmp(name, "_invert_mouse", sizeof("_invert_mouse") - 1) == 0) { + } else if (strncmp(name, "_look_sensitivity", sizeof("_look_sensitivity") - 1) == 0) { + client_settings->input_look_sensitivity = (f32) atof(pos); + } + } else if (strncmp(name, "cache", sizeof("cache") - 1) == 0) { + name += sizeof("cache") - 1; + + if (strncmp(name, "_chat", sizeof("_chat") - 1) == 0) { + } else if (strncmp(name, "_guild", sizeof("_guild") - 1) == 0) { + } else if (strncmp(name, "_log", sizeof("_log") - 1) == 0) { + } else if (strncmp(name, "_monster", sizeof("_monster") - 1) == 0) { + } else if (strncmp(name, "_npc", sizeof("_npc") - 1) == 0) { + } else if (strncmp(name, "_player", sizeof("_player") - 1) == 0) { + } + } else if (strncmp(name, "audio", sizeof("audio") - 1) == 0) { + name += sizeof("audio") - 1; + + if (strncmp(name, "_volume_environment", sizeof("_volume_environment") - 1) == 0) { + } else if (strncmp(name, "_volume_game", sizeof("_volume_game") - 1) == 0) { + } else if (strncmp(name, "_volume_master", sizeof("_volume_master") - 1) == 0) { + } else if (strncmp(name, "_volume_music", sizeof("_volume_music") - 1) == 0) { + } else if (strncmp(name, "_volume_speech", sizeof("_volume_speech") - 1) == 0) { + } + } else if (strncmp(name, "network", sizeof("network") - 1) == 0) { + name += sizeof("network") - 1; + + if (strncmp(name, "_hostname", sizeof("_hostname") - 1) == 0) { + } else if (strncmp(name, "_port", sizeof("_port") - 1) == 0) { + } + } else if (strncmp(name, "system", sizeof("system") - 1) == 0) { + name += sizeof("system") - 1; + + if (strncmp(name, "system_cache", sizeof("system_cache") - 1) == 0) { + } else if (strncmp(name, "system_memory", sizeof("system_memory") - 1) == 0) { + } else if (strncmp(name, "system_threads", sizeof("system_threads") - 1) == 0) { + } + } else { + if (strncmp(name, "extension_active", sizeof("extension_active") - 1) == 0) { + } + } + + // Go to end of line + while (*pos != '\n' && *pos != '\0') { + ++pos; + } + } +} + #endif \ No newline at end of file diff --git a/models/settings/setting_types.h b/models/settings/setting_types.h index 6601423..2f34caa 100644 --- a/models/settings/setting_types.h +++ b/models/settings/setting_types.h @@ -75,8 +75,9 @@ #define SETTING_TYPE_UNLIMITED 0x00 #define SETTING_UI_VISIBILITY_FPS 1 -#define SETTING_UI_VISIBILITY_DEBUG 2 -#define SETTING_UI_VISIBILITY_WIREFRAME 4 +#define SETTING_UI_VISIBILITY_APM 2 +#define SETTING_UI_VISIBILITY_DEBUG 4 +#define SETTING_UI_VISIBILITY_WIREFRAME 8 #define SETTING_INPUT_DEVICE_TYPE_MOUSE_KEYBOARD 1 #define SETTING_INPUT_DEVICE_TYPE_CONTROLLER 2 diff --git a/pathfinding/AStar.h b/pathfinding/AStar.h deleted file mode 100644 index e69de29..0000000 diff --git a/pathfinding/Jps.h b/pathfinding/Jps.h deleted file mode 100644 index e69de29..0000000 diff --git a/pathfinding/JpsBounded.h b/pathfinding/JpsBounded.h deleted file mode 100644 index e69de29..0000000 diff --git a/pathfinding/Jpsp.h b/pathfinding/Jpsp.h index e69de29..82ddc68 100644 --- a/pathfinding/Jpsp.h +++ b/pathfinding/Jpsp.h @@ -0,0 +1,150 @@ +/** + * Jingga + * + * @package Utils + * @copyright Jingga + * @license OMS License 2.0 + * @version 1.0.0 + * @link https://jingga.app + */ +#ifndef TOS_PATHFINDING_JPSP_H +#define TOS_PATHFINDING_JPSP_H + +#include +#include + +#include "../stdlib/Types.h" +#include "../utils/MathUtils.h" + +struct JPSNode { + int32 x, y; + f32 cost; +}; + +struct JPSPath { + JPSNode node; + JPSPath* next; +}; + +struct JPSMinHeap { + int32 size; + JPSNode* nodes; +}; + +struct JPSPGrid { + int32 size; + int32* points; + bool* visited; +}; + +inline +void jpsp_swap(JPSNode* a, JPSNode* b) { + JPSNode temp = *a; + *a = *b; + *b = temp; +} + +void jpsp_push(JPSMinHeap* heap, JPSNode node) { + int32 i = heap->size++; + heap->nodes[i] = node; + + while (i != 0 && heap->nodes[(i - 1) / 2].cost > heap->nodes[i].cost) { + jpsp_swap(&heap->nodes[i], &heap->nodes[(i - 1) / 2]); + i = (i - 1) / 2; + } +} + +void jpsp_pop(JPSMinHeap* heap, JPSNode* root) { + heap->nodes[0] = heap->nodes[--heap->size]; + int32 i = 0; + + while (2 * i + 1 < heap->size) { + int32 child = 2 * i + 1; + if (child + 1 < heap->size && heap->nodes[child].cost > heap->nodes[child + 1].cost) { + child++; + } + + if (heap->nodes[i].cost <= heap->nodes[child].cost) { + break; + } + + jpsp_swap(&heap->nodes[i], &heap->nodes[child]); + i = child; + } +} + +bool jpsp_is_valid(int32 x, int32 y) { + return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE && grid[x][y] == 0; +} + +JPSNode jpsp_jump(int32 x, int32 y, int32 px, int32 py, JPSNode* goal) { + int32 dx = x - px; + int32 dy = y - py; + if (!jpsp_is_valid(x, y)) { + return (JPSNode) { -1, -1, INF }; + } + + if (x == goal->x && y == goal->y) { + return (JPSNode) { x, y, 0 }; + } + + // Check forced neighbors + if ((dx != 0 && jpsp_is_valid(x + dx, y) && !jpsp_is_valid(x + dx, y - dy)) + || (dy != 0 && jpsp_is_valid(x, y + dy) && !jpsp_is_valid(x - dx, y + dy)) + ) { + return (JPSNode) { x, y, 0 }; + } + + // Recursive jump in the direction (dx, dy) + if (dx != 0 && dy != 0) { + JPSNode j1 = jpsp_jump(x + dx, y, x, y, goal); + JPSNode j2 = jpsp_jump(x, y + dy, x, y, goal); + + if (j1.x != -1 || j2.x != -1) { + return (JPSNode) { x, y, 0 }; + } + } + + return jpsp_jump(x + dx, y + dy, x, y, goal); +} + +void jpsp_preprocess() { + for (int x = 0; x < GRID_SIZE; x++) { + for (int y = 0; y < GRID_SIZE; y++) { + if (grid[x][y] == 0) { + visited[x][y] = true; + } + } + } +} + +bool jpsp_plus_search(int startX, int startY, int goalX, int goalY) { + preprocess(); + MinHeap openSet = { .size = 0 }; + push(&openSet, (Node) { startX, startY, 0 }); + + while (openSet.size) { + Node current = pop(&openSet); + + if (current.x == goalX && current.y == goalY) { + printf("Path found to goal (%d, %d)\n", goalX, goalY); + return true; + } + + for (int i = 0; i < 8; i++) { + int nx = current.x + dx[i]; + int ny = current.y + dy[i]; + if (isValid(nx, ny)) { + Node jp = jump(nx, ny, current.x, current.y, (Node) { goalX, goalY, 0 }); + if (jp.x != -1 && !visited[jp.x][jp.y]) { + visited[jp.x][jp.y] = true; + double new_cost = current.cost + heuristic(current.x, current.y, jp.x, jp.y); + push(&openSet, (Node) { jp.x, jp.y, new_cost }); + } + } + } + } + return false; +} + +#endif \ No newline at end of file diff --git a/platform/win32/Library.h b/platform/win32/Library.h index f225d9a..394d879 100644 --- a/platform/win32/Library.h +++ b/platform/win32/Library.h @@ -19,14 +19,16 @@ struct Library { HMODULE handle; - uint64 last_load; bool is_valid; char dir[MAX_PATH]; - char src[64]; char dst[64]; - uint32 function_count; + #if DEBUG + uint64 last_load; + #endif + + int32 function_count; const char** function_names; void** functions; }; @@ -36,13 +38,6 @@ bool library_load(Library* lib) { size_t path_length = strlen(lib->dir); - char src[MAX_PATH]; - str_concat( - lib->dir, path_length, - lib->src, strlen(lib->src), - src - ); - char dst[MAX_PATH]; str_concat( lib->dir, path_length, @@ -50,8 +45,18 @@ bool library_load(Library* lib) dst ); - lib->last_load = last_modified(src); - file_copy(src, dst); + #if DEBUG + char src[MAX_PATH]; + size_t dst_len = strlen(dst); + + memcpy(src, dst, dst_len + 1); + + memcpy(dst + dst_len - (sizeof(".dll") - 1), "_temp", sizeof(".temp") - 1); + memcpy(dst + dst_len - (sizeof(".dll") - 1) + (sizeof(".temp") - 1), ".dll", sizeof(".dll")); + + lib->last_load = last_modified(src); + file_copy(src, dst); + #endif // Make sure the dll is actually unloaded (Windows caches this) if (GetModuleHandleA((LPCSTR) dst)) { @@ -60,7 +65,7 @@ bool library_load(Library* lib) Sleep(100); } - int i = 0; + int32 i = 0; while (GetModuleHandleA((LPCSTR) dst) && i < 10) { ++i; Sleep(100); @@ -75,7 +80,7 @@ bool library_load(Library* lib) } lib->is_valid = true; - for (int c = 0; c < lib->function_count; ++c) { + for (int32 c = 0; c < lib->function_count; ++c) { void* function = (void *) GetProcAddress(lib->handle, (LPCSTR) lib->function_names[c]); if (function) { lib->functions[c] = function; @@ -91,7 +96,7 @@ inline void library_unload(Library* lib) { FreeLibrary(lib->handle); - for (int c = 0; c < lib->function_count; ++c) { + for (int32 c = 0; c < lib->function_count; ++c) { lib->functions[c] = NULL; } } diff --git a/platform/win32/SystemInfo.h b/platform/win32/SystemInfo.h index 2e84bb6..c16b723 100644 --- a/platform/win32/SystemInfo.h +++ b/platform/win32/SystemInfo.h @@ -15,6 +15,7 @@ #include "../../stdlib/simd/SIMD_Helper.h" #include "../../utils/StringUtils.h" +#include #include #include #include @@ -37,28 +38,59 @@ // @todo implement for arm? +uint64 system_private_memory_usage() +{ + PROCESS_MEMORY_COUNTERS_EX pmc; + HANDLE process = GetCurrentProcess(); + + GetProcessMemoryInfo(process, (PROCESS_MEMORY_COUNTERS*) &pmc, sizeof(pmc)); + + CloseHandle(process); + + return pmc.PrivateUsage; +} + +uint64 system_app_memory_usage() +{ + MEMORY_BASIC_INFORMATION mbi; + SIZE_T address = 0; + size_t total_size = 0; + + // MEM_IMAGE = DLL memory + // MEM_MAPPED = Mapped files + while (VirtualQueryEx(GetCurrentProcess(), (LPCVOID) address, &mbi, sizeof(mbi)) == sizeof(mbi)) { + if (mbi.State == MEM_COMMIT && (mbi.Type == MEM_IMAGE || mbi.Type == MEM_MAPPED)) { + total_size += mbi.RegionSize; + } + + address += mbi.RegionSize; + } + + return total_size; +} + uint16 system_language_code() { - LANGID langID = GetUserDefaultUILanguage(); - wchar_t localeName[LOCALE_NAME_MAX_LENGTH]; + LANGID lang_id = GetUserDefaultUILanguage(); + wchar_t local_name[LOCALE_NAME_MAX_LENGTH]; - if (!LCIDToLocaleName(langID, localeName, LOCALE_NAME_MAX_LENGTH, 0)) { + if (!LCIDToLocaleName(lang_id, local_name, LOCALE_NAME_MAX_LENGTH, 0)) { return 0; } - return (localeName[0] << 8) | localeName[1]; + return (local_name[0] << 8) | local_name[1]; } uint16 system_country_code() { - LANGID langID = GetUserDefaultUILanguage(); - wchar_t localeName[LOCALE_NAME_MAX_LENGTH]; + LANGID lang_id = GetUserDefaultUILanguage(); + wchar_t local_name[LOCALE_NAME_MAX_LENGTH]; - if (!LCIDToLocaleName(langID, localeName, LOCALE_NAME_MAX_LENGTH, 0)) { + if (!LCIDToLocaleName(lang_id, local_name, LOCALE_NAME_MAX_LENGTH, 0)) { return 0; } - return (localeName[3] << 8) | localeName[4]; + return (local_name[3] << 8) | local_name[4]; } struct CpuCacheInfo { @@ -454,6 +486,33 @@ struct DisplayInfo { int32 hz; }; +void display_info_get_primary(DisplayInfo* info) { + DISPLAY_DEVICEA device; + DEVMODEA mode; + + device.cb = sizeof(DISPLAY_DEVICEA); + + uint32_t i = 0; + while (EnumDisplayDevicesA(NULL, i, &device, 0)) { + ++i; + + if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) { + continue; + } + + mode.dmSize = sizeof(mode); + + if (EnumDisplaySettingsA(device.DeviceName, ENUM_CURRENT_SETTINGS, &mode)) { + strcpy(info->name, device.DeviceName); + info->width = mode.dmPelsWidth; + info->height = mode.dmPelsHeight; + info->hz = mode.dmDisplayFrequency; + } + + break; + } +} + uint32 display_info_get(DisplayInfo* info) { DISPLAY_DEVICEA device; DEVMODEA mode; diff --git a/platform/win32/UtilsWin32.h b/platform/win32/UtilsWin32.h index bbfb06b..0dc304c 100644 --- a/platform/win32/UtilsWin32.h +++ b/platform/win32/UtilsWin32.h @@ -24,6 +24,8 @@ #define strtok_r strtok_s +// @todo Consider to implement directly mapped files (CreateFileMapping) for certain files (e.g. map data or texture data, ...) + inline void relative_to_absolute(const char* rel, char* path) { char self_path[MAX_PATH]; @@ -314,8 +316,28 @@ file_write_struct(const char* path, const void* file, uint32 size) inline void file_copy(const char* src, const char* dst) { - CopyFileA((LPCSTR) src, (LPCSTR) dst, false); + if (*src == '.') { + char src_full_path[MAX_PATH]; + relative_to_absolute(src, src_full_path); + + if (*dst == '.') { + char dst_full_path[MAX_PATH]; + relative_to_absolute(dst, dst_full_path); + + CopyFileA((LPCSTR) src_full_path, (LPCSTR) dst_full_path, false); + } else { + CopyFileA((LPCSTR) src_full_path, (LPCSTR) dst, false); + } + } else if (*dst == '.') { + char dst_full_path[MAX_PATH]; + relative_to_absolute(dst, dst_full_path); + + CopyFileA((LPCSTR) src, (LPCSTR) dst_full_path, false); + } else { + CopyFileA((LPCSTR) src, (LPCSTR) dst, false); + } } + inline void close_handle(HANDLE fp) { diff --git a/platform/win32/input/RawInput.h b/platform/win32/input/RawInput.h index e727be0..3f85290 100644 --- a/platform/win32/input/RawInput.h +++ b/platform/win32/input/RawInput.h @@ -182,6 +182,7 @@ int rawinput_init_controllers(HWND hwnd, Input* __restrict states, RingMemory* r return i; } +inline void input_mouse_position(HWND hwnd, v2_int32* pos) { POINT p; diff --git a/stdlib/Types.h b/stdlib/Types.h index dceb6d5..132a5d7 100644 --- a/stdlib/Types.h +++ b/stdlib/Types.h @@ -46,13 +46,11 @@ typedef intptr_t smm; struct v2_int32 { union { struct { - int32 x; - int32 y; + int32 x, y; }; struct { - int32 width; - int32 height; + int32 width, height; }; int32 v[2]; @@ -62,18 +60,11 @@ struct v2_int32 { struct v3_int32 { union { struct { - union { - int32 x; - int32 r; - }; - union { - int32 y; - int32 g; - }; - union { - int32 z; - int32 b; - }; + int32 x, y, z; + }; + + struct { + int32 r, g, b; }; int32 v[3]; @@ -83,10 +74,15 @@ struct v3_int32 { struct v4_int32 { union { struct { - int32 x; - int32 y; - int32 z; - int32 w; + int32 x, y; + + union { + int32 z, width; + }; + + union { + int32 w, height; + }; }; int32 v[4]; @@ -96,8 +92,7 @@ struct v4_int32 { struct v2_int64 { union { struct { - int64 x; - int64 y; + int64 x, y; }; int64 v[2]; @@ -107,18 +102,11 @@ struct v2_int64 { struct v3_int64 { union { struct { - union { - int64 x; - int64 r; - }; - union { - int64 y; - int64 g; - }; - union { - int64 z; - int64 b; - }; + int64 x, y, z; + }; + + struct { + int64 r, g, b; }; int64 v[3]; @@ -128,10 +116,7 @@ struct v3_int64 { struct v4_int64 { union { struct { - int64 x; - int64 y; - int64 z; - int64 w; + int64 x, y, z, w; }; int64 v[4]; @@ -141,8 +126,7 @@ struct v4_int64 { struct v2_f32 { union { struct { - f32 x; - f32 y; + f32 x, y; }; f32 v[2]; @@ -152,24 +136,19 @@ struct v2_f32 { struct v3_f32 { union { struct { - union { - f32 x; - f32 r; - f32 pitch; - f32 u; - }; - union { - f32 y; - f32 g; - f32 yaw; - f32 v; - }; - union { - f32 z; - f32 b; - f32 roll; - f32 w; - }; + f32 x, y, z; + }; + + struct { + f32 r, g, b; + }; + + struct { + f32 pitch, yaw, roll; + }; + + struct { + f32 u, v, w; }; f32 vec[3]; @@ -179,23 +158,15 @@ struct v3_f32 { struct v4_f32 { union { struct { - union { - f32 x; - f32 r; - }; - union { - f32 y; - f32 g; - }; + f32 x, y, z, w; + }; - union { - f32 z; - f32 b; - }; - union { - f32 w; - f32 a; - }; + struct { + f32 r, g, b, a; + }; + + struct { + f32 x, y, width, height; }; f32 vec[4]; @@ -216,18 +187,11 @@ struct v2_f64 { struct v3_f64 { union { struct { - union { - f64 x; - f64 r; - }; - union { - f64 y; - f64 g; - }; - union { - f64 z; - f64 b; - }; + f64 x, y, z; + }; + + struct { + f64 r, g, b; }; f64 v[3]; diff --git a/stdlib/simd/SIMD_Helper.h b/stdlib/simd/SIMD_Helper.h index 13b9f43..c333edf 100644 --- a/stdlib/simd/SIMD_Helper.h +++ b/stdlib/simd/SIMD_Helper.h @@ -26,10 +26,10 @@ inline int32 max_sse_supported() int32 cpuInfo[4] = {-1}; __cpuid(cpuInfo, 1); // CPUID function 1 - uint32_t ecx = cpuInfo[2]; - uint32_t edx = cpuInfo[3]; + uint32 ecx = cpuInfo[2]; + uint32 edx = cpuInfo[3]; #else - uint32_t eax, ebx, ecx, edx; + uint32 eax, ebx, ecx, edx; eax = 1; // CPUID function 1 __asm__ __volatile__("cpuid;" @@ -77,7 +77,7 @@ int max_avx256_supported() } } #else - unsigned int32 eax, ebx, ecx, edx; + uint32 eax, ebx, ecx, edx; __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) @@ -112,7 +112,7 @@ int max_avx512_supported() ebx = cpuInfo[1]; } #else - unsigned int32 eax, ebx, ecx, edx; + uint32 eax, ebx, ecx, edx; __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) @@ -161,8 +161,7 @@ int max_avx512_supported() return 0; } -/* -const char avx512_versions[8][12] = { +const char AVX512_VERSIONS[8][12] = { "AVX-512F", "AVX-512DQ", "AVX-512IFMA", @@ -172,6 +171,34 @@ const char avx512_versions[8][12] = { "AVX-512BW", "AVX-512VL" }; -*/ + +bool supports_abm() { + bool popcnt_supported; + bool lzcnt_supported; + + #ifdef _MSC_VER + int cpuInfo[4]; + __cpuid(cpuInfo, 0x80000001); + + popcnt_supported = (cpuInfo[2] & (1 << 5)) != 0; + lzcnt_supported = (cpuInfo[1] & (1 << 5)) != 0; + #else + uint32 eax, ebx, ecx, edx; + eax = 0x80000001; + + __asm__ __volatile__ ( + "cpuid" + : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) + : "a"(eax) + ); + + // Check if the ABM (POPCNT and LZCNT) bits are set + popcnt_supported = (ecx & (1 << 5)) != 0; + lzcnt_supported = (ebx & (1 << 5)) != 0; + #endif + + + return popcnt_supported && lzcnt_supported; +} #endif \ No newline at end of file diff --git a/utils/BitUtils.h b/utils/BitUtils.h index 1315ae5..bac7988 100644 --- a/utils/BitUtils.h +++ b/utils/BitUtils.h @@ -12,6 +12,10 @@ #include #include "../stdlib/Types.h" +// @todo Replace many of these functions with intrinsic functions +// This file can remain but the callers should get adjusted +// Obviously we would have to check at runtime if ABM is supported + // Left to right #define IS_BIT_SET_L2R(num, pos, bits) ((bool) ((num) & (1 << ((bits - 1) - (pos))))) #define BIT_SET_L2R(num, pos, bits) ((num) | ((uint32) 1 << ((bits - 1) - (pos)))) @@ -346,4 +350,50 @@ uint32 bits_reverse(uint32 data, uint32 count) return reversed; } +const int32 BIT_COUNT_LOOKUP_TABLE[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +int32 bits_count(uint64 data) { + return BIT_COUNT_LOOKUP_TABLE[data & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 8) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 16) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 24) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 32) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 40) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 48) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 56) & 0xFF]; +} + +int32 bits_count(uint32 data) { + return BIT_COUNT_LOOKUP_TABLE[data & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 8) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 16) & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 24) & 0xFF]; +} + +int32 bits_count(uint16 data) { + return BIT_COUNT_LOOKUP_TABLE[data & 0xFF] + + BIT_COUNT_LOOKUP_TABLE[(data >> 8) & 0xFF]; +} + +int32 bits_count(uint8 data) { + return BIT_COUNT_LOOKUP_TABLE[data]; +} + #endif \ No newline at end of file diff --git a/utils/StringUtils.h b/utils/StringUtils.h index 1c5d667..5e96e67 100644 --- a/utils/StringUtils.h +++ b/utils/StringUtils.h @@ -134,40 +134,30 @@ int32 utf8_get_char_at(const char* in, int32 index) { } inline -void wchar_to_char(wchar_t* str, int32 length = 0) +void wchar_to_char(wchar_t* str) { - char *dest = (char *) str; - size_t len = wcslen(str) * sizeof(wchar_t); + char *src = (char*) str; + char *dest = (char *) src; - if (length > 0 && length < len) { - len = length; - } - - for (int32 i = 0; i < len; ++i) { - if (*str != '\0') { - *dest = (char) *str; - ++dest; + while (*src != '\0' && src[1] != '\0') { + if (*src != '\0') { + *dest++ = (char) *src; } - ++str; + ++src; } *dest = '\0'; } inline -void wchar_to_char(const wchar_t* __restrict src, char* __restrict dest, int32 length = 0) +void wchar_to_char(const char* str, char* __restrict dest) { - size_t len = wcslen(src) * sizeof(wchar_t); + char *src = (char*) str; - if (length > 0 && length < len) { - len = length; - } - - for (int32 i = 0; i < len; ++i) { + while (*src != '\0' && src[1] != '\0') { if (*src != '\0') { - *dest = (char) *src; - ++dest; + *dest++ = (char) *src; } ++src; @@ -182,9 +172,8 @@ int32 str_to_int(const char *str) int32 result = 0; int32 sign = 1; - if (*str == '-') { + if (*str++ == '-') { sign = -1; - ++str; } while (*str >= '0' && *str <= '9') { @@ -210,7 +199,7 @@ int32 int_to_str(int64 number, char *str, const char thousands = ',') { } while (number > 0) { - if (thousands + if (thousands != '\0' && (digit_count == 3 || digit_count == 6 || digit_count == 9 || digit_count == 12 || digit_count == 15) ) { str[i++] = thousands; @@ -339,34 +328,54 @@ char* strtok(char* str, const char* __restrict delim, char* *key) { inline constexpr char toupper_ascii(char c) { - return c >= 'a' && c <= 'z' - ? c & 0x5f - : c; + return c - 32 * (c >= 'a' && c <= 'z'); +} + +inline +void toupper_ascii(char* str) +{ + while (*str != '\0') { + *str -= 32 * (*str >= 'a' && *str <= 'z'); + ++str; + } } inline constexpr char tolower_ascii(char c) { - return c >= 'A' && c <= 'Z' - ? c | 0x20 - : c; + return c + 32 * (c >= 'A' && c <= 'Z'); +} + +inline +void tolower_ascii(char* str) +{ + while (*str != '\0') { + *str += 32 * (*str >= 'A' && *str <= 'Z'); + ++str; + } } inline constexpr void create_const_name(const unsigned char* name, char* modified_name) { - // Print block - if (name == NULL) { - modified_name = NULL; - } else { - size_t i; - const size_t length = strlen((const char* ) name); - for (i = 0; i < length; ++i) { - modified_name[i] = name[i] == ' ' ? '_' : toupper_ascii(name[i]); - } - - modified_name[i] = '\0'; + size_t i = 0; + while (*name != '\0') { + modified_name[i] = *name == ' ' ? '_' : toupper_ascii(*name); + ++name; + ++i; } + + modified_name[i] = '\0'; +} + +inline +void create_const_name(unsigned char* name) +{ + while (*name != '\0') { + *name = *name == ' ' ? '_' : toupper_ascii(*name); + } + + *name = '\0'; } inline constexpr @@ -421,12 +430,12 @@ void print_bytes(const void* ptr, size_t size) { const unsigned char* bytePtr = (const unsigned char *) ptr; - int32 count = 0; + size_t count = 0; - for (int32 i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { ++count; if (count == 1) { - printf("%03d - %03d: %02x ", i + 1, i + 8, bytePtr[i]); + printf("%03lld - %03lld: %02x ", i + 1, i + 8, bytePtr[i]); } else if (count < 8) { printf("%02x ", bytePtr[i]); } else { @@ -448,4 +457,21 @@ int32 is_eol(const char* str) return 0; } +inline constexpr +bool is_whitespace(char str) +{ + return str == ' ' || str == '\t'; +} + +inline +int32 chars_to_eol(const char* str) +{ + int32 offset = 0; + while (!is_eol(str) && *str != '\0') { + ++offset; + } + + return offset; +} + #endif \ No newline at end of file