From 99c6ecc2a45b468a2b425fa25466fdd66e653a99 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Sun, 30 Aug 2026 21:13:04 +0200 Subject: [PATCH 01/14] reimplement: SHC_3BB0A8C1_0x00469A30 100% --- .../setupFontSizeClassObject.cpp | 21 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/setupFontSizeClassObject.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/setupFontSizeClassObject.cpp b/src/OpenSHC/Text/FontSizeClass/setupFontSizeClassObject.cpp new file mode 100644 index 000000000..546054b66 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/setupFontSizeClassObject.cpp @@ -0,0 +1,21 @@ +#include "../FontSizeClass.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00469A30 + void FontSizeClass::setupFontSizeClassObject(GmID fontGmID, int numberOfFontStartInGm, FontRenderType renderType, + int baselineOffset, int lineHeight, int letterSpacing, int whiteSpaceWidth) + { + this->fontGmID_0x0 = fontGmID; + this->renderType_0xc = renderType; + this->baselineOffset_0x10 = baselineOffset; + this->lineHeight_0x14 = lineHeight; + this->letterSpacing_0x18 = letterSpacing; + this->whiteSpaceWidth_0x1c = whiteSpaceWidth; + this->numberOfFontStartInGm_0x4 = numberOfFontStartInGm; + this->fontStartImageId_0x8 = -1; + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index b80b8635f..6b57e7fe6 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -20149,7 +20149,7 @@ SHC_3BB0A8C1_0x00469980 | 0.0% | Pending SHC_3BB0A8C1_0x004699E0 | 0.0% | Pending -SHC_3BB0A8C1_0x00469A30 | 0.0% | Pending +SHC_3BB0A8C1_0x00469A30 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00469A70 | 0.0% | Pending From c45d662f1f27034f62ab5d6a5096095dedec4d48 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Mon, 31 Aug 2026 20:57:46 +0200 Subject: [PATCH 02/14] reimplement: SHC_3BB0A8C1_0x00469A70 100% --- .../Text/FontSizeClass/getWidthOfText.cpp | 72 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/getWidthOfText.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/getWidthOfText.cpp b/src/OpenSHC/Text/FontSizeClass/getWidthOfText.cpp new file mode 100644 index 000000000..878d5fb2f --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/getWidthOfText.cpp @@ -0,0 +1,72 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Globals/DAT_GMImageHeaders.hpp" +#include "OpenSHC/Globals/DAT_TextInputDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" +#include "OpenSHC/Globals/GMTotalPicturesProcessed.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00469A70 + int FontSizeClass::getWidthOfText(char* text, int length) + { + int _currentLineWidthUnk = 0; + int _maxSingleLineWidth = -1; + + int local_c = DAT_TextManagerObject::instance.field9_0x24; + if (DAT_TextManagerObject::instance.field9_0x24 <= DAT_TextManagerObject::instance.field10_0x28) { + local_c = DAT_TextManagerObject::instance.field10_0x28; + } + + int iVar1 = 0; + if (this->fontStartImageId_0x8 == -1) { + this->fontStartImageId_0x8 + = GMTotalPicturesProcessed::instance[this->fontGmID_0x0] + -1 + this->numberOfFontStartInGm_0x4; + } + + for (int _textIndex = 0; _textIndex < length; ++_textIndex) { + byte _char = text[_textIndex]; + + int imageID + = DAT_TextInputDefinedData::instance + .CharToImageSeqIDMapping[DAT_TextManagerObject::instance.alternativeCodePageUsedUnk][_char]; + if (imageID == -1) { + if (_char >= ' ') { + _currentLineWidthUnk += this->whiteSpaceWidth_0x1c; + } else if (_char == '\n' && _currentLineWidthUnk > _maxSingleLineWidth) { + _maxSingleLineWidth = _currentLineWidthUnk; + _currentLineWidthUnk = 0; + } + } else { + imageID += this->fontStartImageId_0x8; + if (local_c != 0) { + local_c = 0; + + if (this->lineHeight_0x14 == 27) { + iVar1 = 19; + } + + if (this->lineHeight_0x14 == 20) { + iVar1 = 20; + } + + if (iVar1 != 0) { + _currentLineWidthUnk += 3 + + DAT_GMImageHeaders::instance.imh[GMTotalPicturesProcessed::instance[156] + iVar1 - 1] + .width + - DAT_GMImageHeaders::instance.imh[imageID].width - this->letterSpacing_0x18; + } + } + _currentLineWidthUnk += DAT_GMImageHeaders::instance.imh[imageID].width + this->letterSpacing_0x18; + } + } + if (_currentLineWidthUnk <= _maxSingleLineWidth) { + _currentLineWidthUnk = _maxSingleLineWidth; + } + + return _currentLineWidthUnk; + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 6b57e7fe6..53b5c2f10 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -20151,7 +20151,7 @@ SHC_3BB0A8C1_0x004699E0 | 0.0% | Pending SHC_3BB0A8C1_0x00469A30 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00469A70 | 0.0% | Pending +SHC_3BB0A8C1_0x00469A70 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00469AD0 | 0.0% | Pending From 71eb962d8d71ffc6e8b4c21710ef0341b704344b Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Mon, 31 Aug 2026 21:28:41 +0200 Subject: [PATCH 03/14] reimplement: SHC_3BB0A8C1_0x00469B90 100% --- .../FontSizeClass/getWordStartingFromPos.cpp | 50 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/getWordStartingFromPos.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/getWordStartingFromPos.cpp b/src/OpenSHC/Text/FontSizeClass/getWordStartingFromPos.cpp new file mode 100644 index 000000000..7454adcf7 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/getWordStartingFromPos.cpp @@ -0,0 +1,50 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00469B90 + int FontSizeClass::getWordStartingFromPos( + char* text, int startAndRunIndex, char* wordReceiver, int maxWordBufferSize, int* wordStartIndexOutPtr) + { + if (!text || !wordReceiver || text[startAndRunIndex] == '\0') { + return 0; + } + + if (DAT_TextManagerObject::instance.field12_0x30) { + *wordReceiver = text[startAndRunIndex]; + wordReceiver[1] = '\0'; + *wordStartIndexOutPtr = 0; + return 1; + } + + int wordStartIndex = -1; + char _charHolder; + do { + _charHolder = text[startAndRunIndex]; + ++startAndRunIndex; + ++wordStartIndex; + if (_charHolder == '\0') { + return 0; + } + } while (_charHolder == ' '); + *wordStartIndexOutPtr = wordStartIndex; + *wordReceiver = _charHolder; + + int wordIndexAndLength; + for (wordIndexAndLength = 1; wordIndexAndLength < maxWordBufferSize; ++wordIndexAndLength) { + char currentChar = text[startAndRunIndex]; + ++startAndRunIndex; + if (currentChar == '\0' || currentChar == ' ') { + break; + } + wordReceiver[wordIndexAndLength] = currentChar; + } + wordReceiver[wordIndexAndLength] = '\0'; + return wordIndexAndLength; + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 53b5c2f10..ac8bd9428 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -20155,7 +20155,7 @@ SHC_3BB0A8C1_0x00469A70 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00469AD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00469B90 | 0.0% | Pending +SHC_3BB0A8C1_0x00469B90 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00469BE0 | 0.0% | Pending From 8f776e280c9e989e0a2089842177d254095ac38f Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:49:32 +0200 Subject: [PATCH 04/14] reimplement: SHC_3BB0A8C1_0x00469C40 100% --- .../Text/FontSizeClass/wrapTextIntoLines.cpp | 82 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/wrapTextIntoLines.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/wrapTextIntoLines.cpp b/src/OpenSHC/Text/FontSizeClass/wrapTextIntoLines.cpp new file mode 100644 index 000000000..1850979a0 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/wrapTextIntoLines.cpp @@ -0,0 +1,82 @@ +// disable deprecation warnings for strcpy +#pragma warning(disable : 4996) + +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/OS.func.hpp" +#include "OpenSHC/string-literals.hpp" + +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00469C40 + void FontSizeClass::wrapTextIntoLines(char* text, int allowedWidth) + { + int const _textLength = strlen(text); + int const _textWidth + = MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::getWidthOfText, this)(text, _textLength); + int currentIndexInLine = 0; + int wordCutIndex = 0; + int currentWidthOfLine = 0; + int wordsInLine = 0; + int const whiteSpaceWidth = this->whiteSpaceWidth_0x1c; + int lineIndex = 0; + + DAT_TextManagerObject::instance.count1 = 0; + if (_textLength <= 0) { + return; + } + + if (_textWidth <= allowedWidth && _textLength <= 127) { + strcpy(DAT_TextManagerObject::instance.stringArray1[0], text); + DAT_TextManagerObject::instance.count1 = 1; + } else if (_textWidth > allowedWidth) { + do { + char _wordReceiver[64]; + int _wordStartIndex; + int _wordLengthWithoutNull + = MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::getWordStartingFromPos, this)( + text, wordCutIndex, _wordReceiver, sizeof(_wordReceiver) - 1, &_wordStartIndex); + + if (_wordLengthWithoutNull == 0) + break; + + wordCutIndex += _wordStartIndex + _wordLengthWithoutNull; + int _wordWidth = MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::getWidthOfText, this)( + _wordReceiver, _wordLengthWithoutNull); + + if (_wordWidth > allowedWidth) { + DAT_TextManagerObject::instance.count1 = 0; + return; + } + + if (_wordWidth + currentWidthOfLine > allowedWidth && wordsInLine) { + DAT_TextManagerObject::instance.stringArray1[lineIndex][currentIndexInLine] = '\0'; + ++lineIndex; + + currentWidthOfLine = 0; + wordsInLine = 0; + if (32 <= lineIndex) { + lineIndex = 31; + break; + } + currentIndexInLine = 0; + } + + MACRO_CALL(OpenSHC::OS_Func::_sprintf)( + &DAT_TextManagerObject::instance.stringArray1[lineIndex][currentIndexInLine], s__s_005a5a08, + _wordReceiver); + + ++wordsInLine; + currentWidthOfLine += _wordWidth + whiteSpaceWidth; // printf adds "%s " + currentIndexInLine += 1 + _wordLengthWithoutNull; // printf adds "%s " + } while (wordCutIndex < _textLength); + DAT_TextManagerObject::instance.stringArray1[lineIndex][currentIndexInLine] = '\0'; + DAT_TextManagerObject::instance.count1 = lineIndex + 1; + } + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index ac8bd9428..3c1c5fef3 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -20159,7 +20159,7 @@ SHC_3BB0A8C1_0x00469B90 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00469BE0 | 0.0% | Pending -SHC_3BB0A8C1_0x00469C40 | 0.0% | Pending +SHC_3BB0A8C1_0x00469C40 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00469E10 | 0.0% | Pending From dc89ad360b24861a6fd6409b28d4f103e22d5185 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:56:42 +0200 Subject: [PATCH 05/14] reimplement: SHC_3BB0A8C1_0x00469E10 100% --- .../Text/FontSizeClass/getCharWidthUnk.cpp | 36 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/getCharWidthUnk.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/getCharWidthUnk.cpp b/src/OpenSHC/Text/FontSizeClass/getCharWidthUnk.cpp new file mode 100644 index 000000000..61f7b9d58 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/getCharWidthUnk.cpp @@ -0,0 +1,36 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Globals/DAT_GMImageHeaders.hpp" +#include "OpenSHC/Globals/DAT_TextInputDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" +#include "OpenSHC/Globals/GMTotalPicturesProcessed.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00469E10 + int FontSizeClass::getCharWidthUnk(byte charUnk) + { + int _width = 0; + if (this->fontStartImageId_0x8 == -1) { + this->fontStartImageId_0x8 + = GMTotalPicturesProcessed::instance[this->fontGmID_0x0] + this->numberOfFontStartInGm_0x4 - 1; + } + + int const imageSeqID + = DAT_TextInputDefinedData::instance + .CharToImageSeqIDMapping[DAT_TextManagerObject::instance.alternativeCodePageUsedUnk][charUnk]; + + if (imageSeqID == -1) { + if (charUnk >= ' ') { + return this->whiteSpaceWidth_0x1c; + } + } else { + _width = DAT_GMImageHeaders::instance.imh[this->fontStartImageId_0x8 + imageSeqID].width + + this->letterSpacing_0x18; + } + return _width; + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 3c1c5fef3..8cd84a7da 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -20161,7 +20161,7 @@ SHC_3BB0A8C1_0x00469BE0 | 0.0% | Pending SHC_3BB0A8C1_0x00469C40 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00469E10 | 0.0% | Pending +SHC_3BB0A8C1_0x00469E10 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00469E70 | 0.0% | Pending From 583d4feb70bac3ce5da465f660601e2580e85ab3 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:01:18 +0200 Subject: [PATCH 06/14] reimplement: SHC_3BB0A8C1_0x00471610 100% --- .../Text/FontSizeClass/getWidthOfWideText.cpp | 20 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/getWidthOfWideText.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/getWidthOfWideText.cpp b/src/OpenSHC/Text/FontSizeClass/getWidthOfWideText.cpp new file mode 100644 index 000000000..b15dc7589 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/getWidthOfWideText.cpp @@ -0,0 +1,20 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00471610 + int FontSizeClass::getWidthOfWideText(LPWSTR wideText, int numberOfChars) + { + CHAR _charStringBuffer[3000]; + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::wideCharToMultiByteWithSize, + DAT_WideCharMultiByteState::ptr)(_charStringBuffer, wideText, numberOfChars); + return MACRO_CALL_MEMBER(FontSizeClass_Func::getWidthOfText, this)(_charStringBuffer, numberOfChars); + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 8cd84a7da..3d4a1afd1 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21293,7 +21293,7 @@ SHC_3BB0A8C1_0x00471570 | 0.0% | Pending SHC_3BB0A8C1_0x004715A0 | 0.0% | Pending -SHC_3BB0A8C1_0x00471610 | 0.0% | Pending +SHC_3BB0A8C1_0x00471610 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00471670 | 0.0% | Pending From 77452e1ba6c48f6c512307bf60ab3fa684414202 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Tue, 1 Sep 2026 21:05:31 +0200 Subject: [PATCH 07/14] reimplement: SHC_3BB0A8C1_0x00471670 100% --- .../Text/FontSizeClass/getWideCharWidth.cpp | 18 ++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp b/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp new file mode 100644 index 000000000..0adf26e2b --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp @@ -0,0 +1,18 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00471670 + dword FontSizeClass::getWideCharWidth(WCHAR wChar) + { + return MACRO_CALL_MEMBER(FontSizeClass_Func::getCharWidthUnk, this)(MACRO_CALL_MEMBER( + Util::WideCharMultiByteState_Func::wideCharToByteUnk, DAT_WideCharMultiByteState::ptr)(wChar)); + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 3d4a1afd1..bd7755376 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21295,7 +21295,7 @@ SHC_3BB0A8C1_0x004715A0 | 0.0% | Pending SHC_3BB0A8C1_0x00471610 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00471670 | 0.0% | Pending +SHC_3BB0A8C1_0x00471670 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00471690 | 0.0% | Pending From a06865eb7282e01b2cb35b91b33640eaf17f7582 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Tue, 1 Sep 2026 22:09:31 +0200 Subject: [PATCH 08/14] reimplement: SHC_3BB0A8C1_0x00472D60 100% --- src/OpenSHC/Text/FontSizeClass/renderText.cpp | 85 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/renderText.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/renderText.cpp b/src/OpenSHC/Text/FontSizeClass/renderText.cpp new file mode 100644 index 000000000..da46924a5 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderText.cpp @@ -0,0 +1,85 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/UI/Rendering/PencilRenderCore.func.hpp" +#include "OpenSHC/UI/Rendering/TextureRenderCore.func.hpp" + +#include "OpenSHC/Globals/DAT_GMImageHeaders.hpp" +#include "OpenSHC/Globals/DAT_PencilRenderCore.hpp" +#include "OpenSHC/Globals/DAT_TextInputDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" +#include "OpenSHC/Globals/GMTotalPicturesProcessed.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00472D60 + int FontSizeClass::renderText(char* text, int textLength, int xPos, int yPos, BGR24 color, int blendStrength) + { + int _xPos = xPos; + int _yPos = yPos; + + Rendering::Colors::RGB15 const fillColor + = MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::transformBGR24ToScreenColor, + DAT_TextureRenderCoreObject::ptr)(color); + Rendering::Enums::RenderTarget const _drawBufferTempUnk + = (Rendering::Enums::RenderTarget)DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue; + + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = DAT_TextManagerObject::instance.textSurfaceTarget; + + if (this->fontStartImageId_0x8 == -1) { + this->fontStartImageId_0x8 + = GMTotalPicturesProcessed::instance[this->fontGmID_0x0] + this->numberOfFontStartInGm_0x4 - 1; + } + + for (int i = 0; i < textLength; ++i) { + byte const currentChar = text[i]; + + int imageSeqId + = DAT_TextInputDefinedData::instance + .CharToImageSeqIDMapping[DAT_TextManagerObject::instance.alternativeCodePageUsedUnk][currentChar]; + + if (_xPos + this->whiteSpaceWidth_0x1c * 5 > DAT_TextManagerObject::instance.field2_0x8 + && _xPos < DAT_TextManagerObject::instance.field3_0xc) { + + if (imageSeqId == -1) { + if (currentChar >= ' ') { + if (DAT_TextManagerObject::instance.field6_0x18) { + int const lineY = this->baselineOffset_0x10 + _yPos + 2; + MACRO_CALL_MEMBER( + UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + _xPos, lineY, _xPos + this->whiteSpaceWidth_0x1c, lineY, fillColor); + } + _xPos += this->whiteSpaceWidth_0x1c; + } else if (currentChar == '\n') { + _yPos += this->baselineOffset_0x10 / 3 + this->baselineOffset_0x10; + _xPos = xPos; + } + + } else { + imageSeqId += this->fontStartImageId_0x8; + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::renderTextChar, + DAT_TextureRenderCoreObject::ptr)(_xPos, this->baselineOffset_0x10 + _yPos, imageSeqId, + (FontRenderType)this->renderType_0xc, this->lineHeight_0x14, fillColor, blendStrength); + _xPos += DAT_GMImageHeaders::instance.imh[imageSeqId].width + this->letterSpacing_0x18 + + DAT_TextureRenderCoreObject::instance.mbr_0x6c; + } + } else if (imageSeqId == -1) { + if (currentChar >= ' ') { + _xPos += this->whiteSpaceWidth_0x1c; + } else if (currentChar == '\n') { + _yPos += this->baselineOffset_0x10 / 3 + this->baselineOffset_0x10; + _xPos = xPos; + } + } else { + _xPos += DAT_GMImageHeaders::instance.imh[this->fontStartImageId_0x8 + imageSeqId].width + + this->letterSpacing_0x18; + } + } + + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = _drawBufferTempUnk; + return _xPos; + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index bd7755376..023013af0 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21429,7 +21429,7 @@ SHC_3BB0A8C1_0x00472CB0 | 0.0% | Pending SHC_3BB0A8C1_0x00472D00 | 0.0% | Pending -SHC_3BB0A8C1_0x00472D60 | 0.0% | Pending +SHC_3BB0A8C1_0x00472D60 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00472DD0 | 0.0% | Pending From 7da7e54697058bfcbacebf32a74ea48bee5c0894 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Thu, 3 Sep 2026 23:56:33 +0200 Subject: [PATCH 09/14] reimplement: SHC_3BB0A8C1_0x00472EF0 severe issues --- .../FontSizeClass/renderMultilineTextUnk.cpp | 179 ++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp new file mode 100644 index 000000000..9abc93a6b --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp @@ -0,0 +1,179 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00472EF0 + int FontSizeClass::renderMultilineTextUnk( + char* text, int xPos, int yPos, int maxWidth, BGR24 color, int blendStrength, int modeUnk) + { + int _textLength = strlen(text); + int _widthOfWholeText = MACRO_CALL_MEMBER(FontSizeClass_Func::getWidthOfText, this)(text, _textLength); + + int _runXPos = xPos; + int _runYPos = yPos; + + int const maxXPosition = maxWidth + xPos; + + int finalTextWidth = 0; + int _nextWordCutStartIndex = 0; + int writtenWords = 0; + int local_68 = 0; + + int whiteSpaceWidth = this->whiteSpaceWidth_0x1c; + int singleLineHeight = (this->lineHeight_0x14 * 38) / 32; + int yLineOffset = singleLineHeight; + + if (DAT_TextManagerObject::instance.field13_0x34 != 0) { + singleLineHeight = DAT_TextManagerObject::instance.field13_0x34; + } + + if (DAT_TextManagerObject::instance.field12_0x30) { + whiteSpaceWidth = 0; + } + + DAT_TextManagerObject::instance.field1_0x4 = 0; + if (_textLength <= 0) { + return 0; + } + + if (_widthOfWholeText <= maxWidth) { + DAT_TextManagerObject::instance.field1_0x4 = singleLineHeight; + if (modeUnk == 0) { + MACRO_CALL_MEMBER(FontSizeClass_Func::renderText, this)( + text, _textLength, _runXPos, _runYPos, color, blendStrength); + return _widthOfWholeText; + } else if (modeUnk == 1) { + return yLineOffset; + } else if (modeUnk == 2) { + return _widthOfWholeText; + } + } + + do { + char _wordReceiver[64]; + int _wordStartIndex; + int wordLength = MACRO_CALL_MEMBER(FontSizeClass_Func::getWordStartingFromPos, this)( + text, _nextWordCutStartIndex, _wordReceiver, sizeof(_wordReceiver) - 1, &_wordStartIndex); + if (!wordLength) { + break; + } + _nextWordCutStartIndex += _wordStartIndex + wordLength; + int _wordWidth = MACRO_CALL_MEMBER(FontSizeClass_Func::getWidthOfText, this)(_wordReceiver, wordLength); + if (_wordWidth > maxWidth) { + int maxXPositionWithLineSep + = maxXPosition - MACRO_CALL_MEMBER(FontSizeClass_Func::getCharWidthUnk, this)('-'); + + int renderedChars = 0; + do { + int remainingWidth = maxXPositionWithLineSep - _runXPos; + int wordReceiverBufferLength = strlen(_wordReceiver) + 1; + int length = 1; + for (; length < wordReceiverBufferLength; ++length) { + if (MACRO_CALL_MEMBER(FontSizeClass_Func::getWidthOfText, this)(_wordReceiver, length) + > remainingWidth) { + break; + } + } + --length; + + if (length < 1) { + if (writtenWords == 0) { + break; + } + } else { + + int iVar1 = MACRO_CALL_MEMBER(FontSizeClass_Func::getWidthOfText, this)(_wordReceiver, length); + + if (modeUnk == 0) { + MACRO_CALL_MEMBER(FontSizeClass_Func::renderText, this)( + _wordReceiver, length, _runXPos, _runYPos, color, blendStrength); + } + + renderedChars += length; + _runXPos += iVar1; + + if (renderedChars >= wordLength) { + break; + } + + if (modeUnk == 0) { + MACRO_CALL_MEMBER(FontSizeClass_Func::renderText, this)( + "-", sizeof(char), _runXPos, _runYPos, color, blendStrength); + } + + for (int i = 0; i < (int)sizeof(_wordReceiver); ++i) { + _wordReceiver[i] = _wordReceiver[length + i]; + if (_wordReceiver[i] == '\0') { + break; + } + } + } + + if (_runXPos - xPos > finalTextWidth) { + finalTextWidth = _runXPos - xPos; + } + _runXPos = xPos; + + _runYPos += singleLineHeight; + yLineOffset += singleLineHeight; + writtenWords = 0; + + if (DAT_TextManagerObject::instance.field12_0x30) { + local_68 = 1; + } + } while (renderedChars < wordLength && local_68 == 0); + ++writtenWords; + _runXPos += whiteSpaceWidth; + continue; + } + + if (_wordWidth + _runXPos > maxXPosition && writtenWords != 0) { + int possibleWidth = _runXPos - xPos; + if (possibleWidth > finalTextWidth) { + finalTextWidth = possibleWidth; + } + + _runYPos += singleLineHeight; + yLineOffset += singleLineHeight; + + writtenWords = 0; + + _runXPos = xPos; + + DAT_TextManagerObject::instance.field1_0x4 += singleLineHeight; + if (DAT_TextManagerObject::instance.field12_0x30) { + break; + } + } + + if (modeUnk == 0) { + MACRO_CALL_MEMBER(FontSizeClass_Func::renderText, this)( + _wordReceiver, wordLength, _runXPos, _runYPos, color, blendStrength); + } + + ++writtenWords; + _runXPos += _wordWidth + whiteSpaceWidth; + } while (_nextWordCutStartIndex < _textLength && local_68 == 0); + + if (_runXPos - xPos > finalTextWidth) { + finalTextWidth = _runXPos - xPos; + } + + if (writtenWords != 0) { + DAT_TextManagerObject::instance.field1_0x4 += singleLineHeight; + } + + if (modeUnk == 1) { + if (writtenWords == 0) { + yLineOffset -= singleLineHeight; + } + return yLineOffset; + } + return finalTextWidth; + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 023013af0..b52abe50a 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21433,7 +21433,7 @@ SHC_3BB0A8C1_0x00472D60 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00472DD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00472EF0 | 0.0% | Pending +SHC_3BB0A8C1_0x00472EF0 | 54.0% | Severe Register Issues, seem functional, but can not be considered done SHC_3BB0A8C1_0x00473300 | 0.0% | Pending From 54ab45e2f4fe1f4a8c8df9aad35dd975e36b80fb Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Sat, 5 Sep 2026 03:07:43 +0200 Subject: [PATCH 10/14] reimplement: SHC_3BB0A8C1_0x00472EF0 55.0% --- .../FontSizeClass/renderMultilineTextUnk.cpp | 26 +++++++++---------- src/core/Resolver.cpp | 12 ++++----- status/addresses-SHC-3BB0A8C1.txt | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp index 9abc93a6b..e40d0c202 100644 --- a/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp +++ b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp @@ -22,12 +22,13 @@ namespace Text { int writtenWords = 0; int local_68 = 0; - int whiteSpaceWidth = this->whiteSpaceWidth_0x1c; int singleLineHeight = (this->lineHeight_0x14 * 38) / 32; int yLineOffset = singleLineHeight; + int whiteSpaceWidth = this->whiteSpaceWidth_0x1c; - if (DAT_TextManagerObject::instance.field13_0x34 != 0) { - singleLineHeight = DAT_TextManagerObject::instance.field13_0x34; + int alternateLineHeight = DAT_TextManagerObject::instance.field13_0x34; + if (alternateLineHeight) { + singleLineHeight = alternateLineHeight; } if (DAT_TextManagerObject::instance.field12_0x30) { @@ -63,12 +64,11 @@ namespace Text { _nextWordCutStartIndex += _wordStartIndex + wordLength; int _wordWidth = MACRO_CALL_MEMBER(FontSizeClass_Func::getWidthOfText, this)(_wordReceiver, wordLength); if (_wordWidth > maxWidth) { - int maxXPositionWithLineSep - = maxXPosition - MACRO_CALL_MEMBER(FontSizeClass_Func::getCharWidthUnk, this)('-'); + int charWidth = MACRO_CALL_MEMBER(FontSizeClass_Func::getCharWidthUnk, this)('-'); int renderedChars = 0; do { - int remainingWidth = maxXPositionWithLineSep - _runXPos; + int remainingWidth = maxXPosition - charWidth - _runXPos; int wordReceiverBufferLength = strlen(_wordReceiver) + 1; int length = 1; for (; length < wordReceiverBufferLength; ++length) { @@ -112,8 +112,9 @@ namespace Text { } } - if (_runXPos - xPos > finalTextWidth) { - finalTextWidth = _runXPos - xPos; + int possibleWidth = _runXPos - xPos; + if (possibleWidth > finalTextWidth) { + finalTextWidth = possibleWidth; } _runXPos = xPos; @@ -135,14 +136,12 @@ namespace Text { if (possibleWidth > finalTextWidth) { finalTextWidth = possibleWidth; } + _runXPos = xPos; _runYPos += singleLineHeight; yLineOffset += singleLineHeight; - writtenWords = 0; - _runXPos = xPos; - DAT_TextManagerObject::instance.field1_0x4 += singleLineHeight; if (DAT_TextManagerObject::instance.field12_0x30) { break; @@ -158,8 +157,9 @@ namespace Text { _runXPos += _wordWidth + whiteSpaceWidth; } while (_nextWordCutStartIndex < _textLength && local_68 == 0); - if (_runXPos - xPos > finalTextWidth) { - finalTextWidth = _runXPos - xPos; + int possibleWidth = _runXPos - xPos; + if (possibleWidth > finalTextWidth) { + finalTextWidth = possibleWidth; } if (writtenWords != 0) { diff --git a/src/core/Resolver.cpp b/src/core/Resolver.cpp index f2035487b..7d87714af 100644 --- a/src/core/Resolver.cpp +++ b/src/core/Resolver.cpp @@ -14,8 +14,8 @@ static void createRelativeJump(int from, int to) DWORD oldProtection; if (!VirtualProtect((void*)from, instructionLength, PAGE_EXECUTE_READWRITE, &oldProtection)) { std::ostringstream oss; - oss << "Error while trying to remove memory protection to create relative jump from '" << from << "' to '" << to - << "': " << GetLastError(); + oss << "Error while trying to remove memory protection to create relative jump from '" << (void*)from + << "' to '" << (void*)to << "': " << GetLastError(); ucp_log(Verbosity_FATAL, oss.str().c_str()); } @@ -26,8 +26,8 @@ static void createRelativeJump(int from, int to) DWORD dummyProtection; if (!VirtualProtect((void*)from, instructionLength, oldProtection, &dummyProtection)) { std::ostringstream oss; - oss << "Error while trying to re-enable memory protection after creating relative jump from '" << from - << "' to '" << to << "': " << GetLastError(); + oss << "Error while trying to re-enable memory protection after creating relative jump from '" << (void*)from + << "' to '" << (void*)to << "': " << GetLastError(); ucp_log(Verbosity_FATAL, oss.str().c_str()); } } @@ -44,7 +44,7 @@ void StructResolver::initialize( #ifdef OPEN_SHC_DLL std::ostringstream oss; - oss << "Abort execution, since address '" << gameAddress << "' was resolved more then once."; + oss << "Abort execution, since address '" << (void*)gameAddress << "' was resolved more then once."; ucp_log(Verbosity_FATAL, oss.str().c_str()); #endif return; @@ -75,7 +75,7 @@ void FunctionResolver::initialize( #ifdef OPEN_SHC_DLL std::ostringstream oss; - oss << "Abort execution, since address '" << gameAddress << "' was resolved more then once."; + oss << "Abort execution, since address '" << (void*)gameAddress << "' was resolved more then once."; ucp_log(Verbosity_FATAL, oss.str().c_str()); #endif return; diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index b52abe50a..dd99bc10c 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21433,7 +21433,7 @@ SHC_3BB0A8C1_0x00472D60 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00472DD0 | 0.0% | Pending -SHC_3BB0A8C1_0x00472EF0 | 54.0% | Severe Register Issues, seem functional, but can not be considered done +SHC_3BB0A8C1_0x00472EF0 | 55.0% | Severe Register Issues, seem functional, but can not be considered done SHC_3BB0A8C1_0x00473300 | 0.0% | Pending From 2c0d0442d12ff80fa1a72e764c0d507d36affd96 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Sat, 5 Sep 2026 21:34:07 +0200 Subject: [PATCH 11/14] reimplement: SHC_3BB0A8C1_0x00473300 and SHC_3BB0A8C1_0x004733A0 100% --- .../FontSizeClass/renderMultilineTextUnk.cpp | 7 +- .../renderMultilineWideTextUnk.cpp | 22 +++++ .../renderSomeSpecificTextUnk.cpp | 84 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 4 +- 4 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/renderMultilineWideTextUnk.cpp create mode 100644 src/OpenSHC/Text/FontSizeClass/renderSomeSpecificTextUnk.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp index e40d0c202..8f3acbd7e 100644 --- a/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp +++ b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp @@ -15,14 +15,15 @@ namespace Text { int _runXPos = xPos; int _runYPos = yPos; - int const maxXPosition = maxWidth + xPos; + int maxXPosition = xPos + maxWidth; int finalTextWidth = 0; int _nextWordCutStartIndex = 0; int writtenWords = 0; int local_68 = 0; + int _wordWidth = 0; - int singleLineHeight = (this->lineHeight_0x14 * 38) / 32; + int singleLineHeight = (this->lineHeight_0x14 * 38) >> 5; int yLineOffset = singleLineHeight; int whiteSpaceWidth = this->whiteSpaceWidth_0x1c; @@ -41,7 +42,7 @@ namespace Text { } if (_widthOfWholeText <= maxWidth) { - DAT_TextManagerObject::instance.field1_0x4 = singleLineHeight; + DAT_TextManagerObject::instance.field1_0x4 += singleLineHeight; if (modeUnk == 0) { MACRO_CALL_MEMBER(FontSizeClass_Func::renderText, this)( text, _textLength, _runXPos, _runYPos, color, blendStrength); diff --git a/src/OpenSHC/Text/FontSizeClass/renderMultilineWideTextUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderMultilineWideTextUnk.cpp new file mode 100644 index 000000000..0dbc2e982 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderMultilineWideTextUnk.cpp @@ -0,0 +1,22 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00473300 + int FontSizeClass::renderMultilineWideTextUnk( + LPWSTR _wideText, int xPos, int yPos, int maxWidth, uint color, int blendStrength, int modeUnk) + { + CHAR _convertedText[3000]; + MACRO_CALL_MEMBER(OpenSHC::Util::WideCharMultiByteState_Func::wideCharToMultiByteWithSize, + DAT_WideCharMultiByteState::ptr)(_convertedText, _wideText, wcslen(_wideText)); + return MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderMultilineTextUnk, this)( + _convertedText, xPos, yPos, maxWidth, color, blendStrength, modeUnk); + } + +} +} diff --git a/src/OpenSHC/Text/FontSizeClass/renderSomeSpecificTextUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderSomeSpecificTextUnk.cpp new file mode 100644 index 000000000..f8c11cf2b --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderSomeSpecificTextUnk.cpp @@ -0,0 +1,84 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/OS.func.hpp" + +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x004733A0 + void FontSizeClass::renderSomeSpecificTextUnk( + int lengthUnk, int otherBlendValueUnk, int xPos, int yPos, BGR24 color) + { + char strBuffer[128]; + + int _runXPos = xPos; + int _runYPos = yPos; + + int lineHeight = (this->lineHeight_0x14 * 38) >> 5; + int blendValue = (otherBlendValueUnk * 32) / 100; + + if (1 > DAT_TextManagerObject::instance.count1 || DAT_TextManagerObject::instance.count1 > 32 + || lengthUnk < 1) { + return; + } + + if (DAT_TextManagerObject::instance.count1 == 1) { + int lengthStr = strlen(DAT_TextManagerObject::instance.stringArray1[0]); + if (1 <= lengthStr) { + if (lengthUnk > lengthStr) { + MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderText, this)( + DAT_TextManagerObject::instance.stringArray1[0], lengthStr, _runXPos, yPos, color, 0); + } else { + if (0 < lengthUnk - 1) { + MACRO_CALL(OpenSHC::OS_Func::_memcpy)( + strBuffer, DAT_TextManagerObject::instance.stringArray1[0], lengthStr); + strBuffer[lengthUnk - 1] = '\0'; + MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderText, this)( + strBuffer, lengthUnk - 1, _runXPos, yPos, color, 0); + _runXPos = MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::getWidthOfText, this)( + strBuffer, lengthUnk - 1); + _runXPos += xPos; + } + strBuffer[0] = DAT_TextManagerObject::instance.stringArray1[0][lengthUnk - 1]; + strBuffer[1] = '\0'; + MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderText, this)( + strBuffer, 1, _runXPos, yPos, color, blendValue); + } + } + } else { + for (int _index = 0; _index < (int)DAT_TextManagerObject::instance.count1; ++_index) { + int lengthStr = strlen(DAT_TextManagerObject::instance.stringArray1[_index]); + if (lengthStr < 1) { + break; + } + + if (lengthUnk > lengthStr) { + MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderText, this)( + DAT_TextManagerObject::instance.stringArray1[_index], lengthStr, xPos, _runYPos, color, 0); + _runYPos += lineHeight; + lengthUnk -= lengthStr; + continue; + } + + if (0 < lengthUnk + -1) { + MACRO_CALL(OpenSHC::OS_Func::_memcpy)( + strBuffer, DAT_TextManagerObject::instance.stringArray1[_index], lengthStr); + strBuffer[lengthUnk + -1] = '\0'; + MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderText, this)( + strBuffer, lengthUnk + -1, xPos, _runYPos, color, 0); + _runXPos = MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::getWidthOfText, this)( + strBuffer, lengthUnk + -1); + _runXPos += xPos; + } + strBuffer[0] = DAT_TextManagerObject::instance.stringArray1[_index][lengthUnk - 1]; + strBuffer[1] = '\0'; + MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderText, this)( + strBuffer, 1, _runXPos, _runYPos, color, blendValue); + break; + } + } + } +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index dd99bc10c..752bd20de 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21435,9 +21435,9 @@ SHC_3BB0A8C1_0x00472DD0 | 0.0% | Pending SHC_3BB0A8C1_0x00472EF0 | 55.0% | Severe Register Issues, seem functional, but can not be considered done -SHC_3BB0A8C1_0x00473300 | 0.0% | Pending +SHC_3BB0A8C1_0x00473300 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004733A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004733A0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00473640 | 0.0% | Pending From a8f3b54afa2001a60ce9999de88343477fa3c253 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Sun, 6 Sep 2026 00:50:31 +0200 Subject: [PATCH 12/14] reimplement: SHC_3BB0A8C1_0x00473640 100% --- .../Text/FontSizeClass/renderCharUnk.cpp | 74 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/renderCharUnk.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/renderCharUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderCharUnk.cpp new file mode 100644 index 000000000..b3a28d592 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderCharUnk.cpp @@ -0,0 +1,74 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/UI/Rendering/PencilRenderCore.func.hpp" +#include "OpenSHC/UI/Rendering/TextureRenderCore.func.hpp" + +#include "OpenSHC/Globals/DAT_GMImageHeaders.hpp" +#include "OpenSHC/Globals/DAT_PencilRenderCore.hpp" +#include "OpenSHC/Globals/DAT_TextInputDefinedData.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" +#include "OpenSHC/Globals/GMTotalPicturesProcessed.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00473640 + int FontSizeClass::renderCharUnk(byte charId, int xPos, int yPosUnk, int bgr24, int blendStrengthUnk) + { + int _xPos = xPos; + int _yPos = yPosUnk; + + Rendering::Enums::RenderTarget renderTargetTemp + = (Rendering::Enums::RenderTarget)DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue; + + Rendering::Colors::RGB15 const _fillColorUnk + = MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::transformBGR24ToScreenColor, + DAT_TextureRenderCoreObject::ptr)(bgr24); + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = DAT_TextManagerObject::instance.textSurfaceTarget; + + if (this->fontStartImageId_0x8 == -1) { + this->fontStartImageId_0x8 + = GMTotalPicturesProcessed::instance[this->fontGmID_0x0] + this->numberOfFontStartInGm_0x4 - 1; + } + + int imageSeqID + = DAT_TextInputDefinedData::instance + .CharToImageSeqIDMapping[DAT_TextManagerObject::instance.alternativeCodePageUsedUnk][charId]; + + if (_xPos + this->whiteSpaceWidth_0x1c * 5 > DAT_TextManagerObject::instance.field2_0x8 + && _xPos < DAT_TextManagerObject::instance.field3_0xc) { + + if (imageSeqID == -1) { + if (charId >= ' ') { + if (DAT_TextManagerObject::instance.field6_0x18 != 0) { + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + _xPos, this->baselineOffset_0x10 + 2 + _yPos, this->whiteSpaceWidth_0x1c + _xPos, + this->baselineOffset_0x10 + 2 + _yPos, _fillColorUnk); + } + _xPos += this->whiteSpaceWidth_0x1c; + } + } else { + imageSeqID += this->fontStartImageId_0x8; + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::renderTextChar, + DAT_TextureRenderCoreObject::ptr)(_xPos, _yPos + this->baselineOffset_0x10, imageSeqID, + (FontRenderType)this->renderType_0xc, this->lineHeight_0x14, _fillColorUnk, blendStrengthUnk); + _xPos += DAT_GMImageHeaders::instance.imh[imageSeqID].width + this->letterSpacing_0x18 + + DAT_TextureRenderCoreObject::instance.mbr_0x6c; + } + } else { + if (imageSeqID == -1) { + if (charId >= ' ') { + _xPos += this->whiteSpaceWidth_0x1c; + } + } else { + imageSeqID += this->fontStartImageId_0x8; + _xPos += DAT_GMImageHeaders::instance.imh[imageSeqID].width + this->letterSpacing_0x18; + } + } + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = renderTargetTemp; + return _xPos; + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 752bd20de..fd11d255f 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21439,7 +21439,7 @@ SHC_3BB0A8C1_0x00473300 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004733A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00473640 | 0.0% | Pending +SHC_3BB0A8C1_0x00473640 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004737B0 | 0.0% | Pending From 571fc392e1e7b41d005375c7241f4a1e96333957 Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Sun, 6 Sep 2026 01:02:06 +0200 Subject: [PATCH 13/14] reimplement: SHC_3BB0A8C1_0x004737B0 and SHC_3BB0A8C1_0x00473830 100% --- .../Text/FontSizeClass/renderWideChar.cpp | 20 +++++++++++++++++ .../Text/FontSizeClass/renderWideText.cpp | 22 +++++++++++++++++++ status/addresses-SHC-3BB0A8C1.txt | 4 ++-- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp create mode 100644 src/OpenSHC/Text/FontSizeClass/renderWideText.cpp diff --git a/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp b/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp new file mode 100644 index 000000000..fef028227 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp @@ -0,0 +1,20 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00473830 + int FontSizeClass::renderWideChar(WCHAR wideChar, int xPos, int yPos, int bgr24, int blendStrengthUnk) + { + return MACRO_CALL_MEMBER(FontSizeClass_Func::renderCharUnk, this)( + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::wideCharToByteUnk, DAT_WideCharMultiByteState::ptr)( + wideChar), + xPos, yPos, bgr24, blendStrengthUnk); + } + +} +} diff --git a/src/OpenSHC/Text/FontSizeClass/renderWideText.cpp b/src/OpenSHC/Text/FontSizeClass/renderWideText.cpp new file mode 100644 index 000000000..46bf7e690 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderWideText.cpp @@ -0,0 +1,22 @@ +#include "../FontSizeClass.func.hpp" + +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x004737B0 + int FontSizeClass::renderWideText( + LPWSTR wideText, int textLength, int xPos, int yPos, BGR24 color, int blendStrength) + { + CHAR _text[3000]; + MACRO_CALL_MEMBER(OpenSHC::Util::WideCharMultiByteState_Func::wideCharToMultiByteWithSize, + DAT_WideCharMultiByteState::ptr)(_text, wideText, textLength); + return MACRO_CALL_MEMBER(OpenSHC::Text::FontSizeClass_Func::renderText, this)( + _text, textLength, xPos, yPos, color, blendStrength); + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index fd11d255f..f51a93605 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -21441,9 +21441,9 @@ SHC_3BB0A8C1_0x004733A0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00473640 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004737B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004737B0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00473830 | 0.0% | Pending +SHC_3BB0A8C1_0x00473830 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00473870 | 0.0% | Pending From cba13d47448cc6e0895d922c391ec27ff0d7c29e Mon Sep 17 00:00:00 2001 From: TheRedDaemon <66257843+TheRedDaemon@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:00:12 +0200 Subject: [PATCH 14/14] reimplement OpenSHC::Text::FontSizeClass fix function call names --- src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp | 2 +- src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp b/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp index 0adf26e2b..2f6e87274 100644 --- a/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp +++ b/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp @@ -11,7 +11,7 @@ namespace Text { dword FontSizeClass::getWideCharWidth(WCHAR wChar) { return MACRO_CALL_MEMBER(FontSizeClass_Func::getCharWidthUnk, this)(MACRO_CALL_MEMBER( - Util::WideCharMultiByteState_Func::wideCharToByteUnk, DAT_WideCharMultiByteState::ptr)(wChar)); + Util::WideCharMultiByteState_Func::singleWideCharToMultiByte, DAT_WideCharMultiByteState::ptr)(wChar)); } } diff --git a/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp b/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp index fef028227..0e25e0f30 100644 --- a/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp +++ b/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp @@ -11,8 +11,8 @@ namespace Text { int FontSizeClass::renderWideChar(WCHAR wideChar, int xPos, int yPos, int bgr24, int blendStrengthUnk) { return MACRO_CALL_MEMBER(FontSizeClass_Func::renderCharUnk, this)( - MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::wideCharToByteUnk, DAT_WideCharMultiByteState::ptr)( - wideChar), + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::singleWideCharToMultiByte, + DAT_WideCharMultiByteState::ptr)(wideChar), xPos, yPos, bgr24, blendStrengthUnk); }