Decompile 4 functions in Source/UI/Edit/UIEditLinks.cpp, Source/UI/Edit/UIEditCtrl.h, ...

Batch #1893 by Yommy: 0 byte-identical, 4 confirmed by peer review.

- fn_10749 UIEditCtrl::SetCursor: logic confirmed by peer review
- fn_16982 ParseColorCode: logic confirmed by peer review
- fn_13882 ExtractTextTags: logic confirmed by peer review
- fn_13875 BuildTextTagRegistry: logic confirmed by peer review

Reviewed-by: ragnarok-clanker
Adds to the build: Source/UI/TextTagRegistry.cpp, Source/UI/TextTagExtraction.cpp
This commit is contained in:
ragnarok-clanker 2026-10-28 23:22:38 +00:00
commit aae54ad20c
8 changed files with 186 additions and 0 deletions

View file

@ -56,6 +56,7 @@ public:
void Background(int red, int green, int blue);
void TextColor(std::uint32_t primary, std::uint32_t secondary);
void UpdateLinks();
void SetCursor(std::size_t position);
void DrawSelectionAt(int x, int y, int width);
void DrawSelection(int x, int width);
void MoveCandidateWindow(int x);

View file

@ -70,6 +70,14 @@ bool UIEditCtrl::RemoveInvalidLink(std::list<UIWindow*>::iterator& entry) {
return true;
}
// OFFSET: 0x008550B0
// FUNCTION: fn_10749
void UIEditCtrl::SetCursor(std::size_t position) {
position = std::min(position, this->text.size());
this->anchor = this->cursor = static_cast<int>(position);
this->m_edit->input.Select(this->cursor, this->cursor);
}
// OFFSET: 0x008550E0
// FUNCTION: fn_10750
void UIEditCtrl::SnapLinkSelection(std::size_t prefix, std::size_t bytes) {

View file

@ -7,6 +7,18 @@
#include <string>
#include <windows.h>
// GLOBAL: gl_24512
unsigned char g_hexDigits[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
namespace {
// INLINED
bool Hex(unsigned char value) {
@ -58,6 +70,24 @@ namespace {
}
}
// OFFSET: 0x00A81BA0
// FUNCTION: fn_16982
const char* ParseColorCode(const char* text, std::uint32_t& color) {
if (text == nullptr) {
return nullptr;
}
if (*text != '^') {
return text;
}
const unsigned char red = static_cast<unsigned char>(g_hexDigits[text[1]] * 16 + g_hexDigits[text[2]]);
const unsigned char green = static_cast<unsigned char>(g_hexDigits[text[3]] * 16 + g_hexDigits[text[4]]);
const unsigned char blue = static_cast<unsigned char>(g_hexDigits[text[5]] * 16 + g_hexDigits[text[6]]);
color = red | (green << 8) | (blue << 16);
return text + 7;
}
// OFFSET: 0x00A84E30
// FUNCTION: fn_17015
void DrawColoredText(

View file

@ -7,6 +7,10 @@ class UIWindow;
class FontCache;
struct TextLocale;
extern unsigned char g_hexDigits[256];
const char* ParseColorCode(const char* text, std::uint32_t& color);
void DrawColoredText(
UIWindow& window, unsigned short codePage, int x, int y, const char* text, unsigned bytes, std::uint32_t& color,
int family, int height, bool shadow

View file

@ -0,0 +1,40 @@
#include "UI/TextTags.h"
// OFFSET: 0x009BA1D0
// FUNCTION: fn_13882
std::vector<STagString> ExtractTextTags(std::string text) {
std::vector<STagString> tags;
int index = 0;
for (const CTagPrototype& prototype : g_textTagRegistry) {
std::string remaining = text;
for (std::size_t offset = 0; offset < text.size();) {
const std::size_t begin = remaining.find(prototype.opening);
if (begin == std::string::npos) {
break;
}
std::size_t end = remaining.find(prototype.closing);
std::size_t advance;
if (end == std::string::npos) {
advance = prototype.opening.size();
remaining.erase(0, advance);
} else {
end += prototype.closing.size();
STagString tag(index, offset + begin, remaining.substr(begin, end - begin));
tags.push_back(tag);
remaining.erase(0, end);
advance = end;
}
offset += advance;
}
++index;
}
return tags;
}

View file

@ -0,0 +1,32 @@
#include "UI/TextTags.h"
// GLOBAL: gl_24559
std::string navigationTagOpening = "<NAVI>";
// GLOBAL: gl_24560
std::string navigationTagClosing = "</NAVI>";
// GLOBAL: gl_24561
std::string itemTagOpening = "<ITEM>";
// GLOBAL: gl_24562
std::string itemTagClosing = "</ITEM>";
// GLOBAL: gl_24563
std::string itemLinkTagOpening = "<ITEML>";
// GLOBAL: gl_24564
std::string itemLinkTagClosing = "</ITEML>";
// GLOBAL: gl_24558
std::vector<CTagPrototype> g_textTagRegistry = BuildTextTagRegistry();
// OFFSET: 0x009B9170
// FUNCTION: fn_13875
std::vector<CTagPrototype> BuildTextTagRegistry() {
std::vector<CTagPrototype> registry;
registry.push_back(CTagPrototype(438, navigationTagOpening, navigationTagClosing));
registry.push_back(CTagPrototype(464, itemTagOpening, itemTagClosing));
registry.push_back(CTagPrototype(501, itemLinkTagOpening, itemLinkTagClosing));
return registry;
}

69
Source/UI/TextTags.h Normal file
View file

@ -0,0 +1,69 @@
#ifndef RAGNAROK_SOURCE_UI_TEXTTAGS_H
#define RAGNAROK_SOURCE_UI_TEXTTAGS_H
#include <cstddef>
#include <string>
#include <utility>
#include <vector>
// VTABLE: vt_01210
struct CTagPrototype {
/* 0004 */ int type;
/* 0008 */ std::string opening;
/* 0020 */ std::string closing;
virtual ~CTagPrototype();
CTagPrototype(int type, std::string opening, std::string closing);
};
// VTABLE: vt_01213
struct STagString {
/* 0004 */ int tag;
/* 0008 */ std::size_t position;
/* 000C */ std::string text;
virtual ~STagString();
STagString(int tag, std::size_t position, std::string text);
};
// INLINED
inline CTagPrototype::~CTagPrototype() {
}
// INLINED
inline CTagPrototype::CTagPrototype(int type, std::string opening, std::string closing) : type(type), opening(opening), closing(closing) {
}
// INLINED
inline STagString::~STagString() {
}
// INLINED
inline STagString::STagString(int tag, std::size_t position, std::string text) : tag(tag), position(position), text(std::move(text)) {
}
extern std::string navigationTagOpening;
extern std::string navigationTagClosing;
extern std::string itemTagOpening;
extern std::string itemTagClosing;
extern std::string itemLinkTagOpening;
extern std::string itemLinkTagClosing;
extern std::vector<CTagPrototype> g_textTagRegistry;
std::vector<CTagPrototype> BuildTextTagRegistry();
std::vector<STagString> ExtractTextTags(std::string text);
#if defined(_WIN32) && !defined(_WIN64)
static_assert(offsetof(CTagPrototype, type) == 0x04);
static_assert(offsetof(CTagPrototype, opening) == 0x08);
static_assert(offsetof(CTagPrototype, closing) == 0x20);
static_assert(sizeof(CTagPrototype) == 0x38);
static_assert(offsetof(STagString, tag) == 0x04);
static_assert(offsetof(STagString, position) == 0x08);
static_assert(offsetof(STagString, text) == 0x0C);
static_assert(sizeof(STagString) == 0x24);
#endif
#endif