diff --git a/src/OpenSHC/Text/FontSizeClass.func.hpp b/src/OpenSHC/Text/FontSizeClass.func.hpp index 27081438..5efccf3a 100644 --- a/src/OpenSHC/Text/FontSizeClass.func.hpp +++ b/src/OpenSHC/Text/FontSizeClass.func.hpp @@ -58,15 +58,15 @@ namespace Text { Address::SHC_3BB0A8C1_0x004733A0, &FontSizeClass::renderSomeSpecificTextUnk) renderSomeSpecificTextUnk; - MACRO_FUNCTION_RESOLVER(int (FontSizeClass::*)(char, int, int, int, int), false, + MACRO_FUNCTION_RESOLVER(int (FontSizeClass::*)(byte, int, int, int, int), false, Address::SHC_3BB0A8C1_0x00473640, &FontSizeClass::renderCharUnk) renderCharUnk; - MACRO_FUNCTION_RESOLVER(void (FontSizeClass::*)(LPWSTR, int, int, int, BGR24, int), false, + MACRO_FUNCTION_RESOLVER(int (FontSizeClass::*)(LPWSTR, int, int, int, BGR24, int), false, Address::SHC_3BB0A8C1_0x004737B0, &FontSizeClass::renderWideText) renderWideText; - MACRO_FUNCTION_RESOLVER(int (FontSizeClass::*)(undefined4, int, int, int, int), false, + MACRO_FUNCTION_RESOLVER(int (FontSizeClass::*)(WCHAR, int, int, int, int), false, Address::SHC_3BB0A8C1_0x00473830, &FontSizeClass::renderWideChar) renderWideChar; diff --git a/src/OpenSHC/Text/FontSizeClass.hpp b/src/OpenSHC/Text/FontSizeClass.hpp index 84cc26de..244786bd 100644 --- a/src/OpenSHC/Text/FontSizeClass.hpp +++ b/src/OpenSHC/Text/FontSizeClass.hpp @@ -35,7 +35,7 @@ namespace Text { int fontStartImageId_0x8; // 0x00000008 length: 4 FontRenderTypeInt renderType_0xc; // 0x0000000C length: 4 int baselineOffset_0x10; // 0x00000010 length: 4 - dword lineHeight_0x14; // 0x00000014 length: 4 + int lineHeight_0x14; // 0x00000014 length: 4 int letterSpacing_0x18; // 0x00000018 length: 4 int whiteSpaceWidth_0x1c; // 0x0000001C length: 4 HGDIOBJ hgdiobj; // 0x00000020 length: 4 @@ -74,11 +74,11 @@ namespace Text { void renderSomeSpecificTextUnk(int lengthUnk, int otherBlendValueUnk, int xPos, int yPos, BGR24 color); - int renderCharUnk(char charId, int xPos, int yPosUnk, int bgr24, int blendStrengthUnk); + int renderCharUnk(byte charId, int xPos, int yPosUnk, int bgr24, int blendStrengthUnk); - void renderWideText(LPWSTR wideText, int textLength, int xPos, int yPos, BGR24 color, int blendStrength); + int renderWideText(LPWSTR wideText, int textLength, int xPos, int yPos, BGR24 color, int blendStrength); - int renderWideChar(undefined4 param_1, int param_2, int param_3, int param_4, int param_5); + int renderWideChar(WCHAR wideChar, int xPos, int yPos, int bgr24, int blendStrengthUnk); }; static_assert_cpp98_obj(sizeof(FontSizeClass) == 36, FontSizeClass); diff --git a/src/OpenSHC/Text/FontSizeClass/getCharWidthUnk.cpp b/src/OpenSHC/Text/FontSizeClass/getCharWidthUnk.cpp new file mode 100644 index 00000000..61f7b9d5 --- /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/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp b/src/OpenSHC/Text/FontSizeClass/getWideCharWidth.cpp new file mode 100644 index 00000000..0adf26e2 --- /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/src/OpenSHC/Text/FontSizeClass/getWidthOfText.cpp b/src/OpenSHC/Text/FontSizeClass/getWidthOfText.cpp new file mode 100644 index 00000000..878d5fb2 --- /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/src/OpenSHC/Text/FontSizeClass/getWidthOfWideText.cpp b/src/OpenSHC/Text/FontSizeClass/getWidthOfWideText.cpp new file mode 100644 index 00000000..b15dc758 --- /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/src/OpenSHC/Text/FontSizeClass/getWordStartingFromPos.cpp b/src/OpenSHC/Text/FontSizeClass/getWordStartingFromPos.cpp new file mode 100644 index 00000000..7454adcf --- /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/src/OpenSHC/Text/FontSizeClass/renderCharUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderCharUnk.cpp new file mode 100644 index 00000000..b3a28d59 --- /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/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp new file mode 100644 index 00000000..8f3acbd7 --- /dev/null +++ b/src/OpenSHC/Text/FontSizeClass/renderMultilineTextUnk.cpp @@ -0,0 +1,180 @@ +#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 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) >> 5; + int yLineOffset = singleLineHeight; + int whiteSpaceWidth = this->whiteSpaceWidth_0x1c; + + int alternateLineHeight = DAT_TextManagerObject::instance.field13_0x34; + if (alternateLineHeight) { + singleLineHeight = alternateLineHeight; + } + + 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 charWidth = MACRO_CALL_MEMBER(FontSizeClass_Func::getCharWidthUnk, this)('-'); + + int renderedChars = 0; + do { + int remainingWidth = maxXPosition - charWidth - _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; + } + } + } + + int possibleWidth = _runXPos - xPos; + if (possibleWidth > finalTextWidth) { + finalTextWidth = possibleWidth; + } + _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; + } + _runXPos = xPos; + + _runYPos += singleLineHeight; + yLineOffset += singleLineHeight; + writtenWords = 0; + + 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); + + int possibleWidth = _runXPos - xPos; + if (possibleWidth > finalTextWidth) { + finalTextWidth = possibleWidth; + } + + if (writtenWords != 0) { + DAT_TextManagerObject::instance.field1_0x4 += singleLineHeight; + } + + if (modeUnk == 1) { + if (writtenWords == 0) { + yLineOffset -= singleLineHeight; + } + return yLineOffset; + } + return finalTextWidth; + } + +} +} diff --git a/src/OpenSHC/Text/FontSizeClass/renderMultilineWideTextUnk.cpp b/src/OpenSHC/Text/FontSizeClass/renderMultilineWideTextUnk.cpp new file mode 100644 index 00000000..0dbc2e98 --- /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 00000000..f8c11cf2 --- /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/src/OpenSHC/Text/FontSizeClass/renderText.cpp b/src/OpenSHC/Text/FontSizeClass/renderText.cpp new file mode 100644 index 00000000..da46924a --- /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/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp b/src/OpenSHC/Text/FontSizeClass/renderWideChar.cpp new file mode 100644 index 00000000..fef02822 --- /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 00000000..46bf7e69 --- /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/src/OpenSHC/Text/FontSizeClass/setupFontSizeClassObject.cpp b/src/OpenSHC/Text/FontSizeClass/setupFontSizeClassObject.cpp new file mode 100644 index 00000000..546054b6 --- /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/src/OpenSHC/Text/FontSizeClass/wrapTextIntoLines.cpp b/src/OpenSHC/Text/FontSizeClass/wrapTextIntoLines.cpp new file mode 100644 index 00000000..1850979a --- /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/src/OpenSHC/Text/TextManager.hpp b/src/OpenSHC/Text/TextManager.hpp index 81968221..841f86c0 100644 --- a/src/OpenSHC/Text/TextManager.hpp +++ b/src/OpenSHC/Text/TextManager.hpp @@ -38,8 +38,8 @@ namespace Text { public: int currentXOffset_0x0; // 0x00000000 length: 4 dword field1_0x4; // 0x00000004 length: 4 - dword field2_0x8; // 0x00000008 length: 4 - dword field3_0xc; // 0x0000000C length: 4 + int field2_0x8; // 0x00000008 length: 4 + int field3_0xc; // 0x0000000C length: 4 CodePageInt codePage; // 0x00000010 length: 4 dword field5_0x14; // 0x00000014 length: 4 dword field6_0x18; // 0x00000018 length: 4 @@ -56,7 +56,7 @@ namespace Text { GameLanguageInt gameLanguage; // 0x00000044 length: 4 FontSizeClass fontSizeClassArray[20]; // 0x00000048 length: 720 char stringArray1[32][128]; // 0x00000318 length: 4096 - dword count1; // 0x00001318 length: 4 + int count1; // 0x00001318 length: 4 undefined1 padding_0x131c[4]; // 0x0000131C length: 4 char integerTextBuffer[20]; // 0x00001320 length: 20 char field26_0x1334[20]; // 0x00001334 length: 20 diff --git a/src/core/Resolver.cpp b/src/core/Resolver.cpp index f2035487..7d87714a 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 6b3a4b48..9850d7b6 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -20149,19 +20149,19 @@ 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 +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 -SHC_3BB0A8C1_0x00469C40 | 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 @@ -21293,9 +21293,9 @@ 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 +SHC_3BB0A8C1_0x00471670 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00471690 | 0.0% | Pending @@ -21429,21 +21429,21 @@ 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 -SHC_3BB0A8C1_0x00472EF0 | 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 +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