From ac3cdea08cea8fbae11d23d595d00316f1227e0f Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 20:56:13 -0300 Subject: [PATCH 1/9] init --- config.ini | 15 ++++++++++++ src/framework/core/configmanager.cpp | 28 ++++++++++++++++++++-- src/framework/core/configmanager.h | 18 +++++++++++++- src/framework/graphics/drawpoolmanager.cpp | 14 +++++++++-- src/framework/graphics/textureatlas.cpp | 3 ++- vcpkg.json | 3 ++- 6 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 config.ini diff --git a/config.ini b/config.ini new file mode 100644 index 0000000000..8af213bef4 --- /dev/null +++ b/config.ini @@ -0,0 +1,15 @@ +; Put public-facing settings here, such as graphics definitions supported by the client. +; This section can also expose options intended for modding, including font customization. + +[graphics] + +; ===== Atlas configuration ===== +; maxAtlasSize: hard cap for atlas textures (in pixels). +maxAtlasSize = 8192 + +; Atlas sizes (in pixels): +; 0 = auto-detect based on the maximum texture size supported by the GPU +; -1 = disable the atlas +mapAtlasSize = 0 +foregroundAtlasSize = 2048 +; =============================== \ No newline at end of file diff --git a/src/framework/core/configmanager.cpp b/src/framework/core/configmanager.cpp index 11663a938b..2236e39a6d 100644 --- a/src/framework/core/configmanager.cpp +++ b/src/framework/core/configmanager.cpp @@ -21,10 +21,17 @@ */ #include "configmanager.h" +#include +#include "resourcemanager.h" ConfigManager g_configs; -void ConfigManager::init() { m_settings = std::make_shared(); } +void ConfigManager::init() { + m_settings = std::make_shared(); + + // Comment out or remove this line to skip loading config.ini. + loadPublicConfig("config.ini"); +} void ConfigManager::terminate() { @@ -116,4 +123,21 @@ bool ConfigManager::unload(const std::string& file) return false; } -void ConfigManager::remove(const ConfigPtr& config) { m_configs.remove(config); } \ No newline at end of file +void ConfigManager::remove(const ConfigPtr& config) { m_configs.remove(config); } + +void ConfigManager::loadPublicConfig(const std::string& fileName) { + try { + auto content = g_resources.readFileContents(fileName); + INIReader reader(content.c_str(), content.size()); + + if (reader.ParseError() < 0) { + g_logger.error("Failed to read config otml '{}''", fileName); + return; + } + + m_publicConfig.graphics.maxAtlasSize = std::max(2048, reader.GetInteger("graphics", "maxAtlasSize", 8192)); + m_publicConfig.graphics.mapAtlasSize = reader.GetInteger("graphics", "mapAtlasSize", 0); + m_publicConfig.graphics.foregroundAtlasSize = reader.GetInteger("graphics", "foregroundAtlasSize", 2048); + } catch (std::exception e) { + } +} \ No newline at end of file diff --git a/src/framework/core/configmanager.h b/src/framework/core/configmanager.h index bb542a06d7..16541587d1 100644 --- a/src/framework/core/configmanager.h +++ b/src/framework/core/configmanager.h @@ -24,7 +24,19 @@ #include "config.h" - // @bindsingleton g_configs +struct GraphicsConfig +{ + uint16_t maxAtlasSize = 8192; + int16_t mapAtlasSize = 0; + int16_t foregroundAtlasSize = 2048; +}; + +struct PublicConfig +{ + GraphicsConfig graphics; +}; + +// @bindsingleton g_configs class ConfigManager { public: @@ -41,11 +53,15 @@ class ConfigManager bool unload(const std::string& file); void remove(const ConfigPtr& config); + const PublicConfig& getPublicConfig() { return m_publicConfig; } + void loadPublicConfig(const std::string& file); + protected: ConfigPtr m_settings; private: std::list m_configs; + PublicConfig m_publicConfig; }; extern ConfigManager g_configs; diff --git a/src/framework/graphics/drawpoolmanager.cpp b/src/framework/graphics/drawpoolmanager.cpp index c5ed0c4ea1..2efc3e829b 100644 --- a/src/framework/graphics/drawpoolmanager.cpp +++ b/src/framework/graphics/drawpoolmanager.cpp @@ -25,6 +25,7 @@ #include "graphics.h" #include "painter.h" #include "textureatlas.h" +#include thread_local static uint8_t CURRENT_POOL = static_cast(DrawPoolType::LAST); @@ -39,8 +40,17 @@ void DrawPoolManager::init(const uint16_t spriteSize) if (spriteSize != 0) m_spriteSize = spriteSize; - auto atlasMap = std::make_shared(Fw::TextureAtlasType::MAP, g_graphics.getMaxTextureSize()); - auto atlasForeground = std::make_shared(Fw::TextureAtlasType::FOREGROUND, 2048, true); + auto mapAtlasSize = g_configs.getPublicConfig().graphics.mapAtlasSize; + auto foregroundAtlasSize = g_configs.getPublicConfig().graphics.foregroundAtlasSize; + + if (mapAtlasSize == 0) + mapAtlasSize = g_graphics.getMaxTextureSize(); + + if (foregroundAtlasSize == 0) + foregroundAtlasSize = g_graphics.getMaxTextureSize(); + + auto atlasMap = mapAtlasSize > 0 ? std::make_shared(Fw::TextureAtlasType::MAP, mapAtlasSize) : nullptr; + auto atlasForeground = foregroundAtlasSize > 0 ? std::make_shared(Fw::TextureAtlasType::FOREGROUND, foregroundAtlasSize, true) : nullptr; // Create Pools for (int8_t i = -1; ++i < static_cast(DrawPoolType::LAST);) { diff --git a/src/framework/graphics/textureatlas.cpp b/src/framework/graphics/textureatlas.cpp index bcd678ebee..bfc405a3a6 100644 --- a/src/framework/graphics/textureatlas.cpp +++ b/src/framework/graphics/textureatlas.cpp @@ -2,6 +2,7 @@ #include "textureatlas.h" #include "painter.h" +#include // Extra padding around smooth textures to avoid sampling artifacts (in pixels) static constexpr uint8_t SMOOTH_PADDING = 2; @@ -15,7 +16,7 @@ static constexpr int MIN_PADDED_ATLAS_TEXTURE_SIZE = 4 + SMOOTH_PADDING * 2; TextureAtlas::TextureAtlas(Fw::TextureAtlasType type, int size, bool smoothSupport) : m_type(type), - m_size({ std::min(size, 8192) }) { + m_size({ std::min(size, g_configs.getPublicConfig().graphics.maxAtlasSize) }) { createNewLayer(false); if (smoothSupport) createNewLayer(true); diff --git a/vcpkg.json b/vcpkg.json index e13cbae3a8..2689443ea0 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -23,7 +23,8 @@ "bshoshany-thread-pool", "fmt", "utfcpp", - "gtest", + "gtest", + "inih", { "name": "luajit", "platform": "!android & !wasm32" From e627766ad8b53e00a2df9f5fa2bd05956ec06f4e Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:16:18 -0300 Subject: [PATCH 2/9] Update vcpkg.json --- vcpkg.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vcpkg.json b/vcpkg.json index 2689443ea0..1b6c40cac8 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -23,8 +23,8 @@ "bshoshany-thread-pool", "fmt", "utfcpp", - "gtest", - "inih", + "gtest", + { "name": "inih", "features": ["cpp"] }, { "name": "luajit", "platform": "!android & !wasm32" @@ -42,5 +42,5 @@ "platform": "windows" } ], - "builtin-baseline":"b322364f06308bdd24823f9d8f03fe0cc86fd46f" + "builtin-baseline": "b322364f06308bdd24823f9d8f03fe0cc86fd46f" } From d7a0d3c9e33c36c5afb0d542b2271ff974be328b Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:17:32 -0300 Subject: [PATCH 3/9] Update configmanager.cpp --- src/framework/core/configmanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/framework/core/configmanager.cpp b/src/framework/core/configmanager.cpp index 2236e39a6d..c2ca3a96fe 100644 --- a/src/framework/core/configmanager.cpp +++ b/src/framework/core/configmanager.cpp @@ -138,6 +138,7 @@ void ConfigManager::loadPublicConfig(const std::string& fileName) { m_publicConfig.graphics.maxAtlasSize = std::max(2048, reader.GetInteger("graphics", "maxAtlasSize", 8192)); m_publicConfig.graphics.mapAtlasSize = reader.GetInteger("graphics", "mapAtlasSize", 0); m_publicConfig.graphics.foregroundAtlasSize = reader.GetInteger("graphics", "foregroundAtlasSize", 2048); - } catch (std::exception e) { + } catch (const std::exception& e) { + g_logger.error("Failed to load public config '{}': {}", fileName, e.what()); } } \ No newline at end of file From 92eebbd5fceec940492497b569f0d10adfce715b Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:27:02 -0300 Subject: [PATCH 4/9] fix compile --- cmake/Findinih.cmake | 59 ++++++++++++++++++++++++++++++++++++++++++++ vcpkg.json | 6 ++--- 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 cmake/Findinih.cmake diff --git a/cmake/Findinih.cmake b/cmake/Findinih.cmake new file mode 100644 index 0000000000..812bb407bd --- /dev/null +++ b/cmake/Findinih.cmake @@ -0,0 +1,59 @@ +include(FindPackageHandleStandardArgs) + +find_package(unofficial-inih CONFIG QUIET) + +if(TARGET unofficial::inih::libinih) + add_library(inih::inih INTERFACE IMPORTED) + target_link_libraries(inih::inih INTERFACE unofficial::inih::libinih) +endif() + +if(TARGET unofficial::inih::inireader) + add_library(inih::inireader INTERFACE IMPORTED) + target_link_libraries(inih::inireader INTERFACE unofficial::inih::inireader) +endif() + +if(TARGET inih::inih) + set(inih_FOUND TRUE) + return() +endif() + +find_path(INIH_INCLUDE_DIR + NAMES ini.h + PATH_SUFFIXES inih include +) + +find_library(INIH_LIBRARY + NAMES inih libinih +) + +# Optional: INIReader (C++ wrapper) +find_path(INIH_CPP_INCLUDE_DIR + NAMES INIReader.h + PATH_SUFFIXES inih cpp include +) + +find_library(INIH_CPP_LIBRARY + NAMES inireader libinireader inihcpp libinihcpp +) + +find_package_handle_standard_args(inih + REQUIRED_VARS INIH_INCLUDE_DIR INIH_LIBRARY +) + +if(inih_FOUND) + add_library(inih::inih UNKNOWN IMPORTED) + set_target_properties(inih::inih PROPERTIES + IMPORTED_LOCATION "${INIH_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${INIH_INCLUDE_DIR}" + ) + + if(INIH_CPP_INCLUDE_DIR AND INIH_CPP_LIBRARY) + add_library(inih::inireader UNKNOWN IMPORTED) + set_target_properties(inih::inireader PROPERTIES + IMPORTED_LOCATION "${INIH_CPP_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${INIH_CPP_INCLUDE_DIR}" + ) + # inireader depends on core inih in many layouts + target_link_libraries(inih::inireader INTERFACE inih::inih) + endif() +endif() diff --git a/vcpkg.json b/vcpkg.json index 1b6c40cac8..2689443ea0 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -23,8 +23,8 @@ "bshoshany-thread-pool", "fmt", "utfcpp", - "gtest", - { "name": "inih", "features": ["cpp"] }, + "gtest", + "inih", { "name": "luajit", "platform": "!android & !wasm32" @@ -42,5 +42,5 @@ "platform": "windows" } ], - "builtin-baseline": "b322364f06308bdd24823f9d8f03fe0cc86fd46f" + "builtin-baseline":"b322364f06308bdd24823f9d8f03fe0cc86fd46f" } From 2cbc6b7b8490aff956da151c6a140947209f5bc4 Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:27:19 -0300 Subject: [PATCH 5/9] Update Findinih.cmake --- cmake/Findinih.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/Findinih.cmake b/cmake/Findinih.cmake index 812bb407bd..bdaf3083cd 100644 --- a/cmake/Findinih.cmake +++ b/cmake/Findinih.cmake @@ -53,7 +53,6 @@ if(inih_FOUND) IMPORTED_LOCATION "${INIH_CPP_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${INIH_CPP_INCLUDE_DIR}" ) - # inireader depends on core inih in many layouts target_link_libraries(inih::inireader INTERFACE inih::inih) endif() endif() From b7b51216ac3857cfd23e6435258fb325d1851c15 Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:44:36 -0300 Subject: [PATCH 6/9] fixes --- cmake/Findinih.cmake | 58 ---------------------------- src/CMakeLists.txt | 3 ++ src/framework/core/configmanager.cpp | 2 +- vcpkg.json | 2 +- 4 files changed, 5 insertions(+), 60 deletions(-) delete mode 100644 cmake/Findinih.cmake diff --git a/cmake/Findinih.cmake b/cmake/Findinih.cmake deleted file mode 100644 index bdaf3083cd..0000000000 --- a/cmake/Findinih.cmake +++ /dev/null @@ -1,58 +0,0 @@ -include(FindPackageHandleStandardArgs) - -find_package(unofficial-inih CONFIG QUIET) - -if(TARGET unofficial::inih::libinih) - add_library(inih::inih INTERFACE IMPORTED) - target_link_libraries(inih::inih INTERFACE unofficial::inih::libinih) -endif() - -if(TARGET unofficial::inih::inireader) - add_library(inih::inireader INTERFACE IMPORTED) - target_link_libraries(inih::inireader INTERFACE unofficial::inih::inireader) -endif() - -if(TARGET inih::inih) - set(inih_FOUND TRUE) - return() -endif() - -find_path(INIH_INCLUDE_DIR - NAMES ini.h - PATH_SUFFIXES inih include -) - -find_library(INIH_LIBRARY - NAMES inih libinih -) - -# Optional: INIReader (C++ wrapper) -find_path(INIH_CPP_INCLUDE_DIR - NAMES INIReader.h - PATH_SUFFIXES inih cpp include -) - -find_library(INIH_CPP_LIBRARY - NAMES inireader libinireader inihcpp libinihcpp -) - -find_package_handle_standard_args(inih - REQUIRED_VARS INIH_INCLUDE_DIR INIH_LIBRARY -) - -if(inih_FOUND) - add_library(inih::inih UNKNOWN IMPORTED) - set_target_properties(inih::inih PROPERTIES - IMPORTED_LOCATION "${INIH_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${INIH_INCLUDE_DIR}" - ) - - if(INIH_CPP_INCLUDE_DIR AND INIH_CPP_LIBRARY) - add_library(inih::inireader UNKNOWN IMPORTED) - set_target_properties(inih::inireader PROPERTIES - IMPORTED_LOCATION "${INIH_CPP_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${INIH_CPP_INCLUDE_DIR}" - ) - target_link_libraries(inih::inireader INTERFACE inih::inih) - endif() -endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6e14d51ceb..ddd8413e68 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -388,6 +388,9 @@ if (WASM) endif() add_library(otclient_core STATIC ${SOURCE_FILES}) + +target_link_libraries(otclient_core PRIVATE unofficial::inih::inireader) + if(NOT MSVC) target_link_options(otclient_core PUBLIC -flto=auto) endif() diff --git a/src/framework/core/configmanager.cpp b/src/framework/core/configmanager.cpp index c2ca3a96fe..6d0bd31a4d 100644 --- a/src/framework/core/configmanager.cpp +++ b/src/framework/core/configmanager.cpp @@ -139,6 +139,6 @@ void ConfigManager::loadPublicConfig(const std::string& fileName) { m_publicConfig.graphics.mapAtlasSize = reader.GetInteger("graphics", "mapAtlasSize", 0); m_publicConfig.graphics.foregroundAtlasSize = reader.GetInteger("graphics", "foregroundAtlasSize", 2048); } catch (const std::exception& e) { - g_logger.error("Failed to load public config '{}': {}", fileName, e.what()); + g_logger.error("Failed to parse public config '{}'", fileName); } } \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json index 2689443ea0..b6e0e73671 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -24,7 +24,7 @@ "fmt", "utfcpp", "gtest", - "inih", + { "name": "inih", "features": ["cpp"] }, { "name": "luajit", "platform": "!android & !wasm32" From bd5f93ad4c75fe9e8794239f9b8e4bc5bbb7b42e Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:51:14 -0300 Subject: [PATCH 7/9] Update CMakeLists.txt --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ddd8413e68..7b2cdbcd2b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,6 +132,7 @@ find_package(ZLIB REQUIRED) find_package(httplib CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED) find_package(utf8cpp REQUIRED) +find_package(unofficial-inih CONFIG REQUIRED) find_path(CPPCODEC_INCLUDE_DIRS "cppcodec/base32_crockford.hpp") From f229f6cb00ea54e2fe2628d3908091f0161fdc7b Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:54:32 -0300 Subject: [PATCH 8/9] update --- src/framework/core/configmanager.cpp | 2 +- src/framework/core/configmanager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/core/configmanager.cpp b/src/framework/core/configmanager.cpp index 6d0bd31a4d..4e2c280b5b 100644 --- a/src/framework/core/configmanager.cpp +++ b/src/framework/core/configmanager.cpp @@ -139,6 +139,6 @@ void ConfigManager::loadPublicConfig(const std::string& fileName) { m_publicConfig.graphics.mapAtlasSize = reader.GetInteger("graphics", "mapAtlasSize", 0); m_publicConfig.graphics.foregroundAtlasSize = reader.GetInteger("graphics", "foregroundAtlasSize", 2048); } catch (const std::exception& e) { - g_logger.error("Failed to parse public config '{}'", fileName); + g_logger.error("Failed to parse public config '{}': {}", fileName, e.what()); } } \ No newline at end of file diff --git a/src/framework/core/configmanager.h b/src/framework/core/configmanager.h index 16541587d1..507463f5bb 100644 --- a/src/framework/core/configmanager.h +++ b/src/framework/core/configmanager.h @@ -53,7 +53,7 @@ class ConfigManager bool unload(const std::string& file); void remove(const ConfigPtr& config); - const PublicConfig& getPublicConfig() { return m_publicConfig; } + const PublicConfig& getPublicConfig() const { return m_publicConfig; } void loadPublicConfig(const std::string& file); protected: From 1dd497f8b5a58e0a004763d064265ef44ff92a89 Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Mon, 29 Dec 2025 21:57:23 -0300 Subject: [PATCH 9/9] Update configmanager.cpp --- src/framework/core/configmanager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/framework/core/configmanager.cpp b/src/framework/core/configmanager.cpp index 4e2c280b5b..970d195ad9 100644 --- a/src/framework/core/configmanager.cpp +++ b/src/framework/core/configmanager.cpp @@ -135,9 +135,9 @@ void ConfigManager::loadPublicConfig(const std::string& fileName) { return; } - m_publicConfig.graphics.maxAtlasSize = std::max(2048, reader.GetInteger("graphics", "maxAtlasSize", 8192)); - m_publicConfig.graphics.mapAtlasSize = reader.GetInteger("graphics", "mapAtlasSize", 0); - m_publicConfig.graphics.foregroundAtlasSize = reader.GetInteger("graphics", "foregroundAtlasSize", 2048); + m_publicConfig.graphics.maxAtlasSize = std::max(2048, reader.GetInteger("graphics", "maxAtlasSize", m_publicConfig.graphics.maxAtlasSize)); + m_publicConfig.graphics.mapAtlasSize = reader.GetInteger("graphics", "mapAtlasSize", m_publicConfig.graphics.mapAtlasSize); + m_publicConfig.graphics.foregroundAtlasSize = reader.GetInteger("graphics", "foregroundAtlasSize", m_publicConfig.graphics.foregroundAtlasSize); } catch (const std::exception& e) { g_logger.error("Failed to parse public config '{}': {}", fileName, e.what()); }