From bfa6e4f401a931acb270cee52a98d9bfa7feab59 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 16 Jan 2024 06:21:13 -0800 Subject: [PATCH] srb2::Draw::TextElement: add parse method - Parse and translate special characters - Currently supported: - Button codes - - - - - - - - - - - - - - All button codes can be suffixed with '_pressed' or '_animated' - E.g. or --- src/v_draw.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/v_draw.hpp | 9 ++++++ 2 files changed, 84 insertions(+) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 0f869e653..cfdd26773 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -7,6 +7,8 @@ // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- +#include + #include "doomdef.h" // skincolornum_t #include "doomtype.h" #include "hu_stuff.h" @@ -27,6 +29,79 @@ int Draw::TextElement::width() const return font_ ? font_width(*font_, default_font_flags(*font_) | flags_.value_or(0), string_.c_str()) / FRACUNIT : 0; } +Draw::TextElement& Draw::TextElement::parse(std::string_view raw) +{ + static const std::unordered_map translation = { +#define BUTTON(str, lower_bits) \ + {str, 0xB0 | lower_bits},\ + {str "_animated", 0xA0 | lower_bits},\ + {str "_pressed", 0x90 | lower_bits} + + BUTTON("up", 0x00), + BUTTON("down", 0x01), + BUTTON("right", 0x02), + BUTTON("left", 0x03), + + BUTTON("r", 0x07), + BUTTON("l", 0x08), + BUTTON("start", 0x09), + + BUTTON("a", 0x0A), + BUTTON("b", 0x0B), + BUTTON("c", 0x0C), + + BUTTON("x", 0x0D), + BUTTON("y", 0x0E), + BUTTON("z", 0x0F), + +#undef BUTTON + }; + + string_.clear(); + string_.reserve(raw.size()); + + using std::size_t; + using std::string_view; + + for (;;) + { + size_t p = raw.find('<'); + + // Copy characters until the start tag + string_.append(raw.substr(0, p)); + + if (p == raw.npos) + { + break; // end of string + } + + raw.remove_prefix(p); + + // Find end tag + p = raw.find('>'); + + if (p == raw.npos) + { + break; // no end tag + } + + string_view code = raw.substr(1, p - 1); + + if (auto it = translation.find(code); it != translation.end()) + { + string_.push_back(it->second); // replace with character code + } + else + { + string_.append(raw.substr(0, p + 1)); // code not found, leave text verbatim + } + + raw.remove_prefix(p + 1); // past end of tag + } + + return *this; +} + void Chain::patch(patch_t* patch) const { const auto _ = Clipper(*this); diff --git a/src/v_draw.hpp b/src/v_draw.hpp index a3c0bf682..c21c3356b 100644 --- a/src/v_draw.hpp +++ b/src/v_draw.hpp @@ -11,6 +11,7 @@ #define __V_DRAW_HPP__ #include +#include #include #include @@ -97,6 +98,14 @@ public: return *this; } + TextElement& parse(std::string_view string); + + template + TextElement& parse(fmt::format_string format, Args&&... args) + { + return parse(fmt::format(format, args...)); + } + TextElement& font(Font font) { font_ = font;