diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 7289d7f92..4c4f6a905 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -257,7 +257,6 @@ add_devilutionx_object_library(libdevilutionx_palette_kd_tree ) target_link_dependencies(libdevilutionx_palette_kd_tree PUBLIC DevilutionX::SDL - fmt::fmt libdevilutionx_strings ) @@ -554,7 +553,6 @@ add_devilutionx_object_library(libdevilutionx_palette_blending ) target_link_dependencies(libdevilutionx_palette_blending PUBLIC DevilutionX::SDL - fmt::fmt libdevilutionx_palette_kd_tree libdevilutionx_strings ) diff --git a/Source/dvlnet/zerotier_native.cpp b/Source/dvlnet/zerotier_native.cpp index 48c7fce36..8f2620dbd 100644 --- a/Source/dvlnet/zerotier_native.cpp +++ b/Source/dvlnet/zerotier_native.cpp @@ -66,9 +66,13 @@ std::string ComputeAlternateFolderName(std::string_view path) nullptr, 0); if (status != 0) - return ""; + return {}; - return fmt::format("{:02x}", fmt::join(hash, "")); + char buf[hashSize * 2]; + for (size_t i = 0; i < hashSize; ++i) { + BufCopy(&buf[i * 2], AsHexPad2(hash[i])); + } + return std::string(buf, hashSize * 2); } std::string ToZTCompliantPath(std::string_view configPath) diff --git a/Source/engine/render/text_render.cpp b/Source/engine/render/text_render.cpp index d2b656da2..002f313e9 100644 --- a/Source/engine/render/text_render.cpp +++ b/Source/engine/render/text_render.cpp @@ -34,6 +34,7 @@ #include "utils/is_of.hpp" #include "utils/language.h" #include "utils/log.hpp" +#include "utils/str_cat.hpp" #include "utils/utf8.hpp" namespace devilution { @@ -139,12 +140,12 @@ bool IsSmallFontTallRow(uint16_t row) void GetFontPath(GameFontTables size, uint16_t row, std::string_view ext, char *out) { - *fmt::format_to(out, R"(fonts\{}-{:02x}{})", FontSizes[size], row, ext) = '\0'; + *BufCopy(out, "fonts\\", FontSizes[size], "-", AsHexPad2(row), ext) = '\0'; } void GetFontPath(std::string_view language_code, GameFontTables size, uint16_t row, std::string_view ext, char *out) { - *fmt::format_to(out, R"(fonts\{}\{}-{:02x}{})", language_code, FontSizes[size], row, ext) = '\0'; + *BufCopy(out, "fonts\\", language_code, "\\", FontSizes[size], "-", AsHexPad2(row), ext) = '\0'; } uint32_t GetFontId(GameFontTables size, uint16_t row) diff --git a/Source/utils/palette_kd_tree.cpp b/Source/utils/palette_kd_tree.cpp index d3c569f56..aa137220f 100644 --- a/Source/utils/palette_kd_tree.cpp +++ b/Source/utils/palette_kd_tree.cpp @@ -13,8 +13,6 @@ #include #endif -#include - #include "utils/static_vector.hpp" #include "utils/str_cat.hpp" @@ -197,9 +195,8 @@ void PaletteKdTreeNode<0>::toGraphvizDot( const std::pair *const end = values.data() + valuesEndInclusive; for (const std::pair *it = values.data() + valuesBegin; it <= end; ++it) { const auto &[rgb, paletteIndex] = *it; - char hexColor[6]; - fmt::format_to(hexColor, "{:02x}{:02x}{:02x}", rgb[0], rgb[1], rgb[2]); - StrAppend(dot, R"("); + StrAppend(dot, R"("); const bool useWhiteText = rgb[0] + rgb[1] + rgb[2] < 350; if (useWhiteText) StrAppend(dot, R"()"); StrAppend(dot, diff --git a/Source/utils/str_cat.cpp b/Source/utils/str_cat.cpp index ebb99c2d0..157c2e8d3 100644 --- a/Source/utils/str_cat.cpp +++ b/Source/utils/str_cat.cpp @@ -1,9 +1,17 @@ #include "utils/str_cat.hpp" +#include + #include namespace devilution { +namespace { + +[[nodiscard]] char HexDigit(uint8_t v) { return "0123456789abcdef"[v]; } + +} // namespace + char *BufCopy(char *out, long long value) { const fmt::format_int formatted { value }; @@ -16,6 +24,23 @@ char *BufCopy(char *out, unsigned long long value) std::memcpy(out, formatted.data(), formatted.size()); return out + formatted.size(); } +char *BufCopy(char *out, AsHexU8Pad2 value) +{ + *out++ = HexDigit(value.value >> 4); + *out++ = HexDigit(value.value & 0xf); + return out; +} +char *BufCopy(char *out, AsHexU16Pad2 value) +{ + if (value.value > 0xff) { + if (value.value > 0xfff) { + out = BufCopy(out, AsHexU8Pad2 { static_cast(value.value >> 8) }); + } else { + *out++ = HexDigit(value.value >> 8); + } + } + return BufCopy(out, AsHexU8Pad2 { static_cast(value.value & 0xff) }); +} void StrAppend(std::string &out, long long value) { @@ -27,5 +52,17 @@ void StrAppend(std::string &out, unsigned long long value) const fmt::format_int formatted { value }; out.append(formatted.data(), formatted.size()); } +void StrAppend(std::string &out, AsHexU8Pad2 value) +{ + char hex[2]; + BufCopy(hex, value); + out.append(hex, 2); +} +void StrAppend(std::string &out, AsHexU16Pad2 value) +{ + char hex[4]; + const auto len = static_cast(BufCopy(hex, value) - hex); + out.append(hex, len); +} } // namespace devilution diff --git a/Source/utils/str_cat.hpp b/Source/utils/str_cat.hpp index b8a03fc95..ac939b687 100644 --- a/Source/utils/str_cat.hpp +++ b/Source/utils/str_cat.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -7,6 +8,24 @@ namespace devilution { +struct AsHexU8Pad2 { + uint8_t value; +}; + +struct AsHexU16Pad2 { + uint16_t value; +}; + +/** + * @brief Formats the value as a lowercase zero-padded hexadecimal with at least 2 hex digits (0-padded on the left). + */ +constexpr AsHexU8Pad2 AsHexPad2(uint8_t value) { return { value }; } + +/** + * @brief Formats the value as a lowercase zero-padded hexadecimal with at least 2 hex digits (0-padded on the left). + */ +constexpr AsHexU16Pad2 AsHexPad2(uint16_t value) { return { value }; } + /** * @brief Writes the integer to the given buffer. * @return char* end of the buffer @@ -43,6 +62,9 @@ inline char *BufCopy(char *out, unsigned short value) return BufCopy(out, static_cast(value)); } +char *BufCopy(char *out, AsHexU8Pad2 value); +char *BufCopy(char *out, AsHexU16Pad2 value); + /** * @brief Appends the integer to the given string. */ @@ -77,6 +99,9 @@ inline void StrAppend(std::string &out, unsigned short value) StrAppend(out, static_cast(value)); } +void StrAppend(std::string &out, AsHexU8Pad2 value); +void StrAppend(std::string &out, AsHexU16Pad2 value); + /** * @brief Copies the given std::string_view to the given buffer. */