From d723ebce1a2a99dbd07251fc1718cba1f807f783 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Wed, 19 May 2021 02:03:47 +0200 Subject: [PATCH] Render help text using common text rendering --- Source/control.cpp | 4 +- Source/engine/render/text_render.cpp | 9 +- Source/engine/render/text_render.hpp | 2 +- Source/help.cpp | 251 +++++++++++---------------- 4 files changed, 114 insertions(+), 152 deletions(-) diff --git a/Source/control.cpp b/Source/control.cpp index 87a16c217..264c76203 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -1687,13 +1687,13 @@ void DrawGoldSplit(const CelOutputBuffer &out, int amount) initialDropGoldValue), initialDropGoldValue); WordWrapGameString(tempstr, 200); - DrawString(out, tempstr, { dialogX + 31, 87, 200, 50 }, UIS_GOLD | UIS_CENTER); + DrawString(out, tempstr, { dialogX + 31, 87, 200, 50 }, UIS_GOLD | UIS_CENTER, 1, 17); tempstr[0] = '\0'; if (amount > 0) { sprintf(tempstr, "%u", amount); } - DrawString(out, tempstr, { dialogX + 37, 140, 0, 0 }, UIS_SILVER, true); + DrawString(out, tempstr, { dialogX + 37, 140, 0, 0 }, UIS_SILVER, 1, -1, true); } void control_drop_gold(char vkey) diff --git a/Source/engine/render/text_render.cpp b/Source/engine/render/text_render.cpp index e9839e39c..028595a0e 100644 --- a/Source/engine/render/text_render.cpp +++ b/Source/engine/render/text_render.cpp @@ -116,7 +116,7 @@ const uint8_t fontkern[3][68] = { } }; -int LineHeights[3] = { 17, 43, 50 }; +int LineHeights[3] = { 12, 43, 50 }; std::optional pPanelText; /** Graphics for the medium size font */ @@ -268,7 +268,7 @@ void WordWrapGameString(char *text, size_t width, size_t size, int spacing) /** * @todo replace SDL_Rect with croped CelOutputBuffer */ -void DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rect, uint16_t flags, int spacing, bool drawTextCursor) +void DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rect, uint16_t flags, int spacing, int lineHeight, bool drawTextCursor) { GameFontTables size = GameFontSmall; if ((flags & UIS_MED) != 0) @@ -310,6 +310,9 @@ void DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &re int rightMargin = rect.x + w; int bottomMargin = rect.y + h; + if (lineHeight == -1) + lineHeight = LineHeights[size]; + for (unsigned i = 0; i < textLength; i++) { uint8_t frame = fontframe[size][gbFontTransTbl[static_cast(text[i])]]; int symbolWidth = fontkern[size][frame]; @@ -325,7 +328,7 @@ void DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &re sx += (w - lineWidth) / 2; else if ((flags & UIS_RIGHT) != 0) sx += w - lineWidth; - sy += LineHeights[size]; + sy += lineHeight; if (sy > bottomMargin) return; } diff --git a/Source/engine/render/text_render.hpp b/Source/engine/render/text_render.hpp index f782238aa..ad6b5fa35 100644 --- a/Source/engine/render/text_render.hpp +++ b/Source/engine/render/text_render.hpp @@ -61,7 +61,7 @@ void PrintChar(const CelOutputBuffer &out, int sx, int sy, int nCel, text_color */ int GetLineWidth(const char *text, GameFontTables size = GameFontSmall, int spacing = 1, int *charactersInLine = nullptr); void WordWrapGameString(char *text, size_t width, size_t size = GameFontSmall, int spacing = 1); -void DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rect, uint16_t flags = 0, int spacing = 1, bool drawTextCursor = false); +void DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rect, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false); int PentSpn2Spin(); } // namespace devilution diff --git a/Source/help.cpp b/Source/help.cpp index 1c2e5ee10..6b57dfd1c 100644 --- a/Source/help.cpp +++ b/Source/help.cpp @@ -3,6 +3,8 @@ * * Implementation of the in-game help text. */ +#include +#include #include "control.h" #include "engine/render/text_render.hpp" @@ -10,182 +12,140 @@ #include "minitext.h" #include "stores.h" #include "utils/language.h" +#include "utils/stdcompat/string_view.hpp" namespace devilution { -int help_select_line; +unsigned int SkipLines; bool helpflag; -int HelpTop; - -const char gszHelpText[] = { - // TRANSLATORS: HUGE KEY. There might be changes in a future version where redundant keys between the shareware help and the full game help will be consolidated. - N_("$Keyboard Shortcuts:|" - "F1: Open Help Screen|" - "Esc: Display Main Menu|" - "Tab: Display Auto-map|" - "Space: Hide all info screens|" - "S: Open Speedbook|" - "B: Open Spellbook|" - "I: Open Inventory screen|" - "C: Open Character screen|" - "Q: Open Quest log|" - "F: Reduce screen brightness|" - "G: Increase screen brightness|" - "Z: Zoom Game Screen|" - "+ / -: Zoom Automap|" - "1 - 8: Use Belt item|" - "F5, F6, F7, F8: Set hotkey for skill or spell|" - "Shift + Left Mouse Button: Attack without moving|" - "Shift + Left Mouse Button (on character screen): Assign all stat points|" - "Shift + Left Mouse Button (on inventory): Move item to belt or equip/unequip item|" - "Shift + Left Mouse Button (on belt): Move item to inventory|" - "|" - "$Movement:|" - "If you hold the mouse button down while moving, the character " - "will continue to move in that direction.|" - "|" - "$Combat:|" - "Holding down the shift key and then left-clicking allows the " - "character to attack without moving.|" - "|" - "$Auto-map:|" - "To access the auto-map, click the 'MAP' button on the " + +const char *const gszHelpText[] = { + N_("$Keyboard Shortcuts:"), + N_("F1: Open Help Screen"), + N_("Esc: Display Main Menu"), + N_("Tab: Display Auto-map"), + N_("Space: Hide all info screens"), + N_("S: Open Speedbook"), + N_("B: Open Spellbook"), + N_("I: Open Inventory screen"), + N_("C: Open Character screen"), + N_("Q: Open Quest log"), + N_("F: Reduce screen brightness"), + N_("G: Increase screen brightness"), + N_("Z: Zoom Game Screen"), + N_("+ / -: Zoom Automap"), + N_("1 - 8: Use Belt item"), + N_("F5, F6, F7, F8: Set hotkey for skill or spell"), + N_("Shift + Left Mouse Button: Attack without moving"), + N_("Shift + Left Mouse Button (on character screen): Assign all stat points"), + N_("Shift + Left Mouse Button (on inventory): Move item to belt or equip/unequip item"), + N_("Shift + Left Mouse Button (on belt): Move item to inventory"), + "", + N_("$Movement:"), + N_("If you hold the mouse button down while moving, the character " + "will continue to move in that direction."), + "", + N_("$Combat:"), + N_("Holding down the shift key and then left-clicking allows the " + "character to attack without moving."), + "", + N_("$Auto-map:"), + N_("To access the auto-map, click the 'MAP' button on the " "Information Bar or press 'TAB' on the keyboard. Zooming in and " "out of the map is done with the + and - keys. Scrolling the map " - "uses the arrow keys.|" - "|" - "$Picking up Objects:|" - "Useable items that are small in size, such as potions or scrolls, " + "uses the arrow keys."), + "", + N_("$Picking up Objects:"), + N_("Useable items that are small in size, such as potions or scrolls, " "are automatically placed in your 'belt' located at the top of " "the Interface bar . When an item is placed in the belt, a small " "number appears in that box. Items may be used by either pressing " - "the corresponding number or right-clicking on the item.|" - "|" - "$Gold|" - "You can select a specific amount of gold to drop by" - "right-clicking on a pile of gold in your inventory.|" - "|" - "$Skills & Spells:|" - "You can access your list of skills and spells by left-clicking on " + "the corresponding number or right-clicking on the item."), + "", + N_("$Gold"), + N_("You can select a specific amount of gold to drop by" + "right-clicking on a pile of gold in your inventory."), + "", + N_("$Skills & Spells:"), + N_("You can access your list of skills and spells by left-clicking on " "the 'SPELLS' button in the interface bar. Memorized spells and " "those available through staffs are listed here. Left-clicking on " "the spell you wish to cast will ready the spell. A readied spell " - "may be cast by simply right-clicking in the play area.|" - "|" - "$Using the Speedbook for Spells|" - "Left-clicking on the 'readied spell' button will open the 'Speedbook' " + "may be cast by simply right-clicking in the play area."), + "", + N_("$Using the Speedbook for Spells"), + N_("Left-clicking on the 'readied spell' button will open the 'Speedbook' " "which allows you to select a skill or spell for immediate use. " "To use a readied skill or spell, simply right-click in the main play " - "area.|" - "Shift + Left-clicking on the 'select current spell' button will clear the readied spell|" - "|" - "$Setting Spell Hotkeys|" - "You can assign up to four Hotkeys for skills, spells or scrolls. " + "area."), + N_("Shift + Left-clicking on the 'select current spell' button will clear the readied spell"), + "", + N_("$Setting Spell Hotkeys"), + N_("You can assign up to four Hotkeys for skills, spells or scrolls. " "Start by opening the 'speedbook' as described in the section above. " "Press the F5, F6, F7 or F8 keys after highlighting the spell you " - "wish to assign.|" - "|" - "$Spell Books|" - "Reading more than one book increases your knowledge of that " - "spell, allowing you to cast the spell more effectively.|" - "&") + "wish to assign."), + "", + N_("$Spell Books"), + N_("Reading more than one book increases your knowledge of that " + "spell, allowing you to cast the spell more effectively."), }; +std::vector HelpTextLines; + void InitHelp() { helpflag = false; -} + char tempstr[512]; -static void DrawHelpLine(const CelOutputBuffer &out, int x, int y, char *text, uint16_t style) -{ - const int sx = x + 32 + PANEL_X; - const int sy = y * 12 + 44 + UI_OFFSET_Y; - DrawString(out, text, { sx, sy, 577, 0 }, style); + for (auto text : gszHelpText) { + strcpy(tempstr, _(text)); + + WordWrapGameString(tempstr, 577); + const string_view paragraph = tempstr; + + size_t previous = 0; + while (true) { + size_t next = paragraph.find("\n", previous); + HelpTextLines.emplace_back(paragraph.substr(previous, next)); + if (next == std::string::npos) + break; + previous = next + 1; + } + } } void DrawHelp(const CelOutputBuffer &out) { - int i, c, w; - const char *s; - DrawSTextHelp(); DrawQTextBack(out); - PrintSString(out, 0, 2, gbIsHellfire ? _("Hellfire Help") : _("Diablo Help"), UIS_GOLD | UIS_CENTER); + + const char *title; + if (gbIsHellfire) + title = gbIsSpawn ? _("Shareware Hellfire Help") : _("Hellfire Help"); + else + title = gbIsSpawn ? _("Shareware Diablo Help") : _("Diablo Help"); + PrintSString(out, 0, 2, title, UIS_GOLD | UIS_CENTER); + DrawSLine(out, 5); - s = _(&gszHelpText[0]); + const int sx = PANEL_X + 32; + const int sy = UI_OFFSET_Y + 51; - for (i = 0; i < help_select_line; i++) { - c = 0; - w = 0; - while (*s == '\0') { - s++; - } - if (*s == '$') { - s++; - } - if (*s == '&') { + for (int i = 7; i < 22; i++) { + const char *line = HelpTextLines[i - 7 + SkipLines].c_str(); + if (line[0] == '\0') { continue; } - while (*s != '|' && w < 577) { - while (*s == '\0') { - s++; - } - tempstr[c] = *s; - w += fontkern[GameFontSmall][fontframe[GameFontSmall][gbFontTransTbl[(BYTE)tempstr[c]]]] + 1; - c++; - s++; - } - if (w >= 577) { - c--; - while (tempstr[c] != ' ') { - s--; - c--; - } - } - if (*s == '|') { - s++; - } - } - for (i = 7; i < 22; i++) { - c = 0; - w = 0; - while (*s == '\0') { - s++; - } + + int offset = 0; uint16_t style = UIS_SILVER; - if (*s == '$') { - s++; + if (line[0] == '$') { + offset = 1; style = UIS_RED; } - if (*s == '&') { - HelpTop = help_select_line; - continue; - } - while (*s != '|' && w < 577) { - while (*s == '\0') { - s++; - } - tempstr[c] = *s; - BYTE tc = gbFontTransTbl[(BYTE)tempstr[c]]; - w += fontkern[GameFontSmall][fontframe[GameFontSmall][tc]] + 1; - c++; - s++; - } - if (w >= 577) { - c--; - while (tempstr[c] != ' ') { - s--; - c--; - } - } - if (c != 0) { - tempstr[c] = '\0'; - DrawHelpLine(out, 0, i, tempstr, style); - } - if (*s == '|') { - s++; - } + + DrawString(out, &line[offset], { sx, sy + i * 12, 577, 0 }, style); } PrintSString(out, 0, 23, _("Press ESC to end or the arrow keys to scroll."), UIS_GOLD | UIS_CENTER); @@ -193,21 +153,20 @@ void DrawHelp(const CelOutputBuffer &out) void DisplayHelp() { - help_select_line = 0; + SkipLines = 0; helpflag = true; - HelpTop = 5000; } void HelpScrollUp() { - if (help_select_line > 0) - help_select_line--; + if (SkipLines > 0) + SkipLines--; } void HelpScrollDown() { - if (help_select_line < HelpTop) - help_select_line++; + if (SkipLines < HelpTextLines.size() - 15) + SkipLines++; } } // namespace devilution