Skip to content

Commit

Permalink
Improve DiabloMsg handling
Browse files Browse the repository at this point in the history
1. Simplified implementation.
2. Now adjusts the box size to fit the content (e.g. when wrapping
   failed or when there are too many lines).
  • Loading branch information
glebm committed Oct 14, 2023
1 parent d1d27c8 commit 88bbf4f
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 55 deletions.
2 changes: 1 addition & 1 deletion Source/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
#include "controls/modifier_hints.h"
#include "controls/plrctrls.h"
#include "cursor.h"
#include "diablo_msg.hpp"
#include "engine/backbuffer_state.hpp"
#include "engine/clx_sprite.hpp"
#include "engine/load_cel.hpp"
#include "engine/render/clx_render.hpp"
#include "engine/render/text_render.hpp"
#include "engine/trn.hpp"
#include "diablo_msg.hpp"
#include "gamemenu.h"
#include "init.h"
#include "inv.h"
Expand Down
2 changes: 1 addition & 1 deletion Source/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
#include "automap.h"
#include "control.h"
#include "cursor.h"
#include "diablo_msg.hpp"
#include "engine/backbuffer_state.hpp"
#include "engine/events.hpp"
#include "engine/load_cel.hpp"
#include "engine/point.hpp"
#include "diablo_msg.hpp"
#include "inv.h"
#include "levels/setmaps.h"
#include "lighting.h"
Expand Down
2 changes: 1 addition & 1 deletion Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "controls/plrctrls.h"
#include "controls/remap_keyboard.h"
#include "diablo.h"
#include "diablo_msg.hpp"
#include "discord/discord.h"
#include "doom.h"
#include "encrypt.h"
Expand All @@ -35,7 +36,6 @@
#include "engine/load_file.hpp"
#include "engine/random.hpp"
#include "engine/sound.h"
#include "diablo_msg.hpp"
#include "gamemenu.h"
#include "gmenu.h"
#include "help.h"
Expand Down
76 changes: 31 additions & 45 deletions Source/diablo_msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
#include "diablo_msg.hpp"

#include "DiabloUI/ui_flags.hpp"
#include "control.h"
#include "engine/clx_sprite.hpp"
#include "engine/render/clx_render.hpp"
#include "engine/render/text_render.hpp"
#include "panels/info_box.hpp"
#include "utils/algorithm/container.hpp"
#include "utils/language.h"
#include "utils/timer.hpp"
#include "utils/str_split.hpp"

namespace devilution {

Expand All @@ -30,32 +29,29 @@ struct MessageEntry {
};

std::deque<MessageEntry> DiabloMessages;
uint32_t msgStartTime = 0;
uint32_t msgStartTime;
std::vector<std::string> TextLines;
int OuterHeight = 54;
const int LineWidth = 418;
int OuterHeight;
int LineWidth;
int LineHeight;

int LineHeight()
{
return IsSmallFontTall() ? 18 : 12;
}

void InitNextLines()
void InitDiabloMsg()
{
TextLines.clear();
if (DiabloMessages.empty())
return;

const std::string paragraphs = WordWrapString(DiabloMessages.front().text, LineWidth, GameFont12, 1);

size_t previous = 0;
while (true) {
const size_t next = paragraphs.find('\n', previous);
TextLines.emplace_back(paragraphs.substr(previous, next - previous));
if (next == std::string::npos)
break;
previous = next + 1;
LineWidth = 418;
const std::string_view text = DiabloMessages.front().text;
const std::string wrapped = WordWrapString(text, LineWidth, GameFont12);
for (const std::string_view line : SplitByChar(wrapped, '\n')) {
LineWidth = std::max(LineWidth, GetLineWidth(text, GameFont12));
TextLines.emplace_back(line);
}

OuterHeight = std::max(54, static_cast<int>((TextLines.size() * LineHeight()) + 42));
msgStartTime = SDL_GetTicks();
LineHeight = GetLineHeight(text, GameFont12);
OuterHeight = static_cast<int>((TextLines.size()) * LineHeight) + 42;
}

} // namespace
Expand Down Expand Up @@ -126,17 +122,13 @@ void InitDiabloMsg(diablo_message e, uint32_t duration /*= 3500*/)

void InitDiabloMsg(std::string_view msg, uint32_t duration /*= 3500*/)
{
if (DiabloMessages.size() >= MAX_SEND_STR_LEN)
return;

if (c_find_if(DiabloMessages, [&msg](const MessageEntry &entry) { return entry.text == msg; })
!= DiabloMessages.end())
return;

DiabloMessages.push_back({ std::string(msg), duration });
if (DiabloMessages.size() == 1) {
InitNextLines();
msgStartTime = SDL_GetTicks();
InitDiabloMsg();
}
}

Expand All @@ -149,10 +141,7 @@ void CancelCurrentDiabloMsg()
{
if (!DiabloMessages.empty()) {
DiabloMessages.pop_front();
if (!DiabloMessages.empty()) {
InitNextLines();
msgStartTime = SDL_GetTicks();
}
InitDiabloMsg();
}
}

Expand All @@ -176,14 +165,16 @@ void DrawDiabloMsg(const Surface &out)
const int borderPartWidth = 12;
const int borderPartHeight = 12;

const int outerHeight = OuterHeight;
const int outerWidth = 429;
const int textPaddingX = 5;
const int borderThickness = 3;

const int outerHeight = std::min<int>(out.h(), OuterHeight);
const int outerWidth = std::min<int>(out.w(), LineWidth + 2 * borderThickness + textPaddingX);
const int innerWidth = outerWidth - 2 * borderThickness;
const int lineWidth = innerWidth - textPaddingX;
const int innerHeight = outerHeight - 2 * borderThickness;

const Point uiRectanglePosition = GetUIRectangle().position;
const Point topLeft { uiRectanglePosition.x + 101, ((gnScreenHeight - GetMainPanel().size.height - outerHeight) / 2) - borderThickness };
const Point topLeft { (out.w() - outerWidth) / 2, (out.h() - outerHeight) / 2 };

const int innerXBegin = topLeft.x + borderThickness;
const int innerXEnd = innerXBegin + innerWidth;
Expand All @@ -210,25 +201,20 @@ void DrawDiabloMsg(const Surface &out)
}
DrawHalfTransparentRectTo(out, innerXBegin, innerYBegin, innerWidth, innerHeight);

const int lineHeight = LineHeight();
const int textX = innerXBegin + 5;
int textY = innerYBegin + (innerHeight - lineHeight * static_cast<int>(TextLines.size())) / 2;
const int textX = innerXBegin + textPaddingX;
int textY = innerYBegin + (innerHeight - LineHeight * static_cast<int>(TextLines.size())) / 2;
for (const std::string &line : TextLines) {
DrawString(out, line, { { textX, textY }, { LineWidth, lineHeight } }, UiFlags::AlignCenter, 1, lineHeight);
textY += lineHeight;
DrawString(out, line, { { textX, textY }, { lineWidth, LineHeight } }, UiFlags::AlignCenter, 1, LineHeight);
textY += LineHeight;
}

// Calculate the time the current message has been displayed
const uint32_t currentTime = SDL_GetTicks();
const uint32_t messageElapsedTime = currentTime - msgStartTime;
const uint32_t messageElapsedTime = SDL_GetTicks() - msgStartTime;

// Check if the current message's duration has passed
if (!DiabloMessages.empty() && messageElapsedTime >= DiabloMessages.front().duration) {
DiabloMessages.pop_front();
if (!DiabloMessages.empty()) {
InitNextLines();
msgStartTime = currentTime;
}
InitDiabloMsg();
}
}

Expand Down
4 changes: 2 additions & 2 deletions Source/engine/render/scrollrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "controls/plrctrls.h"
#include "cursor.h"
#include "dead.h"
#include "diablo_msg.hpp"
#include "doom.h"
#include "engine/backbuffer_state.hpp"
#include "engine/dx.h"
Expand All @@ -21,7 +22,6 @@
#include "engine/render/text_render.hpp"
#include "engine/trn.hpp"
#include "engine/world_tile.hpp"
#include "diablo_msg.hpp"
#include "gmenu.h"
#include "help.h"
#include "hwcursor.hpp"
Expand Down Expand Up @@ -1194,7 +1194,7 @@ void DrawView(const Surface &out, Point startPosition)
DrawChatLog(out);
}
if (IsDiabloMsgAvailable()) {
DrawDiabloMsg(out);
DrawDiabloMsg(out.subregionY(0, out.h() - GetMainPanel().size.height));
}
if (MyPlayerIsDead) {
RedBack(out);
Expand Down
2 changes: 1 addition & 1 deletion Source/gamemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
#include "gamemenu.h"

#include "cursor.h"
#include "diablo_msg.hpp"
#include "engine/backbuffer_state.hpp"
#include "engine/events.hpp"
#include "engine/sound.h"
#include "engine/sound_defs.hpp"
#include "diablo_msg.hpp"
#include "gmenu.h"
#include "init.h"
#include "loadsave.h"
Expand Down
2 changes: 1 addition & 1 deletion Source/objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
#ifdef _DEBUG
#include "debug.h"
#endif
#include "diablo_msg.hpp"
#include "engine/backbuffer_state.hpp"
#include "engine/load_cel.hpp"
#include "engine/load_file.hpp"
#include "engine/points_in_rectangle_range.hpp"
#include "engine/random.hpp"
#include "diablo_msg.hpp"
#include "init.h"
#include "inv.h"
#include "inv_iterators.hpp"
Expand Down
4 changes: 2 additions & 2 deletions Source/panels/info_box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
namespace devilution {

/**
* @brief Info box frame
* @brief Fixed size info box frame
*
* Used in stores, the quest log, the help window, and the unique item info window.
*/
extern OptionalOwnedClxSpriteList pSTextBoxCels;

/**
* @brief Info box scrollbar graphics.
* @brief Dynamic size info box frame and scrollbar graphics.
*
* Used in stores and `DrawDiabloMsg`.
*/
Expand Down
2 changes: 1 addition & 1 deletion Source/qol/chatlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
#include "automap.h"
#include "chatlog.h"
#include "control.h"
#include "diablo_msg.hpp"
#include "doom.h"
#include "engine/render/text_render.hpp"
#include "diablo_msg.hpp"
#include "gamemenu.h"
#include "help.h"
#include "init.h"
Expand Down

0 comments on commit 88bbf4f

Please sign in to comment.