diff --git a/IMPLEMENTATION_CHEAT_SHEET.md b/IMPLEMENTATION_CHEAT_SHEET.md index 0b7151e3..ccb173fb 100644 --- a/IMPLEMENTATION_CHEAT_SHEET.md +++ b/IMPLEMENTATION_CHEAT_SHEET.md @@ -144,6 +144,7 @@ SEC_RNG::ptr->currentNumber1 % 4 } ``` Consider this, should a switch structure arise with strange fallthrough and loops, like SHC_3BB0A8C1_0x004870B0. +- Non-consecutive case labels will likely result in a mixture of if-else and switch cases, sometimes even only if-elses. These are hard to spot. One sign, outside of weird decompiler artifacts, is that logic might be put inside a lot of conditions that feature only a single variable. Another can be a lot of GOTOs. ### Loops @@ -196,6 +197,8 @@ you might have found an unrolled loop. Therefore, try to reproduce the logic in If GOTOs are present that clearly jump to the start of a loop, but the logic does not allow to do this without a GOTO, for example from a loop inside a loop, you might be able to move the continue or break condition to the outside. Methods could be placing a fitting condition related to the contained loop conditions after the loop or using a boolean flag that then functions as conditional. Both can sometimes be optimized away. +If an explicit loop condition is removed from the compiler, it is able to prove all paths through the loop. If such a case happens where the condition is actually eliminated from the re-implementation, the re-implementation might be missing a condition that is present in the logic somewhere, but removed from the loop condition itself. The optimization pass failed to detect the resulting predictable loop in this latter case and the condition remains. + ### GOTO A function may contain multiple GOTOs. @@ -262,25 +265,36 @@ They are replaced by specific assembly instructions or otherwise inlined. A list of all intrinsics can be found in `intrin.h` in the std library, but these are mainly very low level instructions. However, there are also C functions that can be replaced by intrinsics. The following attempts to extract these from the header: -| Intrinsic | Does | -| --------- | ---------------------------------------------------------------------------------------------- | -| `memcpy` | Copies a memory block. **Does not support overlapping regions** (use `memmove` for overlap). | -| `memset` | Fills a memory block with a byte value. | -| `memcmp` | Compares two memory blocks byte-by-byte. | -| `memchr` | Searches memory for the first occurrence of a byte. | -| `strcpy` | Copies a null-terminated C string. | -| `strlen` | Returns the length of a null-terminated string (excluding `\0`). | -| `strcmp` | Compares two null-terminated C strings. | -| `strcat` | Appends one null-terminated C string to another. | -| `strncpy` | Copies up to N characters from a string; **may not null-terminate** if the source is too long. | -| `strncmp` | Compares up to N characters of two strings. | -| `wcscpy` | Copies a null-terminated wide-character string. | -| `wcslen` | Returns the length of a null-terminated wide string. | -| `ceil` | Rounds a floating-point value upward to the nearest integer value. | -| `abs` | Returns the absolute value of an `int`. | -| `labs` | Returns the absolute value of a `long`. | -| `longjmp` | Restores a saved execution context created by `setjmp`, continuing execution from that point. | -| `_setjmp` | Saves the current execution context for later restoration with `longjmp`. | +| Intrinsic | Does | +|---------------------------|----------------------------------------------------------------------------------------------------------------------| +| `memcpy` | Copies a memory block. **Does not support overlapping regions** (use `memmove` for overlap). | +| `memset` | Fills a memory block with a byte value. | +| `memcmp` | Compares two memory blocks byte-by-byte. | +| `memchr` | Searches memory for the first occurrence of a byte. | +| `strcpy` | Copies a null-terminated C string. | +| `strlen` | Returns the length of a null-terminated string (excluding `\0`). | +| `strcmp` | Compares two null-terminated C strings. | +| `strcat` | Appends one null-terminated C string to another. | +| `strncpy` | Copies up to N characters from a string; **may not null-terminate** if the source is too long. | +| `strncmp` | Compares up to N characters of two strings. | +| `strset` | Sets every character in a null-terminated string to the specified character. | +| `_strset` | Microsoft-specific version of `strset`; sets every character in a null-terminated string to the specified character. | +| `wcscpy` | Copies a null-terminated wide-character string. | +| `wcslen` | Returns the length of a null-terminated wide string. | +| `wcscmp` | Compares two null-terminated wide-character strings. | +| `wcscat` | Appends one null-terminated wide-character string to another. | +| `wcsncpy` | Copies up to N wide characters; **may not null-terminate** if the source is too long. | +| `wcsncmp` | Compares up to N wide characters of two strings. | +| `_wcsset` | Sets every character in a null-terminated wide string to the specified wide character. | +| `ceil` | Returns the smallest integral floating-point value greater than or equal to the argument. | +| `abs` | Returns the absolute value of an `int`. | +| `labs` | Returns the absolute value of a `long`. | +| `longjmp` | Restores a saved execution context created by `setjmp`, continuing execution from that point. | +| `_setjmp` | Saves the current execution context for later restoration with `longjmp`. | +| `_AddressOfReturnAddress` | Returns the address of the current function's return-address storage. | +| `_WriteBarrier` | Prevents certain compiler memory-write reorderings across the barrier. | +| `__trap` | Generates a processor/compiler trap, optionally with arguments. | + In cases where the decompiler seems to perform one of these actions via simple instructions, one can also try one of these functions. diff --git a/src/OpenSHC/OS.func.hpp b/src/OpenSHC/OS.func.hpp index 5527dd60..c825a2f8 100644 --- a/src/OpenSHC/OS.func.hpp +++ b/src/OpenSHC/OS.func.hpp @@ -171,5 +171,13 @@ namespace OS_Func { void(__cdecl*)(int _Code), REIMPLEMENTED_CRT, Address::SHC_3BB0A8C1_0x00583D55, &OpenSHC::OS::_exit) _exit; + MACRO_FUNCTION_RESOLVER(int(__cdecl*)(FILE*, wchar_t const*, ...), REIMPLEMENTED_CRT, + Address::SHC_3BB0A8C1_0x005807A8, &OpenSHC::OS::_fwprintf) + _fwprintf; + + MACRO_FUNCTION_RESOLVER( + long(__cdecl*)(wchar_t const*), REIMPLEMENTED_CRT, Address::SHC_3BB0A8C1_0x00580C0B, &OpenSHC::OS::__wtol) + __wtol; + } // namespace OS_Func } // namespace OpenSHC diff --git a/src/OpenSHC/OS.hpp b/src/OpenSHC/OS.hpp index 8f22f3e9..5487c733 100644 --- a/src/OpenSHC/OS.hpp +++ b/src/OpenSHC/OS.hpp @@ -99,5 +99,9 @@ namespace OS { void __cdecl _exit(int _Code); + int _fwprintf(FILE* stream, wchar_t const* format, ...); + + long __wtol(wchar_t const* str); + } // namespace OS } // namespace OpenSHC diff --git a/src/OpenSHC/OS/OS.cpp b/src/OpenSHC/OS/OS.cpp index 05797263..e300ed41 100644 --- a/src/OpenSHC/OS/OS.cpp +++ b/src/OpenSHC/OS/OS.cpp @@ -146,5 +146,19 @@ namespace OS { // STUB: STRONGHOLDCRUSADER 0x00583D55 void _exit(int _Code) { exit(_Code); } + // STUB: STRONGHOLDCRUSADER 0x005807A8 + int _fwprintf(FILE* stream, wchar_t const* format, ...) + { + // needed for proxy + va_list args; + va_start(args, format); + int result = vfwprintf(stream, format, args); + va_end(args); + return result; + } + + // STUB: STRONGHOLDCRUSADER 0x00580C0B + long __wtol(wchar_t const* str) { return _wtol(str); } + } } diff --git a/src/OpenSHC/Text/TextEditorState.func.hpp b/src/OpenSHC/Text/TextEditorState.func.hpp index d8f348f7..49876ccb 100644 --- a/src/OpenSHC/Text/TextEditorState.func.hpp +++ b/src/OpenSHC/Text/TextEditorState.func.hpp @@ -36,16 +36,16 @@ namespace Text { findOrAddHelpSectionName; MACRO_FUNCTION_RESOLVER( - uint (TextEditorState::*)(FILE*), false, Address::SHC_3BB0A8C1_0x0045D200, &TextEditorState::parseHLPPart) + LPWSTR (TextEditorState::*)(FILE*), false, Address::SHC_3BB0A8C1_0x0045D200, &TextEditorState::parseHLPPart) parseHLPPart; MACRO_FUNCTION_RESOLVER(void (TextEditorState::*)(), false, Address::SHC_3BB0A8C1_0x0045D370, &TextEditorState::loadHelpSectionGraphics) loadHelpSectionGraphics; - MACRO_FUNCTION_RESOLVER(undefined* (TextEditorState::*)(int*), false, Address::SHC_3BB0A8C1_0x0045D3C0, - &TextEditorState::getWideCharPointer) - getWideCharPointer; + MACRO_FUNCTION_RESOLVER(uint (TextEditorState::*)(int*), false, Address::SHC_3BB0A8C1_0x0045D3C0, + &TextEditorState::getWideCharOrWideCharPointer) + getWideCharOrWideCharPointer; MACRO_FUNCTION_RESOLVER(void (TextEditorState::*)(), false, Address::SHC_3BB0A8C1_0x0045D430, &TextEditorState::renderHelpImageHotspots) @@ -103,19 +103,19 @@ namespace Text { &TextEditorState::saveHelpFileToResource) saveHelpFileToResource; - MACRO_FUNCTION_RESOLVER(undefined4 (TextEditorState::*)(undefined4), false, Address::SHC_3BB0A8C1_0x0045F080, - &TextEditorState::getHelpTokenAdvanceLength) - getHelpTokenAdvanceLength; + MACRO_FUNCTION_RESOLVER(int (TextEditorState::*)(HelpTextToken), false, Address::SHC_3BB0A8C1_0x0045F080, + &TextEditorState::helpToken_getHelpTokenAdvanceLength) + helpToken_getHelpTokenAdvanceLength; - MACRO_FUNCTION_RESOLVER(void (TextEditorState::*)(undefined4), false, Address::SHC_3BB0A8C1_0x0045F0D0, - &TextEditorState::insertHelpTextToken) - insertHelpTextToken; + MACRO_FUNCTION_RESOLVER(void (TextEditorState::*)(HelpTextToken), false, Address::SHC_3BB0A8C1_0x0045F0D0, + &TextEditorState::helpToken_insertSpaceForHelpTextToken) + helpToken_insertSpaceForHelpTextToken; MACRO_FUNCTION_RESOLVER(void (TextEditorState::*)(), false, Address::SHC_3BB0A8C1_0x0045F240, &TextEditorState::closeHelpDialogAndReturnToMenu) closeHelpDialogAndReturnToMenu; - MACRO_FUNCTION_RESOLVER(int (TextEditorState::*)(LPCSTR), false, Address::SHC_3BB0A8C1_0x0045F470, + MACRO_FUNCTION_RESOLVER(FILE* (TextEditorState::*)(LPCSTR), false, Address::SHC_3BB0A8C1_0x0045F470, &TextEditorState::readCrusaderHelpHlp) readCrusaderHelpHlp; @@ -167,7 +167,7 @@ namespace Text { &TextEditorState::openMapDescriptionEditorDialog) openMapDescriptionEditorDialog; - MACRO_FUNCTION_RESOLVER(void (TextEditorState::*)(char*, undefined4), false, Address::SHC_3BB0A8C1_0x004620F0, + MACRO_FUNCTION_RESOLVER(void (TextEditorState::*)(char*, int), false, Address::SHC_3BB0A8C1_0x004620F0, &TextEditorState::setCustomHelpText) setCustomHelpText; diff --git a/src/OpenSHC/Text/TextEditorState.hpp b/src/OpenSHC/Text/TextEditorState.hpp index 3d08c6d0..2977ceda 100644 --- a/src/OpenSHC/Text/TextEditorState.hpp +++ b/src/OpenSHC/Text/TextEditorState.hpp @@ -8,6 +8,7 @@ #pragma once +#include "OpenSHC/UI/Enums/MenuViewTypeInt.hpp" #include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" #include "mbstring.h" @@ -16,6 +17,45 @@ namespace OpenSHC { namespace Text { + // TODO: Need proper places (and name?) + + enum HelpTextToken { + HTT_PIC = 1, + HTT_FONT = 2, + HTT_COLOUR = 3, + HTT_LINK = 4, + HTT_ENDLINK = 5, + HTT_NEWPARAGRAPH = 6, + HTT_CENTRE = 7, + HTT_ENDCENTRE = 8, + HTT_TAB = 9, // seems unused in almost all code + HTT_LINKCOLOUR = 10, + HTT_SOUND = 11, + HTT_STRING = 12, + HTT_INCLUDE = 14, + }; + + enum HelpTextPicturePositionToken { + HTT_PIC_LEFT = 0, + HTT_PIC_CENTRE = 1, + HTT_PIC_RIGHT = 2, + HTT_PIC_HERE = 3, + }; + + struct ImageHotspot { + short xPos; + short yPos; + short imageRelated; + short unknown3; + }; + + struct LineLayout { + short unknown0; + short unknown1; + short unknown2; + }; + + using OpenSHC::UI::Enums::MenuViewTypeInt; using OpenSHC::WindowsHelper::Enums::BOOLEnum; #pragma pack(push, 1) @@ -23,32 +63,32 @@ namespace Text { // SIZE: 0x00023974 class TextEditorState { public: - pointer DAT_PointerToTemporaryTextMemory; // 0x00000000 length: 4 - undefined4 customHelpTextLength; // 0x00000004 length: 4 + LPWSTR DAT_PointerToTemporaryTextMemory; // 0x00000000 length: 4 + int customHelpTextLength; // 0x00000004 length: 4 undefined4 isDialogStateInitialized; // 0x00000008 length: 4 undefined4 helpDialogVariant; // 0x0000000C length: 4 - undefined4 useInGameHelpHandler; // 0x00000010 length: 4 - undefined4 savedMenuViewType; // 0x00000014 length: 4 + int useInGameHelpHandler; // 0x00000010 length: 4 + MenuViewTypeInt savedMenuViewType; // 0x00000014 length: 4 undefined4 savedActiveMenuTab; // 0x00000018 length: 4 undefined4 savedMenuFlag; // 0x0000001C length: 4 BOOLEnum pendingCreditsFadeBorder; // 0x00000020 length: 4 BOOLEnum helpSectionParseSucceeded; // 0x00000024 length: 4 int currentHelpSectionID; // 0x00000028 length: 4 int helpSectionHistoryStack[30]; // 0x0000002C length: 120 - undefined4 counter; // 0x000000A4 length: 4 + int counter; // 0x000000A4 length: 4 undefined4 helpContentScrollOffsetY; // 0x000000A8 length: 4 - undefined4 topVisibleLineIndex; // 0x000000AC length: 4 + int topVisibleLineIndex; // 0x000000AC length: 4 undefined4 dialogX; // 0x000000B0 length: 4 undefined4 dialogY; // 0x000000B4 length: 4 undefined4 dialogWidth; // 0x000000B8 length: 4 undefined4 dialogHeight; // 0x000000BC length: 4 - undefined4 dialogContentX; // 0x000000C0 length: 4 - undefined4 dialogContentY; // 0x000000C4 length: 4 + int dialogContentX; // 0x000000C0 length: 4 + int dialogContentY; // 0x000000C4 length: 4 undefined4 dialogContentHeight; // 0x000000C8 length: 4 - undefined4 dialogContentWidth; // 0x000000CC length: 4 + int dialogContentWidth; // 0x000000CC length: 4 undefined4 helpContentScrollX; // 0x000000D0 length: 4 undefined4 helpContentScrollY; // 0x000000D4 length: 4 - undefined4 activeHelpHotspotIndex; // 0x000000D8 length: 4 + int activeHelpHotspotIndex; // 0x000000D8 length: 4 undefined4 helpDialogSubMode; // 0x000000DC length: 4 undefined4 useAlternateHelpTab; // 0x000000E0 length: 4 undefined4 isCustomTextMode; // 0x000000E4 length: 4 @@ -58,17 +98,22 @@ namespace Text { char* customHelpTextPointer; // 0x000000F4 length: 4 undefined4 isCustomHelpTextWide; // 0x000000F8 length: 4 undefined4 customHelpTextBufferSize; // 0x000000FC length: 4 - undefined4 customTextMaxLength; // 0x00000100 length: 4 + int customTextMaxLength; // 0x00000100 length: 4 char soundFileNames[5][1000]; // 0x00000104 length: 5000 byte soundFilePlayedFlags[5]; // 0x0000148C length: 5 undefined1 padding_0x1491[3]; // 0x00001491 length: 3 - undefined4 soundFileCount; // 0x00001494 length: 4 + int soundFileCount; // 0x00001494 length: 4 char graphicFileNames[20][1000]; // 0x00001498 length: 20000 - undefined4 graphicFileCount; // 0x000062B8 length: 4 - short lineLayoutTable[60000]; // 0x000062BC length: 120000 + int graphicFileCount; // 0x000062B8 length: 4 + LineLayout lineLayoutTable[20000]; // 0x000062BC length: 120000 int imageHotspotCount; // 0x0002377C length: 4 - short imageHotspotTable[50][4]; // 0x00023780 length: 400 - int intArray1[25]; // 0x00023910 length: 100 + ImageHotspot imageHotspotTable[50]; // 0x00023780 length: 400 + wchar_t* intArray1[20]; // 0x00023910 length: 80 + int unknown_0x23960; // 0x00023960 length: 4 + int unknown_0x23964; // 0x00023964 length: 4 + int unknown_0x23968; // 0x00023968 length: 4 + int unknown_0x2396C; // 0x0002396C length: 4 + int unknown_0x23970; // 0x00023970 length: 4 private: TextEditorState(TextEditorState const&); @@ -81,7 +126,7 @@ namespace Text { // Constructor TextEditorState* Constructor_TextEditorState(); - void setHelpWindowBounds(undefined4 param_1, undefined4 param_2, undefined4 param_3, undefined4 param_4); + void setHelpWindowBounds(undefined4 x, undefined4 y, undefined4 height, undefined4 width); void resetHelpStateFields(); @@ -89,17 +134,17 @@ namespace Text { int findOrAddHelpSectionName(char* param_1); - uint parseHLPPart(FILE* filePointer); + LPWSTR parseHLPPart(FILE* filePointer); void loadHelpSectionGraphics(); - undefined* getWideCharPointer(int* param_1); + uint getWideCharOrWideCharPointer(int* param_1); void renderHelpImageHotspots(); void bltTextToScreenIfNeedBe(); - void drawBorderStyle0x20(int param_1, int param_2, int param_3, int param_4); + void drawBorderStyle0x20(int dialogX, int dialogY, int dialogWidth, int dialogHeight); void drawHelpWindowBackground(); @@ -123,15 +168,15 @@ namespace Text { void saveHelpFileToResource(); - undefined4 getHelpTokenAdvanceLength(undefined4 param_1); + int helpToken_getHelpTokenAdvanceLength(HelpTextToken token); - void insertHelpTextToken(undefined4 param_1); + void helpToken_insertSpaceForHelpTextToken(HelpTextToken token); void closeHelpDialogAndReturnToMenu(); - int readCrusaderHelpHlp(LPCSTR param_1); + FILE* readCrusaderHelpHlp(LPCSTR searchedPart); - BOOLEnum loadAndParseHelpFile(char const* param_1); + BOOLEnum loadAndParseHelpFile(char const* searchedPart); void parseHlp(); @@ -145,21 +190,21 @@ namespace Text { void loadAndLayoutHelpContent(); - void openBuildingHelpDialog(int param_1); + void openBuildingHelpDialog(int sectionId); - void openInGameHelpDialog(int param_1); + void openInGameHelpDialog(int sectionId); - void openScenarioHelpDialog(int param_1); + void openScenarioHelpDialog(int sectionId); - void openCreditsScrollDialog(int param_1); + void openCreditsScrollDialog(int sectionId); - void openMapDescriptionEditorDialog(int param_1); + void openMapDescriptionEditorDialog(int sectionId); - void setCustomHelpText(char* param_1, undefined4 param_2); + void setCustomHelpText(char* helpText, int bufferSize); void popHelpDialogStack(); - void openUnusedHelpTextEditorDialog(int param_1); + void openUnusedHelpTextEditorDialog(int sectionId); }; static_assert_cpp98_obj(sizeof(TextEditorState) == 145780, TextEditorState); diff --git a/src/OpenSHC/Text/TextEditorState/Constructor_TextEditorState.cpp b/src/OpenSHC/Text/TextEditorState/Constructor_TextEditorState.cpp new file mode 100644 index 00000000..afb18c1b --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/Constructor_TextEditorState.cpp @@ -0,0 +1,43 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/OS.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045F130 + TextEditorState* TextEditorState ::Constructor_TextEditorState() + { + this->isDialogStateInitialized = 0; + this->helpDialogVariant = 0; + this->unknown_0x23960 = 0; + this->helpDialogSubMode = 0; + this->useAlternateHelpTab = 0; + this->customHelpTextLength = 0; + this->pendingTokenTypeToSkip = 0; + this->useWideHelpLayout = 0; + + MACRO_CALL_MEMBER(TextEditorState_Func::resetHelpStateFields, this)(); + + this->DAT_PointerToTemporaryTextMemory = MACRO_CALL(OS_Func::_malloc)(40000); + this->customTextMaxLength = -1; + + // FIXME:: Requires a finishing zero case, or it will not set the counter + for (int counter = 0; counter < 500; ++counter) { + if (strlen(DAT_UserHelpDefinedData::instance.HelpSections[counter])) { + continue; + } + this->counter = counter; + break; + } + + for (int i = 0; i < 20; ++i) { + this->intArray1[i] = 0; + } + return this; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/bltTextToScreenIfNeedBe.cpp b/src/OpenSHC/Text/TextEditorState/bltTextToScreenIfNeedBe.cpp new file mode 100644 index 00000000..d6bb78b8 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/bltTextToScreenIfNeedBe.cpp @@ -0,0 +1,27 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/Rendering/WindowAndDirectDraw.func.hpp" + +#include "OpenSHC/Globals/DAT_TextEditorState.hpp" +#include "OpenSHC/Globals/DAT_WindowAndDirectDraw.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D690 + void TextEditorState::bltTextToScreenIfNeedBe() + { + if (!DAT_TextEditorState::instance.unknown_0x23960) { + return; + } + if (this->savedMenuViewType == UI::Enums::MVT_MAP_EDITOR_LANDSCAPING + || this->savedMenuViewType == UI::Enums::MVT_BUILD_MENU + || this->savedMenuViewType == UI::Enums::MVT_BUILDING_AND_STATUS_MENU) { + MACRO_CALL_MEMBER(UI::Rendering::WindowAndDirectDraw_Func::bltMapGameSurfaceToScreenMenuSurfaceComplete, + DAT_WindowAndDirectDraw::ptr)(); + } + DAT_TextEditorState::instance.unknown_0x23960 = FALSE; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/closeHelpDialogAndReturnToMenu.cpp b/src/OpenSHC/Text/TextEditorState/closeHelpDialogAndReturnToMenu.cpp new file mode 100644 index 00000000..04a89a42 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/closeHelpDialogAndReturnToMenu.cpp @@ -0,0 +1,78 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Game/GameCore.func.hpp" +#include "OpenSHC/OS.func.hpp" +#include "OpenSHC/UI/MenuModalComposition.func.hpp" +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameCore.hpp" +#include "OpenSHC/Globals/DAT_MenuModalComposition1.hpp" +#include "OpenSHC/Globals/DAT_MenuView_TriggerPrepare.hpp" +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045F240 + void TextEditorState::closeHelpDialogAndReturnToMenu() + { + if (!this->isDialogStateInitialized) { + return; + } + MACRO_CALL_MEMBER(TextEditorState_Func::resetHelpStateFields, this)(); + this->isDialogStateInitialized = 0; + + if (this->isCustomTextMode) { + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::activateModalDialog, DAT_MenuModalComposition1::ptr)( + UI::Enums::MMT_NONE, FALSE); + for (int i = 0; i < 20; ++i) { + this->intArray1[i] = 0; + } + if (this->customHelpTextPointer) { + if (!this->isCustomHelpTextWide) { + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::wideCharToMultiByteWithSize, + DAT_WideCharMultiByteState::ptr)(this->customHelpTextPointer, + this->DAT_PointerToTemporaryTextMemory, this->customHelpTextBufferSize); + } else { + MACRO_CALL(OS_Func::_wcsncpy)((wchar_t*)this->customHelpTextPointer, + this->DAT_PointerToTemporaryTextMemory, this->customHelpTextBufferSize); + } + } + DAT_MenuView_TriggerPrepare::instance = TRUE; + + } else if (this->helpDialogVariant == 0) { + + if (this->savedMenuViewType == UI::Enums::MVT_BUILD_MENU) { + DAT_GameCore::instance.buildmenuMenuTabToSwitchTo.tabType = this->savedActiveMenuTab; + MACRO_CALL_MEMBER(Game::GameCore_Func::switchToMenuView, DAT_GameCore::ptr)( + (UI::Enums::MenuViewType)this->savedMenuViewType, 0); + + } else if (this->savedMenuViewType == UI::Enums::MVT_MAP_EDITOR_LANDSCAPING) { + DAT_GameCore::instance.landscapingmenuMenuTabToSwitchTo = this->savedActiveMenuTab; + MACRO_CALL_MEMBER(Game::GameCore_Func::switchToMenuView, DAT_GameCore::ptr)( + (UI::Enums::MenuViewType)this->savedMenuViewType, 0); + + } else if (this->savedMenuViewType == UI::Enums::MVT_BUILDING_AND_STATUS_MENU) { + DAT_GameCore::instance.buildingandstatusmenuMenuTabToSwitchTo = this->savedActiveMenuTab; + MACRO_CALL_MEMBER(Game::GameCore_Func::switchToMenuView, DAT_GameCore::ptr)( + (UI::Enums::MenuViewType)this->savedMenuViewType, 0); + + } else { + DAT_GameCore::instance.menuTabToSwitchTo.tabType = this->savedActiveMenuTab; + MACRO_CALL_MEMBER(Game::GameCore_Func::switchToMenuView, DAT_GameCore::ptr)( + (UI::Enums::MenuViewType)this->savedMenuViewType, 0); + } + + } else { + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::activateModalDialog, DAT_MenuModalComposition1::ptr)( + UI::Enums::MMT_NONE, FALSE); + for (int i = 0; i < 20; ++i) { + this->intArray1[i] = 0; + } + } + + this->helpDialogVariant = 0; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/drawBorderStyle0x20.cpp b/src/OpenSHC/Text/TextEditorState/drawBorderStyle0x20.cpp new file mode 100644 index 00000000..c36e3e66 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/drawBorderStyle0x20.cpp @@ -0,0 +1,37 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_00df2964.hpp" +#include "OpenSHC/Globals/DAT_00df296c.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" +#include "OpenSHC/Globals/INT_00df2968.hpp" +#include "OpenSHC/Globals/INT_00df2970.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D6C0 + void TextEditorState::drawBorderStyle0x20(int dialogX, int dialogY, int dialogWidth, int dialogHeight) + { + this->dialogX = dialogX; + this->dialogY = dialogY; + this->dialogWidth = dialogWidth; + this->dialogHeight = dialogHeight; + + // NOTE: dialogWidth is used to compute the content height and vice versa, no idea if something was switched; + // also, the required order feels strange, maybe they used a RECT struct or macro + // FIXME: ContentHeight and ContentWidth or the dialogWidth and dialogHeight are swapped + int const contentX = this->dialogX + DAT_00df2964::instance; + int const contentY = this->dialogY + DAT_00df296c::instance; + int const contentWidth = this->dialogHeight - INT_00df2970::instance; + int const contentHeight = this->dialogWidth - INT_00df2968::instance; + this->dialogContentX = contentX; + this->dialogContentY = contentY; + this->dialogContentHeight = contentHeight; + this->dialogContentWidth = contentWidth; + + this->helpContentScrollX = DAT_ViewportRenderState::instance.viewportState.currentCameraOffsetX; + this->helpContentScrollY = DAT_ViewportRenderState::instance.viewportState.currentCameraOffsetY; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/drawHelpWindowBackground.cpp b/src/OpenSHC/Text/TextEditorState/drawHelpWindowBackground.cpp new file mode 100644 index 00000000..ac5555d6 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/drawHelpWindowBackground.cpp @@ -0,0 +1,52 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/Rendering/PencilRenderCore.func.hpp" + +#include "OpenSHC/Globals/COL_BLACK.hpp" +#include "OpenSHC/Globals/COL_DARK_CYAN_GREY.hpp" +#include "OpenSHC/Globals/COL_VERY_DARK_GREY.hpp" +#include "OpenSHC/Globals/DAT_PencilRenderCore.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D740 + void TextEditorState::drawHelpWindowBackground() + { + if (this->helpDialogVariant != 1) { + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = Rendering::Enums::RT_SCREEN_MENU; + } else { + DAT_TextManagerObject::instance.textSurfaceTarget = Rendering::Enums::RT_MAP_GAME; + DAT_PencilRenderCore::instance.surfaceTarget = Rendering::Enums::RT_MAP_GAME; + } + if (this->isCustomTextMode) { + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawBoxWithRoundedEdges, DAT_PencilRenderCore::ptr)( + this->dialogX, this->dialogY, this->dialogWidth + this->dialogX, this->dialogHeight + this->dialogY, + UI::Enums::RBERL_SLIGHT); + } else if (!this->useAlternateHelpTab) { + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawColorBox, DAT_PencilRenderCore::ptr)( + this->dialogX, this->dialogY, this->dialogWidth + this->dialogX, this->dialogHeight + this->dialogY, + COL_BLACK::instance.shortValue); + } else if (this->helpDialogVariant != 2) { + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawColorBox, DAT_PencilRenderCore::ptr)( + this->dialogX, this->dialogY, this->dialogWidth + this->dialogX, this->dialogHeight + this->dialogY, + COL_VERY_DARK_GREY::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawColorBox, DAT_PencilRenderCore::ptr)( + this->dialogContentX, this->dialogContentY, this->dialogContentHeight + this->dialogContentX, + this->dialogContentWidth + this->dialogContentY, COL_BLACK::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawColorBox, DAT_PencilRenderCore::ptr)( + this->dialogX, this->dialogY + this->dialogHeight, this->dialogWidth + this->dialogX, + this->dialogY + this->dialogHeight + 60, COL_DARK_CYAN_GREY::instance.shortValue); + } + if (this->helpDialogVariant != 1) { + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = Rendering::Enums::RT_MAP_GAME; + } else { + DAT_TextManagerObject::instance.textSurfaceTarget = Rendering::Enums::RT_SCREEN_MENU; + DAT_PencilRenderCore::instance.surfaceTarget = Rendering::Enums::RT_SCREEN_MENU; + } + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/findHelpGraphicIndexByName.cpp b/src/OpenSHC/Text/TextEditorState/findHelpGraphicIndexByName.cpp new file mode 100644 index 00000000..76afd0b0 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/findHelpGraphicIndexByName.cpp @@ -0,0 +1,20 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/OS.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D890 + int TextEditorState::findHelpGraphicIndexByName(char* param_1) + { + for (int i = 0; i < this->graphicFileCount; ++i) { + if (!MACRO_CALL(OS_Func::__stricmp)(this->graphicFileNames[i], param_1)) { + return i; + } + } + return -1; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/findHelpSectionIndexByName.cpp b/src/OpenSHC/Text/TextEditorState/findHelpSectionIndexByName.cpp new file mode 100644 index 00000000..018ef45a --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/findHelpSectionIndexByName.cpp @@ -0,0 +1,22 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/OS.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D140 + int TextEditorState::findHelpSectionIndexByName(char* param_1) + { + for (int counter = 0; counter < this->counter; ++counter) { + if (!MACRO_CALL(OS_Func::__stricmp)(DAT_UserHelpDefinedData::instance.HelpSections[counter], param_1)) { + return counter; + } + } + return -1; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/findOrAddHelpGraphicName.cpp b/src/OpenSHC/Text/TextEditorState/findOrAddHelpGraphicName.cpp new file mode 100644 index 00000000..4e668a43 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/findOrAddHelpGraphicName.cpp @@ -0,0 +1,25 @@ +// disable deprecation warnings for strcpy +#pragma warning(disable : 4996) + +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D8F0 + int TextEditorState::findOrAddHelpGraphicName(char* param_1) + { + int graphicIndex = MACRO_CALL_MEMBER(TextEditorState_Func::findHelpGraphicIndexByName, this)(param_1); + if (graphicIndex != -1) { + return graphicIndex; + } + graphicIndex = this->graphicFileCount; + strcpy(this->graphicFileNames[graphicIndex], param_1); + if (this->graphicFileCount < 20) { + ++this->graphicFileCount; + } + return graphicIndex; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/findOrAddHelpSectionName.cpp b/src/OpenSHC/Text/TextEditorState/findOrAddHelpSectionName.cpp new file mode 100644 index 00000000..d1be3a1e --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/findOrAddHelpSectionName.cpp @@ -0,0 +1,32 @@ +// disable deprecation warnings for strcpy +#pragma warning(disable : 4996) + +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Text/TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D1A0 + int TextEditorState::findOrAddHelpSectionName(char* param_1) + { + int helpSectionId + = MACRO_CALL_MEMBER(OpenSHC::Text::TextEditorState_Func::findHelpSectionIndexByName, this)(param_1); + if (helpSectionId != -1) { + return helpSectionId; + } + // FIXME:: This should overflow the buffer if filled to much. The counter can reach 500, which is one over the + // buffer, ignoring that it will just overwrite this again and again. + helpSectionId = this->counter; + strcpy(DAT_UserHelpDefinedData::instance.HelpSections[helpSectionId], param_1); + if (this->counter < 500) { + ++this->counter; + } + return helpSectionId; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/findOrAddSoundName.cpp b/src/OpenSHC/Text/TextEditorState/findOrAddSoundName.cpp new file mode 100644 index 00000000..154d8464 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/findOrAddSoundName.cpp @@ -0,0 +1,29 @@ +// disable deprecation warnings for strcpy +#pragma warning(disable : 4996) + +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Text/TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045DAE0 + int TextEditorState::findOrAddSoundName(char* param_1) + { + int index = MACRO_CALL_MEMBER(OpenSHC::Text::TextEditorState_Func::findSoundIndexByName, this)(param_1); + if (index != -1) { + return index; + } + + index = this->soundFileCount; + strcpy(this->soundFileNames[index], param_1); + this->soundFilePlayedFlags[index] = 0; + if (this->soundFileCount < 5) { + ++this->soundFileCount; + } + return index; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/findSoundIndexByName.cpp b/src/OpenSHC/Text/TextEditorState/findSoundIndexByName.cpp new file mode 100644 index 00000000..f105e1de --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/findSoundIndexByName.cpp @@ -0,0 +1,20 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/OS.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045DA80 + int TextEditorState::findSoundIndexByName(char* param_1) + { + for (int i = 0; i < this->soundFileCount; i = i + 1) { + if (!MACRO_CALL(OpenSHC::OS_Func::__stricmp)(this->soundFileNames[i], param_1)) { + return i; + } + } + return -1; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/getHelpSectionText.cpp b/src/OpenSHC/Text/TextEditorState/getHelpSectionText.cpp new file mode 100644 index 00000000..a0c88560 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/getHelpSectionText.cpp @@ -0,0 +1,20 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D9E0 + char* TextEditorState::getHelpSectionText(int param_1) + { + for (int index = 0; DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 != -1; ++index) { + if (DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 == param_1) { + return DAT_UserHelpDefinedData::instance.field5_0x7a124[index].text_0x0; + } + } + return NULL; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/getNextHelpColorEntryIndex.cpp b/src/OpenSHC/Text/TextEditorState/getNextHelpColorEntryIndex.cpp new file mode 100644 index 00000000..98ad9021 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/getNextHelpColorEntryIndex.cpp @@ -0,0 +1,19 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045DA20 + int TextEditorState::getNextHelpColorEntryIndex(int param_1) + { + int newIndex = param_1 + 1; + if (DAT_UserHelpDefinedData::instance.field6_0x7a16c[newIndex].name_0x0 == NULL) { + newIndex = 0; + } + return newIndex; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/getNextHelpSectionID.cpp b/src/OpenSHC/Text/TextEditorState/getNextHelpSectionID.cpp new file mode 100644 index 00000000..dd1e12b3 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/getNextHelpSectionID.cpp @@ -0,0 +1,26 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D950 + int TextEditorState::getNextHelpSectionID(int param_1) + { + for (int index = 0; DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 != -1; ++index) { + if (DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 != param_1) { + continue; + } + + ++index; + if (DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 == -1) { + index = 0; + } + return DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4; + } + return -1; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/getPrevHelpColorEntryIndex.cpp b/src/OpenSHC/Text/TextEditorState/getPrevHelpColorEntryIndex.cpp new file mode 100644 index 00000000..d3f15557 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/getPrevHelpColorEntryIndex.cpp @@ -0,0 +1,23 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045DA40 + int TextEditorState::getPrevHelpColorEntryIndex(int param_1) + { + --param_1; + if (param_1 < 0) { + param_1 = 0; + while (DAT_UserHelpDefinedData::instance.field6_0x7a16c[param_1].name_0x0 != NULL) { + ++param_1; + } + --param_1; + } + return param_1; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/getPrevHelpSectionID.cpp b/src/OpenSHC/Text/TextEditorState/getPrevHelpSectionID.cpp new file mode 100644 index 00000000..4e5d3ba8 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/getPrevHelpSectionID.cpp @@ -0,0 +1,28 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D990 + int TextEditorState::getPrevHelpSectionID(int param_1) + { + for (int index = 0; DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 != -1; ++index) { + if (DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 == param_1) { + --index; + if (index < 0) { + index = 0; + while (DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4 != -1) { + ++index; + } + --index; + } + return DAT_UserHelpDefinedData::instance.field5_0x7a124[index].unknown_0x4; + } + } + return -1; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/getWideCharOrWideCharPointer.cpp b/src/OpenSHC/Text/TextEditorState/getWideCharOrWideCharPointer.cpp new file mode 100644 index 00000000..7e28eded --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/getWideCharOrWideCharPointer.cpp @@ -0,0 +1,36 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Globals/DAT_ARRAY_00df2b78.hpp" + +namespace OpenSHC { +namespace Text { + + // NOTE: Return is essentially a "union", however, it needs to be a value for the proper structure + // Also, it might be likely that this function is "known" by its only user "processHelpRichTextTokens" + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D3C0 + uint TextEditorState::getWideCharOrWideCharPointer(int* param_1) + { + int result = this->DAT_PointerToTemporaryTextMemory[*param_1]; + *param_1 += 1; + + if (result >= L' ') { + DAT_ARRAY_00df2b78::instance[0] = result; + + int length = 1; + while (this->DAT_PointerToTemporaryTextMemory[*param_1] >= L' ') { + DAT_ARRAY_00df2b78::instance[length] = this->DAT_PointerToTemporaryTextMemory[*param_1]; + *param_1 += 1; + ++length; + if (this->DAT_PointerToTemporaryTextMemory[*param_1 - 1] == L' ') { + break; + } + } + DAT_ARRAY_00df2b78::instance[length] = L'\0'; + result = (int)DAT_ARRAY_00df2b78::instance; + } + return (uint)result; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/helpToken.cpp b/src/OpenSHC/Text/TextEditorState/helpToken.cpp new file mode 100644 index 00000000..6931a374 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/helpToken.cpp @@ -0,0 +1,39 @@ +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045F080 + int TextEditorState::helpToken_getHelpTokenAdvanceLength(HelpTextToken token) + { + switch (token) { + case HTT_PIC: + return 4; + + case HTT_FONT: + case HTT_COLOUR: + case HTT_LINK: + case HTT_LINKCOLOUR: + case HTT_SOUND: + case HTT_STRING: + case HTT_INCLUDE: + return 3; + + default: + return 1; + } + } + + // FUNCTION: STRONGHOLDCRUSADER 0x0045F0D0 + void TextEditorState::helpToken_insertSpaceForHelpTextToken(HelpTextToken token) + { + int tokenLength = MACRO_CALL_MEMBER(TextEditorState_Func::helpToken_getHelpTokenAdvanceLength, this)(token); + for (int textIndex = this->customHelpTextLength; textIndex >= this->activeHelpHotspotIndex; --textIndex) { + this->DAT_PointerToTemporaryTextMemory[textIndex + tokenLength] + = this->DAT_PointerToTemporaryTextMemory[textIndex]; + } + this->customHelpTextLength += tokenLength; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/initializeAndLayoutHelpText.cpp b/src/OpenSHC/Text/TextEditorState/initializeAndLayoutHelpText.cpp new file mode 100644 index 00000000..44b86a79 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/initializeAndLayoutHelpText.cpp @@ -0,0 +1,22 @@ +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x004614D0 + void TextEditorState::initializeAndLayoutHelpText() + { + for (int i = 0; i < 20000; ++i) { + this->lineLayoutTable[i].unknown0 = 25; + this->lineLayoutTable[i].unknown1 = this->dialogContentHeight - 25; + this->lineLayoutTable[i].unknown2 = 0; + } + for (int i = 0; i < 4; ++i) { + this->lineLayoutTable[i].unknown0 = -1; + } + this->imageHotspotCount = 0; + while (!MACRO_CALL_MEMBER(TextEditorState_Func::processHelpRichTextTokens, this)(0)) {}; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/loadAndLayoutHelpContent.cpp b/src/OpenSHC/Text/TextEditorState/loadAndLayoutHelpContent.cpp new file mode 100644 index 00000000..62a5eddb --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/loadAndLayoutHelpContent.cpp @@ -0,0 +1,22 @@ +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x004619D0 + void TextEditorState::loadAndLayoutHelpContent() + { + this->graphicFileCount = 0; + this->soundFileCount = 0; + this->topVisibleLineIndex = -1; + this->helpContentScrollOffsetY = 0; + if (!this->isCustomTextMode) { + MACRO_CALL_MEMBER(TextEditorState_Func::parseHlp, this)(); + MACRO_CALL_MEMBER(TextEditorState_Func::loadHelpSectionGraphics, this)(); + } + this->activeHelpHotspotIndex = 0; + MACRO_CALL_MEMBER(TextEditorState_Func::initializeAndLayoutHelpText, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/loadAndParseHelpFile.cpp b/src/OpenSHC/Text/TextEditorState/loadAndParseHelpFile.cpp new file mode 100644 index 00000000..7a0e6bf8 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/loadAndParseHelpFile.cpp @@ -0,0 +1,22 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/OS.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045F580 + BOOLEnum TextEditorState::loadAndParseHelpFile(char const* searchedPart) + { + FILE* _File = MACRO_CALL_MEMBER(TextEditorState_Func::readCrusaderHelpHlp, this)(searchedPart); + if (_File) { + MACRO_CALL(OS_Func::_fclose)(_File); + if (this->helpSectionParseSucceeded) { + return TRUE; + } + } + return FALSE; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/loadHelpSectionGraphics.cpp b/src/OpenSHC/Text/TextEditorState/loadHelpSectionGraphics.cpp new file mode 100644 index 00000000..ea5ba6b5 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/loadHelpSectionGraphics.cpp @@ -0,0 +1,22 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/Rendering/TextureRenderCore.func.hpp" + +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D370 + void TextEditorState::loadHelpSectionGraphics() + { + DAT_TextureRenderCoreObject::instance.backwardsLoadedGfxIndex_0x16C850 = 99; + DAT_TextureRenderCoreObject::instance.loadedGfxArray[99].backwardsOffsetInBuffer = 0; + for (int i = 0; i < this->graphicFileCount; ++i) { + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::loadGfxAtBufferEnd, + DAT_TextureRenderCoreObject::ptr)(this->graphicFileNames[i]); + } + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/openBuildingHelpDialog.cpp b/src/OpenSHC/Text/TextEditorState/openBuildingHelpDialog.cpp new file mode 100644 index 00000000..fd849ca4 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/openBuildingHelpDialog.cpp @@ -0,0 +1,79 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Text/TextEditorState.func.hpp" +#include "OpenSHC/UI/MenuModalComposition.func.hpp" + +#include "OpenSHC/Globals/DAT_00df2964.hpp" +#include "OpenSHC/Globals/DAT_00df296c.hpp" +#include "OpenSHC/Globals/DAT_MenuModalComposition1.hpp" +#include "OpenSHC/Globals/DAT_UserTextHandlerState.hpp" +#include "OpenSHC/Globals/INT_00df2968.hpp" +#include "OpenSHC/Globals/INT_00df2970.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00461A20 + void TextEditorState::openBuildingHelpDialog(int sectionId) + { + if (!this->isDialogStateInitialized) { + this->isDialogStateInitialized = TRUE; + this->helpDialogVariant = 1; + this->useInGameHelpHandler = 0; + this->helpDialogSubMode = 0; + this->useAlternateHelpTab = 0; + this->isCustomTextMode = 0; + DAT_UserTextHandlerState::instance.inputBufferIndex = 0; + this->helpContentScrollX = 0; + this->helpContentScrollY = 0; + } else if (sectionId == this->currentHelpSectionID) { + return; + } + + this->activeHelpHotspotIndex = 0; + if (sectionId == -1) { + MACRO_CALL_MEMBER(TextEditorState_Func::closeHelpDialogAndReturnToMenu, this)(); + return; + } + + this->isTextHelpDialogMode = 1; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::activateModalDialog, DAT_MenuModalComposition1::ptr)( + UI::Enums::MMT_BUILDING_HELP_TEXT, FALSE); + + int modalX; + int modalY; + int modalWidth; + int modalHeight; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::fillWithMenuModalDimensions, DAT_MenuModalComposition1::ptr)( + &modalX, &modalY, &modalWidth, &modalHeight); + // Likely also some rect structure + DAT_00df2964::instance = 15; + DAT_00df296c::instance = 13; + INT_00df2968::instance = 60; + INT_00df2970::instance = 65; + this->dialogX = modalX; + this->dialogY = modalY; + this->dialogWidth = modalWidth; + this->dialogHeight = modalHeight; + + int const dialogContentX = this->dialogX + DAT_00df2964::instance; + int const dialogContentY = this->dialogY + DAT_00df296c::instance; + int const dialogContentHeight = this->dialogHeight - INT_00df2970::instance; + int const dialogContentWidth = this->dialogWidth - INT_00df2968::instance; + this->dialogContentX = dialogContentX; + this->dialogContentY = dialogContentY; + this->dialogContentHeight = dialogContentWidth; + this->dialogContentWidth = dialogContentHeight; + + for (int i = 28; i >= 0; --i) { + this->helpSectionHistoryStack[i + 1] = this->helpSectionHistoryStack[i]; + } + this->helpSectionHistoryStack[0] = this->currentHelpSectionID; + + this->currentHelpSectionID = sectionId; + this->helpContentScrollOffsetY = 0; + MACRO_CALL_MEMBER(TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/openCreditsScrollDialog.cpp b/src/OpenSHC/Text/TextEditorState/openCreditsScrollDialog.cpp new file mode 100644 index 00000000..cc8d182e --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/openCreditsScrollDialog.cpp @@ -0,0 +1,73 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/MenuModalComposition.func.hpp" + +#include "OpenSHC/Globals/DAT_00df2964.hpp" +#include "OpenSHC/Globals/DAT_00df296c.hpp" +#include "OpenSHC/Globals/DAT_MenuModalComposition1.hpp" +#include "OpenSHC/Globals/DAT_UserTextHandlerState.hpp" +#include "OpenSHC/Globals/INT_00df2968.hpp" +#include "OpenSHC/Globals/INT_00df2970.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00461E50 + void TextEditorState::openCreditsScrollDialog(int sectionId) + { + if (!this->isDialogStateInitialized) { + this->isDialogStateInitialized = TRUE; + this->helpDialogVariant = 2; + this->useInGameHelpHandler = FALSE; + this->helpDialogSubMode = 0; + this->useAlternateHelpTab = FALSE; + this->isCustomTextMode = FALSE; + DAT_UserTextHandlerState::instance.inputBufferIndex = 0; + } + this->activeHelpHotspotIndex = 0; + if (sectionId == -1) { + MACRO_CALL_MEMBER(TextEditorState_Func::closeHelpDialogAndReturnToMenu, this)(); + return; + } + + this->isTextHelpDialogMode = TRUE; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::activateModalDialog, DAT_MenuModalComposition1::ptr)( + UI::Enums::MMT_CREDITS_SCROLL, FALSE); + + int modalX; + int modalY; + int modalWidth; + int modalHeight; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::fillWithMenuModalDimensions, DAT_MenuModalComposition1::ptr)( + &modalX, &modalY, &modalWidth, &modalHeight); + + DAT_00df2964::instance = 0; + DAT_00df296c::instance = 0; + INT_00df2968::instance = 0; + INT_00df2970::instance = 0; + this->dialogX = modalX; + this->dialogY = modalY; + this->dialogWidth = modalWidth; + this->dialogHeight = modalHeight; + + int const dialogContentX = this->dialogX + DAT_00df2964::instance; + int const dialogContentY = this->dialogY + DAT_00df296c::instance; + int const dialogContentHeight = this->dialogHeight - INT_00df2970::instance; + int const dialogContentWidth = this->dialogWidth - INT_00df2968::instance; + this->dialogContentX = dialogContentX; + this->dialogContentY = dialogContentY; + this->dialogContentHeight = dialogContentWidth; + this->dialogContentWidth = dialogContentHeight; + + for (int i = 28; i >= 0; --i) { + this->helpSectionHistoryStack[i + 1] = this->helpSectionHistoryStack[i]; + } + this->helpSectionHistoryStack[0] = this->currentHelpSectionID; + + this->currentHelpSectionID = sectionId; + this->helpContentScrollOffsetY = 0; + MACRO_CALL_MEMBER(TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/openInGameHelpDialog.cpp b/src/OpenSHC/Text/TextEditorState/openInGameHelpDialog.cpp new file mode 100644 index 00000000..cdb41b1d --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/openInGameHelpDialog.cpp @@ -0,0 +1,74 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/MenuModalComposition.func.hpp" + +#include "OpenSHC/Globals/DAT_00df2964.hpp" +#include "OpenSHC/Globals/DAT_00df296c.hpp" +#include "OpenSHC/Globals/DAT_MenuModalComposition1.hpp" +#include "OpenSHC/Globals/DAT_UserTextHandlerState.hpp" +#include "OpenSHC/Globals/INT_00df2968.hpp" +#include "OpenSHC/Globals/INT_00df2970.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00461B90 + void TextEditorState::openInGameHelpDialog(int sectionId) + { + if (!this->isDialogStateInitialized) { + this->isDialogStateInitialized = TRUE; + this->helpDialogVariant = 1; + this->useInGameHelpHandler = TRUE; + this->helpDialogSubMode = 0; + this->useAlternateHelpTab = 0; + this->isCustomTextMode = 0; + DAT_UserTextHandlerState::instance.inputBufferIndex = 0; + this->helpContentScrollX = 0; + this->helpContentScrollY = 0; + } + this->activeHelpHotspotIndex = 0; + if (sectionId == -1) { + MACRO_CALL_MEMBER(TextEditorState_Func::closeHelpDialogAndReturnToMenu, this)(); + return; + } + this->isTextHelpDialogMode = TRUE; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::activateModalDialog, DAT_MenuModalComposition1::ptr)( + UI::Enums::MMT_IN_GAME_HELP_TEXT, FALSE); + + int modalX; + int modalY; + int modalWidth; + int modalHeight; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::fillWithMenuModalDimensions, DAT_MenuModalComposition1::ptr)( + &modalX, &modalY, &modalWidth, &modalHeight); + + DAT_00df2964::instance = 15; + DAT_00df296c::instance = 13; + INT_00df2968::instance = 60; + INT_00df2970::instance = 65; + this->dialogX = modalX; + this->dialogY = modalY; + this->dialogWidth = modalWidth; + this->dialogHeight = modalHeight; + + int const dialogContentX = this->dialogX + DAT_00df2964::instance; + int const dialogContentY = this->dialogY + DAT_00df296c::instance; + int const dialogContentHeight = this->dialogHeight - INT_00df2970::instance; + int const dialogContentWidth = this->dialogWidth - INT_00df2968::instance; + this->dialogContentX = dialogContentX; + this->dialogContentY = dialogContentY; + this->dialogContentHeight = dialogContentWidth; + this->dialogContentWidth = dialogContentHeight; + + for (int i = 28; i >= 0; --i) { + this->helpSectionHistoryStack[i + 1] = this->helpSectionHistoryStack[i]; + } + this->helpSectionHistoryStack[0] = this->currentHelpSectionID; + + this->currentHelpSectionID = sectionId; + this->helpContentScrollOffsetY = 0; + MACRO_CALL_MEMBER(TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/openMapDescriptionEditorDialog.cpp b/src/OpenSHC/Text/TextEditorState/openMapDescriptionEditorDialog.cpp new file mode 100644 index 00000000..ab6933b0 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/openMapDescriptionEditorDialog.cpp @@ -0,0 +1,75 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/MenuModalComposition.func.hpp" + +#include "OpenSHC/Globals/DAT_00df2964.hpp" +#include "OpenSHC/Globals/DAT_00df296c.hpp" +#include "OpenSHC/Globals/DAT_MenuModalComposition1.hpp" +#include "OpenSHC/Globals/DAT_UserTextHandlerState.hpp" +#include "OpenSHC/Globals/INT_00df2968.hpp" +#include "OpenSHC/Globals/INT_00df2970.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00461F90 + void TextEditorState::openMapDescriptionEditorDialog(int sectionId) + { + if (!this->isDialogStateInitialized) { + this->isDialogStateInitialized = TRUE; + this->helpDialogVariant = 0; + this->useInGameHelpHandler = FALSE; + this->helpDialogSubMode = 0; + this->useAlternateHelpTab = TRUE; + this->isCustomTextMode = TRUE; + DAT_UserTextHandlerState::instance.inputBufferIndex = 0; + this->helpContentScrollX = 0; + this->helpContentScrollY = 0; + } + this->activeHelpHotspotIndex = 0; + this->customHelpTextPointer = NULL; + if (sectionId == -1) { + MACRO_CALL_MEMBER(TextEditorState_Func::closeHelpDialogAndReturnToMenu, this)(); + return; + } + this->isTextHelpDialogMode = 0; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::activateModalDialog, DAT_MenuModalComposition1::ptr)( + UI::Enums::MMT_MAP_DESCRIPTION_EDITOR, FALSE); + + int modalX; + int modalY; + int modalWidth; + int modalHeight; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::fillWithMenuModalDimensions, DAT_MenuModalComposition1::ptr)( + &modalX, &modalY, &modalWidth, &modalHeight); + + DAT_00df2964::instance = 10; + DAT_00df296c::instance = 10; + INT_00df2968::instance = 45; + INT_00df2970::instance = 53; + this->dialogX = modalX; + this->dialogY = modalY; + this->dialogWidth = modalWidth; + this->dialogHeight = modalHeight; + + int const dialogContentX = this->dialogX + DAT_00df2964::instance; + int const dialogContentY = this->dialogY + DAT_00df296c::instance; + int const dialogContentHeight = this->dialogHeight - INT_00df2970::instance; + int const dialogContentWidth = this->dialogWidth - INT_00df2968::instance; + this->dialogContentX = dialogContentX; + this->dialogContentY = dialogContentY; + this->dialogContentHeight = dialogContentWidth; + this->dialogContentWidth = dialogContentHeight; + + for (int i = 28; i >= 0; --i) { + this->helpSectionHistoryStack[i + 1] = this->helpSectionHistoryStack[i]; + } + this->helpSectionHistoryStack[0] = this->currentHelpSectionID; + + this->currentHelpSectionID = -1; + this->helpContentScrollOffsetY = 0; + MACRO_CALL_MEMBER(TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/openScenarioHelpDialog.cpp b/src/OpenSHC/Text/TextEditorState/openScenarioHelpDialog.cpp new file mode 100644 index 00000000..cbe2b44f --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/openScenarioHelpDialog.cpp @@ -0,0 +1,74 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/MenuModalComposition.func.hpp" + +#include "OpenSHC/Globals/DAT_00df2964.hpp" +#include "OpenSHC/Globals/DAT_00df296c.hpp" +#include "OpenSHC/Globals/DAT_MenuModalComposition1.hpp" +#include "OpenSHC/Globals/DAT_UserTextHandlerState.hpp" +#include "OpenSHC/Globals/INT_00df2968.hpp" +#include "OpenSHC/Globals/INT_00df2970.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00461CF0 + void TextEditorState::openScenarioHelpDialog(int sectionId) + { + if (!this->isDialogStateInitialized) { + this->isDialogStateInitialized = TRUE; + this->helpDialogVariant = 2; + this->useInGameHelpHandler = FALSE; + this->helpDialogSubMode = 0; + this->useAlternateHelpTab = FALSE; + this->isCustomTextMode = FALSE; + DAT_UserTextHandlerState::instance.inputBufferIndex = 0; + this->helpContentScrollX = 0; + this->helpContentScrollY = 0; + } + this->activeHelpHotspotIndex = 0; + if (sectionId == -1) { + MACRO_CALL_MEMBER(OpenSHC::Text::TextEditorState_Func::closeHelpDialogAndReturnToMenu, this)(); + return; + } + this->isTextHelpDialogMode = TRUE; + MACRO_CALL_MEMBER(OpenSHC::UI::MenuModalComposition_Func::activateModalDialog, DAT_MenuModalComposition1::ptr)( + OpenSHC::UI::Enums::MMT_DISPLAY_SCENARIO_HELP_TEXT, FALSE); + + int modalX; + int modalY; + int modalWidth; + int modalHeight; + MACRO_CALL_MEMBER(UI::MenuModalComposition_Func::fillWithMenuModalDimensions, DAT_MenuModalComposition1::ptr)( + &modalX, &modalY, &modalWidth, &modalHeight); + + DAT_00df2964::instance = 10; + DAT_00df296c::instance = 10; + INT_00df2968::instance = 45; + INT_00df2970::instance = 20; + this->dialogX = modalX; + this->dialogY = modalY; + this->dialogWidth = modalWidth; + this->dialogHeight = modalHeight; + + int const dialogContentX = this->dialogX + DAT_00df2964::instance; + int const dialogContentY = this->dialogY + DAT_00df296c::instance; + int const dialogContentHeight = this->dialogHeight - INT_00df2970::instance; + int const dialogContentWidth = this->dialogWidth - INT_00df2968::instance; + this->dialogContentX = dialogContentX; + this->dialogContentY = dialogContentY; + this->dialogContentHeight = dialogContentWidth; + this->dialogContentWidth = dialogContentHeight; + + for (int i = 28; i >= 0; --i) { + this->helpSectionHistoryStack[i + 1] = this->helpSectionHistoryStack[i]; + } + this->helpSectionHistoryStack[0] = this->currentHelpSectionID; + + this->currentHelpSectionID = sectionId; + this->helpContentScrollOffsetY = 0; + MACRO_CALL_MEMBER(OpenSHC::Text::TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/openUnusedHelpTextEditorDialog.cpp b/src/OpenSHC/Text/TextEditorState/openUnusedHelpTextEditorDialog.cpp new file mode 100644 index 00000000..45951bd8 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/openUnusedHelpTextEditorDialog.cpp @@ -0,0 +1,95 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Game/GameCore.func.hpp" + +#include "OpenSHC/Globals/DAT_GameCore.hpp" +#include "OpenSHC/Globals/DAT_UserTextHandlerState.hpp" +#include "OpenSHC/Globals/DAT_WindowAndDirectDraw.hpp" +#include "OpenSHC/Globals/Menu_UnusedHelpTextEditor.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00462190 + void TextEditorState::openUnusedHelpTextEditorDialog(int sectionId) + { + if (this->helpDialogVariant) { + if (this->helpDialogVariant == 2) { + MACRO_CALL_MEMBER(TextEditorState_Func::openScenarioHelpDialog, this)(sectionId); + return; + } + if (this->useInGameHelpHandler) { + MACRO_CALL_MEMBER(TextEditorState_Func::openInGameHelpDialog, this)(sectionId); + return; + } + MACRO_CALL_MEMBER(TextEditorState_Func::openBuildingHelpDialog, this)(sectionId); + return; + } + + if (!this->isDialogStateInitialized) { + this->savedMenuViewType = DAT_GameCore::instance.currentMenuViewType; + this->savedActiveMenuTab = DAT_GameCore::instance.activeMenuTab.tabType; + this->savedMenuFlag = DAT_GameCore::instance.unknownAlwaysZero01; + this->unknown_0x23960 = 1; + this->isDialogStateInitialized = TRUE; + this->useInGameHelpHandler = FALSE; + this->helpDialogVariant = 0; + this->helpDialogSubMode = 0; + this->useAlternateHelpTab = FALSE; + this->isCustomTextMode = FALSE; + this->helpContentScrollX = 0; + this->helpContentScrollY = 0; + this->useWideHelpLayout = FALSE; + DAT_UserTextHandlerState::instance.inputBufferIndex = 0; + } + this->activeHelpHotspotIndex = 0; + if (sectionId == -1) { + MACRO_CALL_MEMBER(TextEditorState_Func::closeHelpDialogAndReturnToMenu, this)(); + return; + } + if (!this->useAlternateHelpTab) { + this->isTextHelpDialogMode = TRUE; + DAT_GameCore::instance.menuTabToSwitchTo.tabType = 0; + MACRO_CALL_MEMBER(Game::GameCore_Func::switchToMenuView, DAT_GameCore::ptr)( + UI::Enums::MVT_UNUSED_HELP_TEXT_EDITOR, 0); + } else { + this->isTextHelpDialogMode = TRUE; + DAT_GameCore::instance.menuTabToSwitchTo.tabType = 1; + MACRO_CALL_MEMBER(Game::GameCore_Func::switchToMenuView, DAT_GameCore::ptr)( + UI::Enums::MVT_UNUSED_HELP_TEXT_EDITOR, 0); + } + Menu_UnusedHelpTextEditor::instance.thousand = 0; + + int const dialogX = DAT_WindowAndDirectDraw::instance.mainMenuBorderWidth + 80; + int const dialogY = DAT_WindowAndDirectDraw::instance.mainMenuBorderHeight + 60; + int const dialogWidth = 640; + int const dialogHeight = 480; + this->dialogX = dialogX; + this->dialogY = dialogY; + this->dialogWidth = dialogWidth; + this->dialogHeight = dialogHeight; + + if (!this->useWideHelpLayout) { + this->dialogContentX = this->dialogX + 10; + this->dialogContentY = this->dialogY + 10; + this->dialogContentHeight = 600; + this->dialogContentWidth = 435; + } else { + this->dialogContentX = this->dialogX + 10; + this->dialogContentY = this->dialogY + 10; + this->dialogContentHeight = 664; + this->dialogContentWidth = 291; + } + + for (int i = 28; i >= 0; --i) { + this->helpSectionHistoryStack[i + 1] = this->helpSectionHistoryStack[i]; + } + this->helpSectionHistoryStack[0] = this->currentHelpSectionID; + + this->currentHelpSectionID = sectionId; + this->helpContentScrollOffsetY = 0; + MACRO_CALL_MEMBER(TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/parseHLPPart.cpp b/src/OpenSHC/Text/TextEditorState/parseHLPPart.cpp new file mode 100644 index 00000000..cc97503d --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/parseHLPPart.cpp @@ -0,0 +1,78 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/OS.func.hpp" + +#include "OpenSHC/Globals/HLP_WCHAR_Buffer.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D200 + LPWSTR TextEditorState::parseHLPPart(FILE* filePointer) + { + + int finishedParsing = FALSE; + int quoteActive = FALSE; + int reachedWEOF = FALSE; + wchar_t* bufferPtr = HLP_WCHAR_Buffer::instance; + while (!reachedWEOF) { + if (finishedParsing) { + return HLP_WCHAR_Buffer::instance; + } + + int readWChar = MACRO_CALL(OS_Func::_fgetwc)(filePointer); + switch (readWChar) { + case L'"': + quoteActive ^= TRUE; + continue; + + case L'\t': + case L' ': + case L',': + case L'=': + if (!quoteActive) { + int consumed = FALSE; + while (!reachedWEOF && !consumed) { + readWChar = MACRO_CALL(OS_Func::_fgetwc)(filePointer); + + if (readWChar == WEOF) { + reachedWEOF = TRUE; + continue; + } + + switch (readWChar) { + default: + MACRO_CALL(OS_Func::_fseek)(filePointer, -2, FILE_CURRENT); + case L'>': + consumed = true; + case L'\t': + case L' ': + case L',': + case L'=': + break; + } + } + } + case L'>': + if (!quoteActive) { + finishedParsing = true; + *bufferPtr = L'\0'; + continue; + } + break; + + case L'\n': + case L'\r': + continue; + + case WEOF: + reachedWEOF = true; + continue; + } + *bufferPtr++ = readWChar; + } + return NULL; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/parseHlp.cpp b/src/OpenSHC/Text/TextEditorState/parseHlp.cpp new file mode 100644 index 00000000..792efc70 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/parseHlp.cpp @@ -0,0 +1,352 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/IO/LowLevelMemory.func.hpp" +#include "OpenSHC/OS.func.hpp" +#include "OpenSHC/UI/Rendering/TextureRenderCore.func.hpp" +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" +#include "OpenSHC/Globals/DAT_TextEditorState.hpp" +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // TODO: fix L-strings + + // FUNCTION: STRONGHOLDCRUSADER 0x0045F5B0 + void TextEditorState::parseHlp() + { + FILE* filePointer[4]; + int graphicIndexes[4][100]; + + int const currentHelpSectionID = this->currentHelpSectionID; + int textMemIndex = 0; + + BOOL headerActive = FALSE; + BOOL bodyActive = FALSE; + int _filePointerIndex = 0; + + int loadedGraphics[4] = { 0, 0, 0, 0 }; + this->customHelpTextLength = 0; + MACRO_CALL_MEMBER(IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 40000, NULL, this->DAT_PointerToTemporaryTextMemory); + filePointer[0] = MACRO_CALL_MEMBER(TextEditorState_Func::readCrusaderHelpHlp, this)( + DAT_UserHelpDefinedData::instance.HelpSections[currentHelpSectionID]); + if (!filePointer[0]) { + return; + } + + while (_filePointerIndex >= 0) { + BOOL closeFile = FALSE; + while (!closeFile) { + int _wchar = MACRO_CALL(OS_Func::_fgetwc)(filePointer[_filePointerIndex]); + switch (_wchar) { + case '\n': + case '\r': + continue; + + case '<': { + wchar_t* hlpTag + = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)(filePointer[_filePointerIndex]); + if (hlpTag) { + if (!MACRO_CALL(OS_Func::__wcsicmp)(L"header", hlpTag)) { + headerActive = TRUE; + continue; + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"\\header", hlpTag)) { + headerActive = FALSE; + continue; + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"body", hlpTag)) { + bodyActive = TRUE; + continue; + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"\\body", hlpTag)) { + bodyActive = FALSE; + continue; + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"loadpic", hlpTag)) { + if (headerActive) { + wchar_t* resourceName = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (resourceName) { + char resourceNameChars[1000]; + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::wideCharToMultiByteComplete, + DAT_WideCharMultiByteState::ptr)(resourceNameChars, resourceName); + + bool validPic = true; + if (!MACRO_CALL_MEMBER( + UI::Rendering::TextureRenderCore_Func::checkGfxResourceExists, + DAT_TextureRenderCoreObject::ptr)(resourceNameChars)) { + validPic = false; + } else if (!MACRO_CALL(OS_Func::__stricmp)( + resourceNameChars, "st99_dog_cage.tgx")) { + validPic = false; + } + if (!validPic) { + graphicIndexes[_filePointerIndex][loadedGraphics[_filePointerIndex]++] = -1; + } else { + graphicIndexes[_filePointerIndex][loadedGraphics[_filePointerIndex]++] + = MACRO_CALL_MEMBER(TextEditorState_Func::findOrAddHelpGraphicName, this)( + resourceNameChars); + } + continue; + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"pic", hlpTag)) { + if (bodyActive) { + wchar_t* picId = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (picId) { + if (MACRO_CALL(OS_Func::__wtol)(picId) < loadedGraphics[_filePointerIndex]) { + if (graphicIndexes[_filePointerIndex][MACRO_CALL(OS_Func::__wtol)(picId)] + != -1) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_PIC; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = graphicIndexes[_filePointerIndex][MACRO_CALL(OS_Func::__wtol)(picId)]; + wchar_t* picPosition = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, + this)(filePointer[_filePointerIndex]); + if (!picPosition) { + closeFile = TRUE; + } else { + if (!MACRO_CALL(OS_Func::__wcsicmp)(L"left", picPosition)) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = HTT_PIC_LEFT; + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"right", picPosition)) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = HTT_PIC_RIGHT; + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"centre", picPosition)) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = HTT_PIC_CENTRE; + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"here", picPosition)) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = HTT_PIC_HERE; + } + } + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_PIC; + continue; + } + } + if (!MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex])) { + closeFile = TRUE; + } + continue; + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"font", hlpTag)) { + if (bodyActive) { + wchar_t* fontId = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (fontId) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_FONT; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = (short)MACRO_CALL(OS_Func::__wtol)(fontId); + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_FONT; + continue; + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"colour", hlpTag)) { + if (bodyActive) { + wchar_t* colorId = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (colorId) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_COLOUR; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = (short)MACRO_CALL(OS_Func::__wtol)(colorId); + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_COLOUR; + continue; + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"linkcolour", hlpTag)) { + if (bodyActive) { + wchar_t* linkColorId = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (linkColorId) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_LINKCOLOUR; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = (short)MACRO_CALL(OS_Func::__wtol)(linkColorId); + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_LINKCOLOUR; + continue; + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"link", hlpTag)) { + if (bodyActive) { + wchar_t* linkName = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (linkName) { + char linkNameChars[1000]; + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::wideCharToMultiByteComplete, + DAT_WideCharMultiByteState::ptr)(linkNameChars, linkName); + int const helpSectionIndex = MACRO_CALL_MEMBER( + TextEditorState_Func::findOrAddHelpSectionName, this)(linkNameChars); + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_LINK; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = helpSectionIndex; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_LINK; + continue; + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"\\link", hlpTag)) { + if (bodyActive) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_ENDLINK; + continue; + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"newparagraph", hlpTag)) { + if (bodyActive) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_NEWPARAGRAPH; + continue; + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"centre", hlpTag)) { + if (bodyActive) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_CENTRE; + continue; + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"\\centre", hlpTag)) { + if (bodyActive) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_ENDCENTRE; + continue; + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"sound", hlpTag)) { + if (bodyActive) { + wchar_t* soundName = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (soundName) { + char soundNameChars[1000]; + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::wideCharToMultiByteComplete, + DAT_WideCharMultiByteState::ptr)(soundNameChars, soundName); + int const soundIndex = MACRO_CALL_MEMBER( + TextEditorState_Func::findOrAddSoundName, this)(soundNameChars); + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_SOUND; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = soundIndex; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_SOUND; + continue; + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"include", hlpTag)) { + if (bodyActive) { + if (DAT_TextEditorState::instance.useAlternateHelpTab) { + wchar_t* includeName = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (includeName) { + char includeNameChars[1000]; + MACRO_CALL_MEMBER( + Util::WideCharMultiByteState_Func::wideCharToMultiByteComplete, + DAT_WideCharMultiByteState::ptr)(includeNameChars, includeName); + int const helpSectionIndex = MACRO_CALL_MEMBER( + TextEditorState_Func::findOrAddHelpSectionName, this)(includeNameChars); + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_INCLUDE; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = helpSectionIndex; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_INCLUDE; + continue; + } + } else { + wchar_t* includeName = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (includeName) { + char includeNameChars[1000]; + MACRO_CALL_MEMBER( + Util::WideCharMultiByteState_Func::wideCharToMultiByteComplete, + DAT_WideCharMultiByteState::ptr)(includeNameChars, includeName); + int sectionId = MACRO_CALL_MEMBER( + TextEditorState_Func::findOrAddHelpSectionName, this)(includeNameChars); + ++_filePointerIndex; + bodyActive = FALSE; + headerActive = FALSE; + loadedGraphics[_filePointerIndex] = 0; + filePointer[_filePointerIndex] + = MACRO_CALL_MEMBER(TextEditorState_Func::readCrusaderHelpHlp, this)( + DAT_UserHelpDefinedData::instance.HelpSections[sectionId]); + continue; + } + } + } + + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"string", hlpTag)) { + if (bodyActive) { + wchar_t* stringId = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)( + filePointer[_filePointerIndex]); + if (stringId) { + if (this->helpDialogVariant) { + long const textIndex = MACRO_CALL(OS_Func::__wtol)(stringId); + + if (this->intArray1[textIndex]) { + int i = 0; + // Mismatch: wrong order of ptr access addition + while (this->intArray1[textIndex][i]) { + wchar_t const ch = this->intArray1[textIndex][i++]; + if (ch == L'\n') { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = HTT_NEWPARAGRAPH; + } else if (ch >= L' ') { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = ch; + } + } + } + + } else { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_STRING; + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] + = (short)MACRO_CALL(OS_Func::__wtol)(stringId); + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = HTT_STRING; + } + continue; + } + } + } else if (!MACRO_CALL(OS_Func::__wcsicmp)(L"\\section", hlpTag)) { + closeFile = TRUE; + continue; + } else { + continue; + } + } + + closeFile = TRUE; + continue; + } + + case L'\u2019': // ’ + _wchar = L'`'; + break; + + case L'\u201C': // “ + case L'\u201D': // ” + _wchar = L'"'; + break; + + case WEOF: + closeFile = TRUE; + continue; + + default: + break; + } + + if (bodyActive) { + this->DAT_PointerToTemporaryTextMemory[textMemIndex++] = _wchar; + } + }; + + MACRO_CALL(OS_Func::_fclose)(filePointer[_filePointerIndex]); + bodyActive = TRUE; + headerActive = FALSE; + --_filePointerIndex; + } + this->customHelpTextLength = textMemIndex; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/popHelpDialogStack.cpp b/src/OpenSHC/Text/TextEditorState/popHelpDialogStack.cpp new file mode 100644 index 00000000..5fd6604c --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/popHelpDialogStack.cpp @@ -0,0 +1,25 @@ +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00462150 + void TextEditorState::popHelpDialogStack() + { + int sectionId = this->helpSectionHistoryStack[0]; + + for (int i = 0; i < 29; ++i) { + this->helpSectionHistoryStack[i] = this->helpSectionHistoryStack[i + 1]; + } + this->helpSectionHistoryStack[29] = -1; + + this->currentHelpSectionID = sectionId; + if (sectionId == -1) { + MACRO_CALL_MEMBER(TextEditorState_Func::closeHelpDialogAndReturnToMenu, this)(); + } else { + MACRO_CALL_MEMBER(TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/processHelpRichTextTokens.cpp b/src/OpenSHC/Text/TextEditorState/processHelpRichTextTokens.cpp new file mode 100644 index 00000000..18379cf6 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/processHelpRichTextTokens.cpp @@ -0,0 +1,817 @@ +// disable deprecation warnings for wcscpy and wcscat +#pragma warning(disable : 4996) + +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Global.func.hpp" +#include "OpenSHC/Input/MouseState.func.hpp" +#include "OpenSHC/Text/FontSizeClass.func.hpp" +#include "OpenSHC/UI/Rendering/PencilRenderCore.func.hpp" + +#include "OpenSHC/Globals/COL_DARK_LIME.hpp" +#include "OpenSHC/Globals/DAT_00df3348.hpp" +#include "OpenSHC/Globals/DAT_00df334c.hpp" +#include "OpenSHC/Globals/DAT_MouseState.hpp" +#include "OpenSHC/Globals/DAT_PencilRenderCore.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + union TextMemUnion { + uint value; + wchar_t* text; + HelpTextToken helpToken; + HelpTextPicturePositionToken picturePositionToken; + }; + + // FUNCTION: STRONGHOLDCRUSADER 0x0045FDC0 + int TextEditorState::processHelpRichTextTokens(int param_1) + { + ushort uVar2; + int iVar5; + wchar_t* pwVar6; + uint uVar10; + int iVar12; + BOOLEnum BVar13; + dword dVar14; + short sVar15; + int iVar17; + int textMemIndex; + dword local_138; + int local_134; + dword currentFontLineHeight; + int local_12c; + int local_11c; + int local_118; + int local_114; + int local_10c; + int local_108; + int local_104; + int local_100; + int local_f8; + dword local_f4; + int local_f0; + int local_e8; + int local_e4; + wchar_t wideTextBuffer[100]; + int currentLinkId = -1; + textMemIndex = 0; + FontSizeClass* currentFontClass = DAT_TextManagerObject::instance.fontSizeClassArray + 17; + currentFontLineHeight = DAT_TextManagerObject::instance.fontSizeClassArray[17].lineHeight_0x14; + local_f0 = 0; + BGR24 color = 0xccfaff; + BGR24 linkColor = 0x8bcf84; + int imageCount = -1; + BOOL centreActive = FALSE; + BOOL local_120 = FALSE; + local_e8 = 0; + local_108 = 0; + local_11c = 0; + local_100 = 0; + local_10c = 0; + local_e4 = 0; + local_134 = -10000; + if (this->helpDialogVariant == 2 || this->isCustomTextMode) { + color = 0xc2f0eb; + } + if (!this->isTextHelpDialogMode) { + return 1; + } + this->unknown_0x23964 = -1; + this->unknown_0x23968 = -1; + if (this->unknown_0x2396C) { + DAT_00df334c::instance = 1; + } + if (this->activeHelpHotspotIndex < 0) { + this->activeHelpHotspotIndex = 0; + } + if (this->customHelpTextLength < this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = this->customHelpTextLength; + } + int lineIndex = -1; + do { + local_138 = this->lineLayoutTable[lineIndex++].unknown0; + } while (local_138 == -1); + while (true) { + iVar5 = textMemIndex; + BGR24 charColor = color; + local_12c = 1; + if (-1 < currentLinkId) { + charColor = linkColor; + } + local_114 = textMemIndex; + TextMemUnion textMemUnion; + textMemUnion.value + = MACRO_CALL_MEMBER(TextEditorState_Func::getWideCharOrWideCharPointer, this)(&textMemIndex); + if (this->useAlternateHelpTab && textMemUnion.value < L' ' && textMemUnion.helpToken != HTT_NEWPARAGRAPH + && iVar5 == this->activeHelpHotspotIndex) { + local_108 = lineIndex + currentFontLineHeight; + local_e8 = lineIndex; + if (param_1 == 1) { + iVar5 = 0; + if (local_120) { + iVar5 = this->lineLayoutTable[lineIndex].unknown2 / 2; + } + local_10c = local_114 - local_11c; + if (this->unknown_0x2396C < 0) { + this->activeHelpHotspotIndex = local_100 + DAT_00df3348::instance; + if (local_11c <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = local_11c - 1; + } + this->unknown_0x2396C = 0; + } + local_134 = 0; + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + this->dialogContentX + iVar5 - 1 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY - 1 + lineIndex, + this->dialogContentX + iVar5 - 1 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + 1 + local_108, + COL_DARK_LIME::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + this->dialogContentX + iVar5 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY - 1 + lineIndex, + this->dialogContentX + iVar5 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + 1 + local_108, + COL_DARK_LIME::instance.shortValue); + local_e4 = 1; + iVar5 = local_114; + } + } + + iVar17 = local_11c; + switch (textMemUnion.helpToken) { + case HTT_PIC: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)(wideTextBuffer, L"DAT_PointerToTemporaryTextMemory[textMemIndex], + this->graphicFileNames[this->DAT_PointerToTemporaryTextMemory[textMemIndex]]); + ++textMemIndex; + switch ((HelpTextPicturePositionToken)this->DAT_PointerToTemporaryTextMemory[textMemIndex] + 1) { + case HTT_PIC_LEFT: + wcscat(wideTextBuffer, L"LEFT>"); + textMemIndex += 2; + break; + case HTT_PIC_CENTRE: + wcscat(wideTextBuffer, L"CENTRE>"); + textMemIndex += 2; + break; + case HTT_PIC_RIGHT: + wcscat(wideTextBuffer, L"RIGHT>"); + textMemIndex += 2; + break; + case HTT_PIC_HERE: + wcscat(wideTextBuffer, L"HERE>"); + textMemIndex += 2; + break; + default: + textMemIndex += 2; + break; + } + break; + } else { + ++imageCount; + if (param_1 == 1) { + if (this->DAT_PointerToTemporaryTextMemory[textMemIndex + 1] == 3) { + uVar10 = this->DAT_PointerToTemporaryTextMemory[textMemIndex]; + goto LAB_0046026d; + } + textMemIndex += 3; + continue; + } + if (param_1 + || (imageCount != this->imageHotspotCount + && this->DAT_PointerToTemporaryTextMemory[textMemIndex + 1] != 3)) { + textMemIndex += 3; + continue; + } + uVar2 = this->DAT_PointerToTemporaryTextMemory[textMemIndex]; + uVar10 = (uint)uVar2; + if (imageCount == this->imageHotspotCount) { + this->imageHotspotTable[this->imageHotspotCount].yPos = lineIndex + 25; + this->imageHotspotTable[this->imageHotspotCount].imageRelated = uVar2; + this->imageHotspotTable[this->imageHotspotCount].unknown3 = currentLinkId; + } + LAB_0046026d: + local_f4 = (dword)this->DAT_PointerToTemporaryTextMemory[textMemIndex + 1]; + iVar5 = DAT_TextureRenderCoreObject::instance.loadedGfxArray[100 - uVar10].width; + dVar14 = DAT_TextureRenderCoreObject::instance.loadedGfxArray[100 - uVar10].height; + sVar15 = (short)iVar5; + switch ((HelpTextPicturePositionToken)local_f4) { + case HTT_PIC_LEFT: + this->imageHotspotTable[this->imageHotspotCount].xPos + = this->lineLayoutTable[lineIndex].unknown0; + for (int i = 0; i < dVar14 + 50; ++i) { + this->lineLayoutTable[lineIndex + i].unknown1 + = this->lineLayoutTable[lineIndex].unknown0 + 25 + sVar15; + } + break; + case HTT_PIC_CENTRE: + this->imageHotspotTable[this->imageHotspotCount].xPos = (this->dialogContentHeight - iVar5) / 2; + for (int i = 0; i < dVar14 + 50; ++i) { + this->lineLayoutTable[lineIndex + i].unknown0 = -1; + } + break; + case HTT_PIC_RIGHT: + this->imageHotspotTable[this->imageHotspotCount].xPos + = this->lineLayoutTable[lineIndex].unknown1 - sVar15; + for (int i = 0; i < dVar14 + 50; ++i) { + this->lineLayoutTable[lineIndex + i].unknown1 + = this->lineLayoutTable[lineIndex].unknown1 - sVar15 - 25; + this->lineLayoutTable[lineIndex + i].unknown0 = -1; + } + break; + case HTT_PIC_HERE: + iVar5 = iVar5 + 3; + if (this->lineLayoutTable[lineIndex].unknown1 < iVar5 + local_138) { + local_f0 = 0; + if (local_120) { + this->lineLayoutTable[lineIndex].unknown2 + = this->lineLayoutTable[lineIndex].unknown1 - local_138; + local_120 = centreActive; + } + do { + lineIndex += currentFontLineHeight + 1; + do { + local_138 = this->lineLayoutTable[lineIndex++].unknown0; + } while (local_138 == -1); + } while (this->lineLayoutTable[lineIndex].unknown1 < local_138 + iVar5); + if (this->useAlternateHelpTab && param_1 == 1) { + ++local_134; + local_100 = local_11c; + local_11c = local_114; + if (0 < this->unknown_0x2396C && 1 < local_134) { + this->activeHelpHotspotIndex = iVar17 + local_10c; + local_134 = -10000; + if (local_114 <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = local_114 + -1; + } + this->unknown_0x2396C = 0; + } + } + currentFontLineHeight = currentFontClass->lineHeight_0x14; + } + if (currentFontLineHeight < dVar14) { + currentFontLineHeight = dVar14; + } + local_138 += iVar5; + if (param_1 != 1 && imageCount == this->imageHotspotCount) { + this->imageHotspotTable[this->imageHotspotCount].xPos = local_138 - iVar5; + this->imageHotspotTable[this->imageHotspotCount].yPos = lineIndex; + ++this->imageHotspotCount; + } + } + textMemIndex += 3; + if (local_f4 == 3 || param_1) { + continue; + } + ++this->imageHotspotCount; + DAT_TextManagerObject::instance.field6_0x18 = 0; + return FALSE; + } + case HTT_FONT: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)( + wideTextBuffer, L"", this->DAT_PointerToTemporaryTextMemory[textMemIndex]); + textMemIndex += 2; + break; + } else { + int fontSize = this->DAT_PointerToTemporaryTextMemory[textMemIndex]; + if (fontSize < 15) { + fontSize += 5; + } + textMemIndex = textMemIndex + 2; + currentFontClass = DAT_TextManagerObject::instance.fontSizeClassArray + fontSize; + dVar14 = DAT_TextManagerObject::instance.fontSizeClassArray[fontSize].lineHeight_0x14; + if (currentFontLineHeight < dVar14 || !local_f0) { + currentFontLineHeight = dVar14; + } + continue; + } + case HTT_COLOUR: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)(wideTextBuffer, L"", + DAT_UserHelpDefinedData::instance + .field6_0x7a16c[this->DAT_PointerToTemporaryTextMemory[textMemIndex]] + .name_0x0); + textMemIndex += 2; + break; + } else { + if (param_1 == 1) { + int const colorIndex = this->DAT_PointerToTemporaryTextMemory[textMemIndex]; + + uint colorRed; + uint colorGreen; + uint colorBlue; + if (this->helpDialogVariant == 2 && colorIndex == 1) { + colorRed = 0xd7; + colorGreen = 0xd2; + colorBlue = 0xa4; + } else { + colorRed = DAT_UserHelpDefinedData::instance.field6_0x7a16c[colorIndex].r_0x4; + colorGreen = DAT_UserHelpDefinedData::instance.field6_0x7a16c[colorIndex].g_0x8; + colorBlue = DAT_UserHelpDefinedData::instance.field6_0x7a16c[colorIndex].b_0xc; + } + textMemIndex += 2; + color = ((colorBlue << 16) & 0xff0000) | ((colorGreen << 8) & 0x00ff00) | colorRed & 0x0000ff; + } else { + textMemIndex += 2; + } + continue; + } + case HTT_LINKCOLOUR: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)(wideTextBuffer, L"", + DAT_UserHelpDefinedData::instance + .field6_0x7a16c[this->DAT_PointerToTemporaryTextMemory[textMemIndex]] + .name_0x0); + textMemIndex += 2; + break; + } else { + if (param_1 == 1) { + int const colorIndex = this->DAT_PointerToTemporaryTextMemory[textMemIndex]; + textMemIndex += 2; + linkColor + = ((DAT_UserHelpDefinedData::instance.field6_0x7a16c[colorIndex].b_0xc << 16) & 0xff0000) + | ((DAT_UserHelpDefinedData::instance.field6_0x7a16c[colorIndex].g_0x8 << 8) & 0x00ff00) + | DAT_UserHelpDefinedData::instance.field6_0x7a16c[colorIndex].r_0x4 & 0x0000ff; + } else { + textMemIndex += 2; + } + continue; + } + case HTT_LINK: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)(wideTextBuffer, L"", + DAT_UserHelpDefinedData::instance + .HelpSections[this->DAT_PointerToTemporaryTextMemory[textMemIndex]]); + textMemIndex += 2; + break; + } else { + currentLinkId = this->DAT_PointerToTemporaryTextMemory[textMemIndex]; + if (param_1 == 1) { + DAT_TextManagerObject::instance.field6_0x18 = 1; + } + textMemIndex += 2; + continue; + } + case HTT_INCLUDE: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)(wideTextBuffer, L"", + DAT_UserHelpDefinedData::instance + .HelpSections[this->DAT_PointerToTemporaryTextMemory[textMemIndex]]); + textMemIndex += 2; + break; + } else { + textMemIndex += 2; + continue; + } + case HTT_SOUND: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)(wideTextBuffer, L"", + this->soundFileNames[this->DAT_PointerToTemporaryTextMemory[textMemIndex]]); + textMemIndex += 2; + break; + } else { + if (param_1 == 1 && -1 < lineIndex - this->helpContentScrollOffsetY + && lineIndex - this->helpContentScrollOffsetY < this->dialogContentWidth + && !this->soundFilePlayedFlags[this->DAT_PointerToTemporaryTextMemory[textMemIndex]]) { + this->soundFilePlayedFlags[this->DAT_PointerToTemporaryTextMemory[textMemIndex]] = 1; + } + textMemIndex += 2; + continue; + } + case HTT_ENDLINK: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + wcscpy(wideTextBuffer, L"<\\LINK>"); + break; + } else { + currentLinkId = -1; + if (param_1 == 1) { + DAT_TextManagerObject::instance.field6_0x18 = 0; + } + continue; + } + case (wchar_t*)13: // unknown case? + default: + pwVar6 = textMemUnion.text; + goto switchD_00460064_caseD_d; + case HTT_STRING: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + MACRO_CALL(Global_Func::PrintToDestination)( + wideTextBuffer, L"", this->DAT_PointerToTemporaryTextMemory[textMemIndex]); + textMemIndex += 2; + break; + } else { + textMemIndex += 2; + continue; + } + case HTT_CENTRE: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + wcscpy(wideTextBuffer, L""); + break; + } else { + centreActive = TRUE; + local_120 = TRUE; + continue; + } + case HTT_ENDCENTRE: + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + wcscpy(wideTextBuffer, L"<\\CENTRE>"); + break; + } else { + centreActive = FALSE; + continue; + } + case HTT_NEWPARAGRAPH: + if (local_120) { + this->lineLayoutTable[lineIndex].unknown2 = this->lineLayoutTable[lineIndex].unknown1 - local_138; + local_120 = centreActive; + } + if (this->useAlternateHelpTab && iVar5 == this->activeHelpHotspotIndex) { + local_108 = currentFontLineHeight + lineIndex; + iVar12 = 0; + local_e8 = lineIndex; + if (param_1 == 1) { + if (local_120) { + iVar12 = this->lineLayoutTable[lineIndex].unknown2 / 2; + } + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + this->dialogContentX + iVar12 - 1 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY - 1 + lineIndex, + this->dialogContentX + iVar12 - 1 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + 1 + local_108, + COL_DARK_LIME::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + this->dialogContentX + iVar12 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY - 1 + lineIndex, + this->dialogContentX + iVar12 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + 1 + local_108, + COL_DARK_LIME::instance.shortValue); + local_e4 = 1; + } + } + lineIndex += 3 + currentFontLineHeight; + local_f0 = 0; + do { + local_138 = this->lineLayoutTable[lineIndex++].unknown0; + } while (local_138 == -1); + currentFontLineHeight = currentFontClass->lineHeight_0x14; + iVar12 = local_11c; + if (this->useAlternateHelpTab != 0) { + local_100 = local_11c; + if (param_1 == 1) { + ++local_134; + if (0 < this->unknown_0x2396C && 1 < local_134) { + this->activeHelpHotspotIndex = local_10c + local_11c; + local_134 = -10000; + if (iVar5 <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = iVar5 + -1; + } + this->unknown_0x2396C = 0; + } + } + iVar12 = iVar5; + if ((iVar5 == this->activeHelpHotspotIndex) && (param_1 == 1)) { + local_10c = 0; + if (this->unknown_0x2396C < 0) { + this->activeHelpHotspotIndex = DAT_00df3348::instance + local_11c; + if (iVar5 <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = iVar5 + -1; + } + this->unknown_0x2396C = 0; + } + local_134 = 0; + } + } + local_11c = iVar12; + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + wcscpy(wideTextBuffer, L""); + break; + } + continue; + case HTT_TAB: // TODO?: unknown token + if (this->helpDialogSubMode == 1) { + charColor = 0xff; + local_12c = 0; + wcscpy(wideTextBuffer, L""); + break; + } else { + if (this->lineLayoutTable[lineIndex].unknown1 < local_138 + 30) { + local_f0 = 0; + if (local_120) { + this->lineLayoutTable[lineIndex].unknown2 + = this->lineLayoutTable[lineIndex].unknown1 - local_138; + local_120 = centreActive; + } + do { + lineIndex += currentFontLineHeight + 1; + do { + local_138 = this->lineLayoutTable[lineIndex++].unknown0; + } while (local_138 == -1); + } while (this->lineLayoutTable[lineIndex].unknown1 < local_138 + 30); + iVar12 = local_11c; + if (this->useAlternateHelpTab && param_1 == 1) { + ++local_134; + local_100 = local_11c; + iVar12 = iVar5; + if (0 < this->unknown_0x2396C && 1 < local_134) { + this->activeHelpHotspotIndex = local_11c + local_10c; + local_134 = -10000; + if (iVar5 <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = iVar5 + -1; + } + this->unknown_0x2396C = 0; + } + } + local_11c = iVar12; + currentFontLineHeight = currentFontClass->lineHeight_0x14; + } + local_138 += 30; + continue; + } + case (wchar_t*)0: // TODO?: unknown token, or just NULL, meaning end? + if (param_1 == 0) { + iVar5 = lineIndex + -1 + currentFontLineHeight; + do { + this->topVisibleLineIndex = iVar5; + if (this->lineLayoutTable[this->topVisibleLineIndex + 1].unknown0 == 25 + && this->lineLayoutTable[this->topVisibleLineIndex + 1].unknown1 + == this->dialogContentHeight - 25) + break; + } while (iVar5 = this->topVisibleLineIndex + 1, this->topVisibleLineIndex + 1 < 20000); + this->topVisibleLineIndex += 6; + if (this->useAlternateHelpTab) { + if (local_e8 < this->helpContentScrollOffsetY) { + this->helpContentScrollOffsetY = local_e8; + } + if (this->helpContentScrollOffsetY + this->dialogContentWidth < local_108) { + this->helpContentScrollOffsetY = (local_108 - this->dialogContentWidth) + 5; + DAT_TextManagerObject::instance.field6_0x18 = 0; + return TRUE; + } + } + DAT_TextManagerObject::instance.field6_0x18 = 0; + return TRUE; + } + if (!this->useAlternateHelpTab) { + DAT_TextManagerObject::instance.field6_0x18 = 0; + return TRUE; + } + DAT_00df3348::instance = local_10c; + if (0 < this->unknown_0x23960 && local_134 == 1) { + this->activeHelpHotspotIndex = local_10c + local_11c; + if (this->customHelpTextLength < this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = this->customHelpTextLength; + } + this->unknown_0x23960 = 0; + } + if (!local_e4 && this->activeHelpHotspotIndex && DAT_00df334c::instance) { + --this->activeHelpHotspotIndex; + this->unknown_0x2396C = 0; + DAT_TextManagerObject::instance.field6_0x18 = 0; + return TRUE; + } + DAT_00df334c::instance = 0; + DAT_TextManagerObject::instance.field6_0x18 = 0; + return TRUE; + } + // NOTE: This is either the local text buffer, or the text directly from the text memory... + pwVar6 = wideTextBuffer; + switchD_00460064_caseD_d: + if (0x1f < (int)pwVar6) { + iVar12 = MACRO_CALL_MEMBER(FontSizeClass_Func::getWidthOfWideText, currentFontClass)( + pwVar6, wcslen((wchar_t*)pwVar6)); + iVar5 = local_11c; + local_f4 = local_138 + iVar12; + if (this->lineLayoutTable[lineIndex].unknown1 < local_f4) { + local_f0 = 0; + if (local_120) { + this->lineLayoutTable[lineIndex].unknown2 + = this->lineLayoutTable[lineIndex].unknown1 - local_138; + local_120 = centreActive; + } + lineIndex += 1 + currentFontLineHeight; + do { + local_138 = this->lineLayoutTable[lineIndex++].unknown0; + } while (local_138 == -1); + currentFontLineHeight = currentFontClass->lineHeight_0x14; + if (this->useAlternateHelpTab) { + ++local_134; + local_100 = local_11c; + local_11c = local_114; + if (0 < this->unknown_0x2396C && 1 < local_134) { + this->activeHelpHotspotIndex = iVar5 + local_10c; + local_134 = -10000; + if (local_114 <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = local_114 - 1; + } + this->unknown_0x2396C = 0; + } + } + local_f4 = iVar12 + local_138; + if (this->lineLayoutTable[lineIndex].unknown1 < (int)local_f4) { + local_f8 = 0; + if (local_120) { + local_f8 = this->lineLayoutTable[lineIndex].unknown2 / 2; + } + int const wideStrLength = wcslen((wchar_t*)pwVar6); + for (local_118 = 0; local_118 < wideStrLength; ++local_118) { + int wideCharWidth = MACRO_CALL_MEMBER( + FontSizeClass_Func::getWideCharWidth, currentFontClass)(textMemUnion.text[local_118]); + while (this->lineLayoutTable[lineIndex].unknown1 < local_138 + wideCharWidth) { + iVar5 = local_11c; + if (local_120) { + this->lineLayoutTable[lineIndex].unknown2 + = this->lineLayoutTable[lineIndex].unknown1 - local_138; + local_120 = centreActive; + } + lineIndex += currentFontLineHeight + 1; + if (this->useAlternateHelpTab && param_1 == 1) { + ++local_134; + local_100 = local_11c; + local_11c = local_114 + local_118; + if (0 < this->unknown_0x2396C && 1 < local_134) { + this->activeHelpHotspotIndex = iVar5 + local_10c; + local_134 = -10000; + if (local_114 + local_118 <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = local_114 + local_118 - 1; + } + this->unknown_0x2396C = 0; + } + } + do { + local_138 = this->lineLayoutTable[lineIndex++].unknown0; + } while (local_138 == -1); + if (local_120) { + local_f8 = this->lineLayoutTable[lineIndex].unknown2 / 2; + } + } + dVar14 = local_138; + if (!this->useAlternateHelpTab || local_114 + local_118 != this->activeHelpHotspotIndex) { + if (param_1 == 1) { + iVar5 = MACRO_CALL_MEMBER(FontSizeClass_Func::renderWideChar, currentFontClass)( + textMemUnion.text[local_118], this->dialogContentX + local_f8 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + lineIndex, charColor, + 0); + local_f0 = 1; + BVar13 = MACRO_CALL_MEMBER( + Input::MouseState_Func::isMouseInsideBox, DAT_MouseState::ptr)( + this->dialogContentX + local_f8 + local_138 - this->helpContentScrollX, + this->dialogContentY - this->helpContentScrollOffsetY + lineIndex + - this->helpContentScrollY, + iVar5 - this->dialogContentX + local_f8 + local_138, currentFontLineHeight + 2); + if (BVar13 != FALSE) { + if (local_12c) { + this->unknown_0x23964 = local_114 + local_118; + this->unknown_0x23968 = currentLinkId; + } else { + this->unknown_0x23964 = local_114; + } + } + } + } else { + iVar5 = lineIndex + currentFontLineHeight; + local_108 = iVar5; + local_e8 = lineIndex; + if (param_1 == 1) { + if (local_12c) { + local_10c = (local_118 - local_11c) + local_114; + if (this->unknown_0x2396C < 0) { + this->activeHelpHotspotIndex = DAT_00df3348::instance + local_100; + if (local_11c <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = local_11c - 1; + } + this->unknown_0x2396C = 0; + } + local_134 = 0; + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, + DAT_PencilRenderCore::ptr)(this->dialogContentX + local_f8 - 1 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + -1 + lineIndex, + this->dialogContentX + local_f8 - 1 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + 1 + iVar5, + COL_DARK_LIME::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, + DAT_PencilRenderCore::ptr)(this->dialogContentX + local_f8 + dVar14, + this->dialogContentY - this->helpContentScrollOffsetY - 1 + lineIndex, + this->dialogContentX + local_f8 + dVar14, + this->dialogContentY - this->helpContentScrollOffsetY + 1 + iVar5, + COL_DARK_LIME::instance.shortValue); + local_e4 = 1; + } + iVar5 = MACRO_CALL_MEMBER(FontSizeClass_Func::renderWideChar, currentFontClass)( + textMemUnion.text[local_118], this->dialogContentX + local_f8 + local_138, + this->dialogContentY - this->helpContentScrollOffsetY + lineIndex, charColor, + 0); + local_f0 = 1; + BVar13 = MACRO_CALL_MEMBER( + Input::MouseState_Func::isMouseInsideBox, DAT_MouseState::ptr)( + this->dialogContentX + local_f8 + local_138 - this->helpContentScrollX, + this->dialogContentY - this->helpContentScrollOffsetY + lineIndex + - this->helpContentScrollY, + iVar5 - this->dialogContentX + local_f8 + local_138, currentFontLineHeight + 2); + if (BVar13 != FALSE) { + if (!local_12c) { + this->unknown_0x23964 = local_114; + } else { + this->unknown_0x23964 = local_114 + local_118; + this->unknown_0x23968 = currentLinkId; + } + } + } + } + local_138 += wideCharWidth; + } + continue; + } + } + iVar5 = this->dialogContentX + local_138; + local_104 = (this->dialogContentY - this->helpContentScrollOffsetY) + lineIndex; + if (local_120) { + iVar5 += this->lineLayoutTable[lineIndex].unknown2 / 2; + } + int const wideStrLength = wcslen((wchar_t*)pwVar6); + for (int i = 0; i < wideStrLength; ++i) { + local_f8 = local_114 - local_11c; + if ((this->useAlternateHelpTab == 0) || (i + local_114 != this->activeHelpHotspotIndex)) { + if (param_1 != 1) + goto LAB_00461201; + LAB_0046117a: + local_f0 = 1; + iVar12 = MACRO_CALL_MEMBER(FontSizeClass_Func::renderWideChar, currentFontClass)( + textMemUnion.text[i], iVar5, local_104, charColor, 0); + BVar13 = MACRO_CALL_MEMBER(Input::MouseState_Func::isMouseInsideBox, DAT_MouseState::ptr)( + iVar5 - this->helpContentScrollX, local_104 - this->helpContentScrollY, iVar12 - iVar5, + currentFontLineHeight + 2); + if (BVar13 != FALSE) { + if (local_12c == 0) { + this->unknown_0x23964 = local_114; + } else { + this->unknown_0x23964 = i + local_114; + this->unknown_0x23968 = currentLinkId; + } + } + } else { + if (param_1 == 1 && local_12c) { + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, + DAT_PencilRenderCore::ptr)(iVar5 + -1, local_104 - 1, iVar5 + -1, + local_104 + 1 + currentFontLineHeight, COL_DARK_LIME::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, + DAT_PencilRenderCore::ptr)(iVar5, local_104 - 1, iVar5, + local_104 + 1 + currentFontLineHeight, COL_DARK_LIME::instance.shortValue); + local_e4 = 1; + } + local_108 = lineIndex + currentFontLineHeight; + local_e8 = lineIndex; + if (param_1 == 1) { + local_10c = local_f8 + i; + local_134 = 0; + if (this->unknown_0x2396C < 0 && local_12c) { + this->activeHelpHotspotIndex = local_100 + DAT_00df3348::instance; + if (local_11c <= this->activeHelpHotspotIndex) { + this->activeHelpHotspotIndex = local_11c + -1; + } + this->unknown_0x2396C = 0; + } + goto LAB_0046117a; + } + LAB_00461201: + dVar14 = MACRO_CALL_MEMBER(FontSizeClass_Func::getWideCharWidth, currentFontClass)( + textMemUnion.text[i]); + iVar12 = iVar5 + dVar14; + } + iVar5 = iVar12; + } + local_138 = local_f4; + } + } + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/readCrusaderHelpHlp.cpp b/src/OpenSHC/Text/TextEditorState/readCrusaderHelpHlp.cpp new file mode 100644 index 00000000..1f6bf9c8 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/readCrusaderHelpHlp.cpp @@ -0,0 +1,66 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/IO/ResourceManager.func.hpp" +#include "OpenSHC/OS.func.hpp" +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" +#include "OpenSHC/string-literals.hpp" + +#include "OpenSHC/Globals/DAT_ResourceManager.hpp" +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // TODO: Replace L-strings with str-ptr + + // FUNCTION: STRONGHOLDCRUSADER 0x0045F470 + FILE* TextEditorState::readCrusaderHelpHlp(LPCSTR searchedPart) + { + this->helpSectionParseSucceeded = FALSE; + + WCHAR searchedPartWide[200]; + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::multiByteToWideCharacter, DAT_WideCharMultiByteState::ptr)( + searchedPartWide, searchedPart); + MACRO_CALL_MEMBER(IO::ResourceManager_Func::resolveResourceFileName, DAT_ResourceManager::ptr)( + IO::FRT_HELP, s_crusader_help_hlp_005a5620); + + char const* const _Filename = MACRO_CALL_MEMBER( + IO::ResourceManager_Func::getFileNameOfCurrentActiveResource, DAT_ResourceManager::ptr)(); + FILE* _File = MACRO_CALL(OS_Func::_fopen)(_Filename, s_rb_005a4e18); + if (_File) { + MACRO_CALL(OS_Func::_fseek)(_File, 2, FILE_BEGIN); // Skip BOM? + + int wideChar; + while (true) { + wideChar = MACRO_CALL(OS_Func::_fgetwc)(_File); + if (wideChar != L'<') { + if (wideChar == WEOF) { + return _File; + } + continue; + } + wchar_t* hlpPart = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)(_File); + if (!hlpPart || MACRO_CALL(OS_Func::__wcsicmp)(L"section", hlpPart)) { + continue; + } + wchar_t* sectionHlpPart = MACRO_CALL_MEMBER(TextEditorState_Func::parseHLPPart, this)(_File); + if (!sectionHlpPart || MACRO_CALL(OS_Func::__wcsicmp)(searchedPartWide, sectionHlpPart)) { + continue; + } + break; + }; + + do { + wideChar = MACRO_CALL(OS_Func::_fgetwc)(_File); + if (wideChar == L'>') { + this->helpSectionParseSucceeded = TRUE; + break; + } + } while (wideChar != WEOF); + } + + return _File; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/renderHelpDialogIfOpen.cpp b/src/OpenSHC/Text/TextEditorState/renderHelpDialogIfOpen.cpp new file mode 100644 index 00000000..13ff6f4a --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/renderHelpDialogIfOpen.cpp @@ -0,0 +1,16 @@ +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x00461550 + void TextEditorState::renderHelpDialogIfOpen() + { + if (this->isDialogStateInitialized) { + MACRO_CALL_MEMBER(TextEditorState_Func::drawHelpWindowBackground, this)(); + MACRO_CALL_MEMBER(TextEditorState_Func::setTextRenderingLogic, this)(); + } + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/renderHelpImageHotspots.cpp b/src/OpenSHC/Text/TextEditorState/renderHelpImageHotspots.cpp new file mode 100644 index 00000000..d468a9d7 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/renderHelpImageHotspots.cpp @@ -0,0 +1,73 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Input/MouseState.func.hpp" +#include "OpenSHC/UI/Rendering/PencilRenderCore.func.hpp" +#include "OpenSHC/UI/Rendering/TextureRenderCore.func.hpp" + +#include "OpenSHC/Globals/COL_GREYISH_YELLOW.hpp" +#include "OpenSHC/Globals/DAT_MouseState.hpp" +#include "OpenSHC/Globals/DAT_PencilRenderCore.hpp" +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D430 + void TextEditorState::renderHelpImageHotspots() + { + for (int i = 0; i < this->imageHotspotCount; ++i) { + int _gfxIndex = 99 - this->imageHotspotTable[i].imageRelated; + if ((this->useInGameHelpHandler || this->helpDialogVariant == 1) + && !MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::checkIfGfxTgxStartsWithTransparentPixels, + DAT_TextureRenderCoreObject::ptr)(_gfxIndex)) { + int x1 = this->imageHotspotTable[i].xPos + this->dialogContentX - 2; + int y1 = this->imageHotspotTable[i].yPos - this->helpContentScrollOffsetY + this->dialogContentY - 2; + int width = DAT_TextureRenderCoreObject::instance.loadedGfxArray[_gfxIndex].width + 3; + int height = DAT_TextureRenderCoreObject::instance.loadedGfxArray[_gfxIndex].height + 3; + if (y1 < this->dialogContentY) { + height += y1 - this->dialogContentY; + y1 = this->dialogContentY; + } + // Does the naming "dialogContentWidth" fit? Is it related to width? + if (height + y1 > this->dialogContentY + this->dialogContentWidth) { + height = this->dialogContentWidth * 2 - y1; + } + int const y2 = y1 + height; + if (y2 >= this->dialogContentY && y1 < this->dialogContentY + this->dialogContentWidth) { + int const x2 = x1 + width; + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x1, y1, x2, y1, COL_GREYISH_YELLOW::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x1, y1 + 1, x2, y1 + 1, COL_GREYISH_YELLOW::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x1, y2, x2, y2, COL_GREYISH_YELLOW::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x1, y2 + -1, x2, y2 + -1, COL_GREYISH_YELLOW::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x1, y1, x1, y2, COL_GREYISH_YELLOW::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x1 + 1, y1, x1 + 1, y2, COL_GREYISH_YELLOW::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x2, y1, x2, y2, COL_GREYISH_YELLOW::instance.shortValue); + MACRO_CALL_MEMBER(UI::Rendering::PencilRenderCore_Func::drawLine, DAT_PencilRenderCore::ptr)( + x2 + -1, y1, x2 + -1, y2, COL_GREYISH_YELLOW::instance.shortValue); + } + } + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::drawGfxOnFlaggedSurface, + DAT_TextureRenderCoreObject::ptr)(_gfxIndex, this->imageHotspotTable[i].xPos + this->dialogContentX, + this->imageHotspotTable[i].yPos - this->helpContentScrollOffsetY + this->dialogContentY); + + int const boxHeight = DAT_TextureRenderCoreObject::instance.loadedGfxArray[_gfxIndex].height; + int const boxWidth = DAT_TextureRenderCoreObject::instance.loadedGfxArray[_gfxIndex].width; + if (MACRO_CALL_MEMBER(Input::MouseState_Func::isMouseInsideBox, DAT_MouseState::ptr)( + this->imageHotspotTable[i].xPos - this->helpContentScrollX + this->dialogContentX, + this->imageHotspotTable[i].yPos - this->helpContentScrollY + this->dialogContentY + - this->helpContentScrollOffsetY, + boxWidth, boxHeight)) { + this->unknown_0x23968 = this->imageHotspotTable[i].unknown3; + } + } + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/resetHelpStateFields.cpp b/src/OpenSHC/Text/TextEditorState/resetHelpStateFields.cpp new file mode 100644 index 00000000..de0e1f34 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/resetHelpStateFields.cpp @@ -0,0 +1,16 @@ +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D0C0 + void TextEditorState::resetHelpStateFields() + { + for (int i = 0; i < 30; ++i) { + this->helpSectionHistoryStack[i] = -1; + } + this->currentHelpSectionID = -1; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/saveHelpFileToResource.cpp b/src/OpenSHC/Text/TextEditorState/saveHelpFileToResource.cpp new file mode 100644 index 00000000..1ae12edc --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/saveHelpFileToResource.cpp @@ -0,0 +1,118 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/IO/ResourceManager.func.hpp" +#include "OpenSHC/OS.func.hpp" +#include "OpenSHC/string-literals.hpp" + +#include "OpenSHC/Globals/DAT_ResourceManager.hpp" +#include "OpenSHC/Globals/DAT_UserHelpDefinedData.hpp" + +namespace OpenSHC { +namespace Text { + + // TODO: Replace L strings with references from a file + + // FUNCTION: STRONGHOLDCRUSADER 0x0045DB40 + void TextEditorState::saveHelpFileToResource() + { + MACRO_CALL_MEMBER(IO::ResourceManager_Func::resolveResourceFileName, DAT_ResourceManager::ptr)( + IO::FRT_HELP, DAT_UserHelpDefinedData::instance.HelpSections[this->currentHelpSectionID]); + char const* const _Filename = MACRO_CALL_MEMBER( + IO::ResourceManager_Func::getFileNameOfCurrentActiveResource, DAT_ResourceManager::ptr)(); + FILE* _File = MACRO_CALL(OS_Func::_fopen)(_Filename, s_wb_005a5510); + if (!_File) { + return; + } + wchar_t const utf16bom = L'\uFEFF'; + MACRO_CALL(OS_Func::_fwrite)((void*)&utf16bom, sizeof(wchar_t), 1, _File); + + MACRO_CALL(OS_Func::_fwprintf)(_File, L"
\n"); + for (int i = 0; i < this->graphicFileCount; ++i) { + MACRO_CALL(OS_Func::_fwprintf)(_File, L"\n", this->graphicFileNames[i]); + } + MACRO_CALL(OS_Func::_fwprintf)(_File, L"<\\HEADER>\n"); + MACRO_CALL(OS_Func::_fwprintf)(_File, L"\n"); + + for (int i = 0; this->DAT_PointerToTemporaryTextMemory[i];) { + HelpTextToken const switchValue = (HelpTextToken)this->DAT_PointerToTemporaryTextMemory[i]; + i += 1; + switch (switchValue) { + case HTT_PIC: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"DAT_PointerToTemporaryTextMemory[i]); + i += 1; + switch ((HelpTextPicturePositionToken)this->DAT_PointerToTemporaryTextMemory[i]) { + case HTT_PIC_LEFT: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"LEFT>"); + i += 2; + break; + case HTT_PIC_RIGHT: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"RIGHT>"); + i += 2; + break; + case HTT_PIC_CENTRE: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"CENTRE>"); + i += 2; + break; + case HTT_PIC_HERE: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"HERE>"); + default: + i += 2; + break; + } + break; + case HTT_FONT: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"", this->DAT_PointerToTemporaryTextMemory[i]); + i += 2; + break; + case HTT_COLOUR: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"", this->DAT_PointerToTemporaryTextMemory[i]); + i += 2; + break; + case HTT_LINKCOLOUR: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"", this->DAT_PointerToTemporaryTextMemory[i]); + i += 2; + break; + case HTT_LINK: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"", + DAT_UserHelpDefinedData::instance.HelpSections[this->DAT_PointerToTemporaryTextMemory[i]]); + i += 2; + break; + case HTT_INCLUDE: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"", + DAT_UserHelpDefinedData::instance.HelpSections[this->DAT_PointerToTemporaryTextMemory[i]]); + i += 2; + break; + case HTT_ENDLINK: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"<\\LINK>"); + break; + case HTT_NEWPARAGRAPH: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"\n\n"); + break; + case HTT_CENTRE: + MACRO_CALL(OS_Func::_fwprintf)(_File, L""); + break; + case HTT_ENDCENTRE: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"<\\CENTRE>"); + break; + case HTT_SOUND: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"", this->DAT_PointerToTemporaryTextMemory[i]); + i += 2; + break; + case HTT_STRING: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"", this->DAT_PointerToTemporaryTextMemory[i]); + i += 2; + break; + default: + MACRO_CALL(OS_Func::_fwprintf)(_File, L"%c", (wchar_t)switchValue); + break; + } + } + + MACRO_CALL(OS_Func::_fwprintf)(_File, L"\n<\\BODY>\n"); + MACRO_CALL(OS_Func::_fclose)(_File); + } + +#undef MACRO_TEXT_ACCESS + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/setCustomHelpText.cpp b/src/OpenSHC/Text/TextEditorState/setCustomHelpText.cpp new file mode 100644 index 00000000..83c6495a --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/setCustomHelpText.cpp @@ -0,0 +1,24 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/Util/WideCharMultiByteState.func.hpp" + +#include "OpenSHC/Globals/DAT_WideCharMultiByteState.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x004620F0 + void TextEditorState::setCustomHelpText(char* helpText, int bufferSize) + { + this->customHelpTextPointer = helpText; + this->isCustomHelpTextWide = 0; + this->customHelpTextBufferSize = bufferSize; + MACRO_CALL_MEMBER(Util::WideCharMultiByteState_Func::multiByteToWideCharacter, DAT_WideCharMultiByteState::ptr)( + this->DAT_PointerToTemporaryTextMemory, helpText); + this->customHelpTextLength = strlen(helpText); + this->isTextHelpDialogMode = TRUE; + MACRO_CALL_MEMBER(TextEditorState_Func::loadAndLayoutHelpContent, this)(); + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/setHelpWindowBounds.cpp b/src/OpenSHC/Text/TextEditorState/setHelpWindowBounds.cpp new file mode 100644 index 00000000..ba116919 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/setHelpWindowBounds.cpp @@ -0,0 +1,16 @@ +#include "../TextEditorState.func.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x0045D080 + void TextEditorState::setHelpWindowBounds(undefined4 x, undefined4 y, undefined4 height, undefined4 width) + { + this->dialogContentX = x; + this->dialogContentY = y; + this->dialogContentHeight = height; + this->dialogContentWidth = width; + } + +} +} diff --git a/src/OpenSHC/Text/TextEditorState/setTextRenderingLogic.cpp b/src/OpenSHC/Text/TextEditorState/setTextRenderingLogic.cpp new file mode 100644 index 00000000..72ef3128 --- /dev/null +++ b/src/OpenSHC/Text/TextEditorState/setTextRenderingLogic.cpp @@ -0,0 +1,55 @@ +#include "../TextEditorState.func.hpp" + +#include "OpenSHC/UI/Rendering/TextureRenderCore.func.hpp" + +#include "OpenSHC/Globals/DAT_PencilRenderCore.hpp" +#include "OpenSHC/Globals/DAT_TextManagerObject.hpp" +#include "OpenSHC/Globals/DAT_TextureRenderCoreObject.hpp" + +namespace OpenSHC { +namespace Text { + + // FUNCTION: STRONGHOLDCRUSADER 0x004613E0 + void TextEditorState::setTextRenderingLogic() + { + if (this->helpDialogVariant != 1) { + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::setRenderingRect, + DAT_TextureRenderCoreObject::ptr)(this->dialogContentX, this->dialogContentY, + this->dialogContentHeight + this->dialogContentX, this->dialogContentWidth + this->dialogContentY); + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::setScreenMenuSurfaceHeightRange, + DAT_TextureRenderCoreObject::ptr)( + this->dialogContentY, this->dialogContentWidth + this->dialogContentY); + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = Rendering::Enums::RT_SCREEN_MENU; + } else { + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::setRenderingRect, + DAT_TextureRenderCoreObject::ptr)(this->dialogContentX, this->dialogContentY, + this->dialogContentHeight + this->dialogContentX, this->dialogContentWidth + this->dialogContentY); + MACRO_CALL_MEMBER( + UI::Rendering::TextureRenderCore_Func::setMapSurfaceHeightRange, DAT_TextureRenderCoreObject::ptr)( + this->dialogContentY, this->dialogContentWidth + this->dialogContentY); + DAT_TextManagerObject::instance.textSurfaceTarget = Rendering::Enums::RT_MAP_GAME; + DAT_PencilRenderCore::instance.surfaceTarget = Rendering::Enums::RT_MAP_GAME; + DAT_TextureRenderCoreObject::instance.currentRenderSurfaceIdentifierUnk_0x8 = Rendering::Enums::RT_MAP_GAME; + } + MACRO_CALL_MEMBER(TextEditorState_Func::processHelpRichTextTokens, this)(TRUE); + MACRO_CALL_MEMBER(TextEditorState_Func::renderHelpImageHotspots, this)(); + if (this->helpDialogVariant != 1) { + DAT_TextureRenderCoreObject::instance.drawBufferChoiceValue = Rendering::Enums::RT_MAP_GAME; + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::setScreenMenuSurfaceHeightRangeToResolution, + DAT_TextureRenderCoreObject::ptr)(); + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::setRenderingRectToGameResolution, + DAT_TextureRenderCoreObject::ptr)(); + } else { + MACRO_CALL_MEMBER( + UI::Rendering::TextureRenderCore_Func::setMapSurfaceHeightRangeUnk, DAT_TextureRenderCoreObject::ptr)(); + MACRO_CALL_MEMBER(UI::Rendering::TextureRenderCore_Func::setRenderingRectToGameResolution, + DAT_TextureRenderCoreObject::ptr)(); + DAT_TextManagerObject::instance.textSurfaceTarget = Rendering::Enums::RT_SCREEN_MENU; + DAT_PencilRenderCore::instance.surfaceTarget = Rendering::Enums::RT_SCREEN_MENU; + DAT_TextureRenderCoreObject::instance.currentRenderSurfaceIdentifierUnk_0x8 + = Rendering::Enums::RT_SCREEN_MENU; + } + } + +} +} diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index 10a0c2b0..1257d83c 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -18147,17 +18147,17 @@ SHC_3BB0A8C1_0x0045CD10 | 0.0% | Pending SHC_3BB0A8C1_0x0045D060 | 0.0% | Pending -SHC_3BB0A8C1_0x0045D080 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D080 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0045D0B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0045D0C0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D0C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D140 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D140 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D1A0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D1A0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D200 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D200 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0045D300 | 0.0% | Pending @@ -18327,41 +18327,41 @@ SHC_3BB0A8C1_0x0045D364 | 0.0% | Pending SHC_3BB0A8C1_0x0045D365 | 0.0% | Pending -SHC_3BB0A8C1_0x0045D370 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D370 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D3C0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D3C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D430 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D430 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0045D460 | 0.0% | Pending -SHC_3BB0A8C1_0x0045D690 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D690 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D6C0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D6C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D740 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D740 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D890 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D890 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D8F0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D8F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D950 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D950 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D990 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D990 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045D9E0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045D9E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045DA20 | 0.0% | Pending +SHC_3BB0A8C1_0x0045DA20 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045DA40 | 0.0% | Pending +SHC_3BB0A8C1_0x0045DA40 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0045DA60 | 0.0% | Pending -SHC_3BB0A8C1_0x0045DA80 | 0.0% | Pending +SHC_3BB0A8C1_0x0045DA80 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045DAE0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045DAE0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045DB40 | 0.0% | Pending +SHC_3BB0A8C1_0x0045DB40 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0045DDF4 | 0.0% | Pending @@ -18709,7 +18709,7 @@ SHC_3BB0A8C1_0x0045EF84 | 0.0% | Pending SHC_3BB0A8C1_0x0045EF90 | 0.0% | Pending -SHC_3BB0A8C1_0x0045F080 | 0.0% | Pending +SHC_3BB0A8C1_0x0045F080 | 100.0% | Reimplemented SHC_3BB0A8C1_0x0045F0B4 | 0.0% | Pending @@ -18745,19 +18745,19 @@ SHC_3BB0A8C1_0x0045F0CC | 0.0% | Pending SHC_3BB0A8C1_0x0045F0CD | 0.0% | Pending -SHC_3BB0A8C1_0x0045F0D0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045F0D0 | 100.0% | Reimplemented, requires SHC_3BB0A8C1_0x0045F130 active SHC_3BB0A8C1_0x0045F120 | 0.0% | Pending -SHC_3BB0A8C1_0x0045F130 | 0.0% | Pending +SHC_3BB0A8C1_0x0045F130 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045F240 | 0.0% | Pending +SHC_3BB0A8C1_0x0045F240 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045F470 | 0.0% | Pending +SHC_3BB0A8C1_0x0045F470 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045F580 | 0.0% | Pending +SHC_3BB0A8C1_0x0045F580 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0045F5B0 | 0.0% | Pending +SHC_3BB0A8C1_0x0045F5B0 | 99.0% | Reimplemented, two cases where an "edx + ecx" is flipped to "ecx + edx" SHC_3BB0A8C1_0x0045FDC0 | 0.0% | Pending @@ -18825,15 +18825,15 @@ SHC_3BB0A8C1_0x004613D0 | 0.0% | Pending SHC_3BB0A8C1_0x004613D4 | 0.0% | Pending -SHC_3BB0A8C1_0x004613E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004613E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004614D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004614D0 | 100.0% | Reimplemented SHC_3BB0A8C1_0x004614F0 | 0.0% | Pending SHC_3BB0A8C1_0x00461520 | 0.0% | Pending -SHC_3BB0A8C1_0x00461550 | 0.0% | Pending +SHC_3BB0A8C1_0x00461550 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00461570 | 0.0% | Pending @@ -18879,23 +18879,23 @@ SHC_3BB0A8C1_0x004619C4 | 0.0% | Pending SHC_3BB0A8C1_0x004619C8 | 0.0% | Pending -SHC_3BB0A8C1_0x004619D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004619D0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00461A20 | 0.0% | Pending +SHC_3BB0A8C1_0x00461A20 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00461B90 | 0.0% | Pending +SHC_3BB0A8C1_0x00461B90 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00461CF0 | 0.0% | Pending +SHC_3BB0A8C1_0x00461CF0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00461E50 | 0.0% | Pending +SHC_3BB0A8C1_0x00461E50 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00461F90 | 0.0% | Pending +SHC_3BB0A8C1_0x00461F90 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004620F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004620F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00462150 | 0.0% | Pending +SHC_3BB0A8C1_0x00462150 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00462190 | 0.0% | Pending +SHC_3BB0A8C1_0x00462190 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00462340 | 0.0% | Pending