Browse Source

Refactor Draw* functions to use Rectangle and Point types

Added overload for DrawString taking a Point to avoid creating a rect for callers which only use position. This also documents the way DrawString operates when passed a clipping rectangle with a dimension of 0.
As part of this overload removed the logic for 0 width regions from DrawString. This does change the behaviour of the Rectangle version if called with a rect with width 0, all callers using that behaviour have been updated in this commit.

Using Rectangle/Size allowed simplifying the logic for certain calls where they could use DrawText alignment flags, previously this was manually aligning by calculating dimensions and offsetting the position. This also fixes #2169

Also includes a few instances where a temporary buffer was used to set the text to be drawn with unbounded sprintf calls, replaced those with snprintf as is recommended in modern C applications. Moving to C++ strings would be good in a future refactor.
pull/2224/head
Andrew James 5 years ago committed by GitHub
parent
commit
60a47caf1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      Source/automap.cpp
  2. 46
      Source/control.cpp
  3. 26
      Source/controls/modifier_hints.cpp
  4. 42
      Source/engine/render/text_render.cpp
  5. 48
      Source/engine/render/text_render.hpp
  6. 4
      Source/gmenu.cpp
  7. 10
      Source/inv.cpp
  8. 14
      Source/items.cpp
  9. 2
      Source/scrollrt.cpp
  10. 16
      Source/stores.cpp

14
Source/automap.cpp

@ -383,24 +383,24 @@ uint16_t GetAutomapType(Point map, bool view)
void DrawAutomapText(const CelOutputBuffer &out)
{
char desc[256];
int nextLine = 20;
Point linePosition { 8, 20 };
if (gbIsMultiplayer) {
if (strcasecmp("0.0.0.0", szPlayerName) != 0) {
strcat(strcpy(desc, _("game: ")), szPlayerName);
DrawString(out, desc, { 8, nextLine, 0, 0 });
nextLine += 15;
DrawString(out, desc, linePosition);
linePosition.y += 15;
}
if (szPlayerDescript[0] != '\0') {
strcat(strcpy(desc, _("password: ")), szPlayerDescript);
DrawString(out, desc, { 8, nextLine, 0, 0 });
nextLine += 15;
DrawString(out, desc, linePosition);
linePosition.y += 15;
}
}
if (setlevel) {
DrawString(out, _(quest_level_names[setlvlnum]), { 8, nextLine, 0, 0 });
DrawString(out, _(quest_level_names[setlvlnum]), linePosition);
return;
}
@ -413,7 +413,7 @@ void DrawAutomapText(const CelOutputBuffer &out)
strcpy(desc, fmt::format(_("Level: {:d}"), currlevel).c_str());
}
DrawString(out, desc, { 8, nextLine, 0, 0 });
DrawString(out, desc, linePosition);
}
}

46
Source/control.cpp

@ -324,15 +324,13 @@ static void DrawSpell(const CelOutputBuffer &out)
static void PrintSBookHotkey(const CelOutputBuffer &out, Point position, const std::string &text)
{
int &x = position.x;
int &y = position.y;
x -= GetLineWidth(text.c_str()) + 5;
x += SPLICONLENGTH;
y += 17;
y -= SPLICONLENGTH;
DrawString(out, text.c_str(), { x - 1, y + 1, 0, 0 }, UIS_BLACK);
DrawString(out, text.c_str(), { x + 0, y + 0, 0, 0 }, UIS_SILVER);
// Align the hot key text with the top-right corner of the spell icon
position += { SPLICONLENGTH - (GetLineWidth(text.c_str()) + 5), 17 - SPLICONLENGTH };
// Draw a drop shadow below and to the left of the text
DrawString(out, text.c_str(), position + Point { -1, 1 }, UIS_BLACK);
// Then draw the text over the top
DrawString(out, text.c_str(), position, UIS_SILVER);
}
void DrawSpellList(const CelOutputBuffer &out)
@ -1104,7 +1102,7 @@ static void PrintInfo(const CelOutputBuffer &out)
if (talkflag)
return;
SDL_Rect line { PANEL_X + 177, PANEL_Y + LineOffsets[pnumlines][0], 288, 0 };
Rectangle line { PANEL_X + 177, PANEL_Y + LineOffsets[pnumlines][0], 288, 0 };
int yo = 0;
int lo = 1;
@ -1115,7 +1113,7 @@ static void PrintInfo(const CelOutputBuffer &out)
}
for (int i = 0; i < pnumlines; i++) {
line.y = PANEL_Y + LineOffsets[pnumlines - lo][i + yo];
line.position.y = PANEL_Y + LineOffsets[pnumlines - lo][i + yo];
DrawString(out, panelstr[i], line, infoclr | UIS_CENTER | UIS_FIT_SPACING, 2);
}
}
@ -1700,22 +1698,40 @@ void DrawGoldSplit(const CelOutputBuffer &out, int amount)
CelDrawTo(out, { dialogX, 178 }, *pGBoxBuff, 1);
strcpy(
constexpr auto bufferSize = sizeof(tempstr) / sizeof(*tempstr);
// strncpy copies up to the maximum number of characters specified, it does not ensure that a null character is
// written to the end of the c-string. To be safe we specify a limit one character shorter than the buffer size and
// ensure that the buffer ends in a null character manually.
strncpy(
tempstr,
fmt::format(ngettext(
/* TRANSLATORS: {:d} is a number. Dialog is shown when splitting a stash of Gold.*/ "You have {:d} gold piece. How many do you want to remove?",
"You have {:d} gold pieces. How many do you want to remove?",
initialDropGoldValue),
initialDropGoldValue)
.c_str());
.c_str(),
bufferSize - 1);
// Ensure the prompt shown to the player is terminated properly (in case the formatted/translated string ends up
// being longer than 255 characters)
tempstr[bufferSize - 1] = '\0';
// Pre-wrap the string at spaces, otherwise DrawString would hard wrap in the middle of words
WordWrapGameString(tempstr, 200);
// The split gold dialog is roughly 4 lines high, but we need at least one line for the player to input an amount.
// Using a clipping region 50 units high (approx 3 lines with a lineheight of 17) to ensure there is enough room left
// for the text entered by the player.
DrawString(out, tempstr, { dialogX + 31, 87, 200, 50 }, UIS_GOLD | UIS_CENTER, 1, 17);
tempstr[0] = '\0';
if (amount > 0) {
sprintf(tempstr, "%u", amount);
// snprintf ensures that the destination buffer ends in a null character.
snprintf(tempstr, bufferSize, "%u", amount);
}
DrawString(out, tempstr, { dialogX + 37, 140, 0, 0 }, UIS_SILVER, 1, -1, true);
// Even a ten digit amount of gold only takes up about half a line. There's no need to wrap or clip text here so we
// use the Point form of DrawString.
DrawString(out, tempstr, Point { dialogX + 37, 140 }, UIS_SILVER, 1, -1, true);
}
void control_drop_gold(char vkey)

26
Source/controls/modifier_hints.cpp

@ -98,16 +98,20 @@ uint16_t CircleMenuHintTextColor(bool active)
return active ? UIS_BLUE : UIS_GOLD;
}
void DrawCircleMenuHint(const CelOutputBuffer &out, const CircleMenuHint &hint, int x, int y)
/**
* @brief Draws hint text for a four button layout with the top/left edge of the bounding box at the position given by origin.
* @param out The output buffer to draw on.
* @param hint Struct describing the text to draw and the dimensions of the layout.
* @param origin Top left corner of the layout (relative to the output buffer).
*/
void DrawCircleMenuHint(const CelOutputBuffer &out, const CircleMenuHint &hint, const Point &origin)
{
DrawString(out, hint.top, { x + hint.xMid - hint.topW / 2, y, 0, 0 }, CircleMenuHintTextColor(IsTopActive(hint)));
y += LineHeight;
DrawString(out, hint.top, origin + Point { hint.xMid - hint.topW / 2, 0 }, CircleMenuHintTextColor(IsTopActive(hint)));
DrawString(out, hint.left, { x, y, 0, 0 }, CircleMenuHintTextColor(IsLeftActive(hint)));
DrawString(out, hint.right, { x + hint.leftW + MidSpaces * SpaceWidth(), y, 0, 0 }, CircleMenuHintTextColor(IsRightActive(hint)));
y += LineHeight;
DrawString(out, hint.left, origin + Point { 0, LineHeight }, CircleMenuHintTextColor(IsLeftActive(hint)));
DrawString(out, hint.right, origin + Point { hint.leftW + MidSpaces * SpaceWidth(), LineHeight }, CircleMenuHintTextColor(IsRightActive(hint)));
DrawString(out, hint.bottom, { x + hint.xMid - hint.bottomW / 2, y, 0, 0 }, CircleMenuHintTextColor(IsBottomActive(hint)));
DrawString(out, hint.bottom, origin + Point { hint.xMid - hint.bottomW / 2, LineHeight * 2 }, CircleMenuHintTextColor(IsBottomActive(hint)));
}
void DrawStartModifierMenu(const CelOutputBuffer &out)
@ -116,8 +120,8 @@ void DrawStartModifierMenu(const CelOutputBuffer &out)
return;
static const CircleMenuHint DPad(/*isDpad=*/true, /*top=*/_("Menu"), /*right=*/_("Inv"), /*bottom=*/_("Map"), /*left=*/_("Char"));
static const CircleMenuHint Buttons(/*isDpad=*/false, /*top=*/"", /*right=*/"", /*bottom=*/_("Spells"), /*left=*/_("Quests"));
DrawCircleMenuHint(out, DPad, PANEL_LEFT + CircleMarginX, PANEL_TOP - CircleTop);
DrawCircleMenuHint(out, Buttons, PANEL_LEFT + PANEL_WIDTH - Buttons.Width() - CircleMarginX, PANEL_TOP - CircleTop);
DrawCircleMenuHint(out, DPad, { PANEL_LEFT + CircleMarginX, PANEL_TOP - CircleTop });
DrawCircleMenuHint(out, Buttons, { PANEL_LEFT + PANEL_WIDTH - Buttons.Width() - CircleMarginX, PANEL_TOP - CircleTop });
}
void DrawSelectModifierMenu(const CelOutputBuffer &out)
@ -126,10 +130,10 @@ void DrawSelectModifierMenu(const CelOutputBuffer &out)
return;
if (sgOptions.Controller.bDpadHotkeys) {
static const CircleMenuHint DPad(/*isDpad=*/true, /*top=*/"F6", /*right=*/"F8", /*bottom=*/"F7", /*left=*/"F5");
DrawCircleMenuHint(out, DPad, PANEL_LEFT + CircleMarginX, PANEL_TOP - CircleTop);
DrawCircleMenuHint(out, DPad, { PANEL_LEFT + CircleMarginX, PANEL_TOP - CircleTop });
}
static const CircleMenuHint Spells(/*isDpad=*/false, "F6", "F8", "F7", "F5");
DrawCircleMenuHint(out, Spells, PANEL_LEFT + PANEL_WIDTH - Spells.Width() - CircleMarginX, PANEL_TOP - CircleTop);
DrawCircleMenuHint(out, Spells, { PANEL_LEFT + PANEL_WIDTH - Spells.Width() - CircleMarginX, PANEL_TOP - CircleTop });
}
} // namespace

42
Source/engine/render/text_render.cpp

@ -269,9 +269,9 @@ void WordWrapGameString(char *text, size_t width, GameFontTables size, int spaci
}
/**
* @todo replace SDL_Rect with cropped CelOutputBuffer
* @todo replace Rectangle with cropped CelOutputBuffer
*/
int DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rect, uint16_t flags, int spacing, int lineHeight, bool drawTextCursor)
int DrawString(const CelOutputBuffer &out, const char *text, const Rectangle &rect, uint16_t flags, int spacing, int lineHeight, bool drawTextCursor)
{
GameFontTables size = GameFontSmall;
if ((flags & UIS_MED) != 0)
@ -289,9 +289,6 @@ int DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rec
else if ((flags & UIS_BLACK) != 0)
color = ColorBlack;
const int w = rect.w != 0 ? rect.w : out.w() - rect.x;
const int h = rect.h != 0 ? rect.h : out.h() - rect.y;
const size_t textLength = strlen(text);
int charactersInLine = 0;
@ -301,17 +298,18 @@ int DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rec
int maxSpacing = spacing;
if ((flags & UIS_FIT_SPACING) != 0)
spacing = AdjustSpacingToFitHorizontally(lineWidth, maxSpacing, charactersInLine, rect.w);
spacing = AdjustSpacingToFitHorizontally(lineWidth, maxSpacing, charactersInLine, rect.size.width);
int sx = rect.x;
Point characterPosition = rect.position;
int sx = rect.position.x;
if ((flags & UIS_CENTER) != 0)
sx += (w - lineWidth) / 2;
characterPosition.x += (rect.size.width - lineWidth) / 2;
else if ((flags & UIS_RIGHT) != 0)
sx += w - lineWidth;
int sy = rect.y;
characterPosition.x += rect.size.width - lineWidth;
characterPosition.y = rect.position.y;
int rightMargin = rect.x + w;
int bottomMargin = rect.y + h;
int rightMargin = rect.position.x + rect.size.width;
int bottomMargin = rect.size.height != 0 ? rect.position.y + rect.size.height : out.h();
if (lineHeight == -1)
lineHeight = LineHeights[size];
@ -320,31 +318,31 @@ int DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rec
for (; i < textLength; i++) {
uint8_t frame = FontFrame[size][FontIndex[static_cast<uint8_t>(text[i])]];
int symbolWidth = FontKern[size][frame];
if (text[i] == '\n' || sx + symbolWidth > rightMargin) {
if (sy + lineHeight >= bottomMargin)
if (text[i] == '\n' || characterPosition.x + symbolWidth > rightMargin) {
if (characterPosition.y + lineHeight >= bottomMargin)
break;
sy += lineHeight;
characterPosition.y += lineHeight;
if ((flags & (UIS_CENTER | UIS_RIGHT | UIS_FIT_SPACING)) != 0)
lineWidth = GetLineWidth(&text[i + 1], size, spacing, &charactersInLine);
if ((flags & UIS_FIT_SPACING) != 0)
spacing = AdjustSpacingToFitHorizontally(lineWidth, maxSpacing, charactersInLine, rect.w);
spacing = AdjustSpacingToFitHorizontally(lineWidth, maxSpacing, charactersInLine, rect.size.width);
sx = rect.x;
characterPosition.x = rect.position.x;
if ((flags & UIS_CENTER) != 0)
sx += (w - lineWidth) / 2;
characterPosition.x += (rect.size.width - lineWidth) / 2;
else if ((flags & UIS_RIGHT) != 0)
sx += w - lineWidth;
characterPosition.x += rect.size.width - lineWidth;
}
if (frame != 0) {
DrawChar(out, { sx, sy }, size, frame, color);
DrawChar(out, characterPosition, size, frame, color);
}
if (text[i] != '\n')
sx += symbolWidth + spacing;
characterPosition.x += symbolWidth + spacing;
}
if (drawTextCursor) {
CelDrawTo(out, { sx, sy }, *pSPentSpn2Cels, PentSpn2Spin());
CelDrawTo(out, characterPosition, *pSPentSpn2Cels, PentSpn2Spin());
}
return i;

48
Source/engine/render/text_render.hpp

@ -12,6 +12,7 @@
#include "DiabloUI/ui_item.h"
#include "engine.h"
#include "engine/cel_sprite.hpp"
#include "engine/rectangle.hpp"
#include "utils/stdcompat/optional.hpp"
namespace devilution {
@ -36,7 +37,52 @@ void InitText();
*/
int GetLineWidth(const char *text, GameFontTables size = GameFontSmall, int spacing = 1, int *charactersInLine = nullptr);
void WordWrapGameString(char *text, size_t width, GameFontTables size = GameFontSmall, int spacing = 1);
int DrawString(const CelOutputBuffer &out, const char *text, const SDL_Rect &rect, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false);
/**
* @brief Draws a line of text within a clipping rectangle (positioned relative to the origin of the output buffer).
*
* Specifying a small width (0 to less than two characters wide) should be avoided as this causes issues when laying
* out the text. To wrap based on available space use the overload taking a Point. If the rect passed through has 0
* height then the clipping area is extended to the bottom edge of the output buffer. If the clipping rectangle
* dimensions extend past the edge of the output buffer text wrapping will be calculated using those dimensions (as if
* the text was being rendered off screen). The text will not actually be drawn beyond the bounds of the output
* buffer, this is purely to allow for clipping without wrapping.
*
* @param out The screen buffer to draw on.
* @param text String to be drawn.
* @param rect Clipping region relative to the output buffer describing where to draw the text and when to wrap long lines.
* @param flags A combination of UiFlags to describe font size, color, alignment, etc. See ui_items.h for available options
* @param spacing Additional space to add between characters.
* This value may be adjusted if the flag UIS_FIT_SPACING is passed in the flags parameter.
* @param lineHeight Allows overriding the default line height, useful for multi-line strings.
* @param drawTextCursor Whether to draw an animated cursor sprite at the end of the text (default is to display nothing).
* @return The number of characters rendered, including characters "drawn" outside the buffer.
*/
int DrawString(const CelOutputBuffer &out, const char *text, const Rectangle &rect, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false);
/**
* @brief Draws a line of text at the given position relative to the origin of the output buffer.
*
* This method is provided as a convenience to pass through to DrawString(..., Rectangle, ...) when no explicit
* clipping/wrapping is requested. Note that this will still wrap the rendered string if it would end up being drawn
* beyond the right edge of the output buffer and clip it if it would extend beyond the bottom edge of the buffer.
*
* @param out The screen buffer to draw on.
* @param text String to be drawn.
* @param position Location of the top left corner of the string relative to the top left corner of the output buffer.
* @param flags A combination of UiFlags to describe font size, color, alignment, etc. See ui_items.h for available options
* @param spacing Additional space to add between characters.
* This value may be adjusted if the flag UIS_FIT_SPACING is passed in the flags parameter.
* @param lineHeight Allows overriding the default line height, useful for multi-line strings.
* @param drawTextCursor Whether to draw an animated cursor sprite at the end of the text (default is to display nothing).
* @return The number of characters rendered (could be less than the string length if it wrapped past the bottom of the buffer).
*/
inline int DrawString(const CelOutputBuffer &out, const char *text, const Point &position, uint16_t flags = 0, int spacing = 1, int lineHeight = -1, bool drawTextCursor = false)
{
return DrawString(out, text, { position.x, position.y, out.w() - position.x, 0 }, flags, spacing, lineHeight, drawTextCursor);
}
int PentSpn2Spin();
} // namespace devilution

4
Source/gmenu.cpp

@ -41,7 +41,7 @@ void gmenu_draw_pause(const CelOutputBuffer &out)
RedBack(out);
if (sgpCurrentMenu == nullptr) {
light_table_index = 0;
DrawString(out, _("Pause"), { PANEL_LEFT + 252, PANEL_TOP / 2, 0, 0 }, UIS_HUGE, 2);
DrawString(out, _("Pause"), Point { 0, PANEL_TOP / 2 }, UIS_HUGE | UIS_CENTER, 2);
}
}
@ -177,7 +177,7 @@ static void GmenuDrawMenuItem(const CelOutputBuffer &out, TMenuItem *pItem, int
int x = (gnScreenWidth - w) / 2;
uint16_t style = (pItem->dwFlags & GMENU_ENABLED) != 0 ? UIS_SILVER : UIS_BLACK;
DrawString(out, _(pItem->pszStr), { x, y, 0, 0 }, style | UIS_HUGE, 2);
DrawString(out, _(pItem->pszStr), Point { x, y }, style | UIS_HUGE, 2);
if (pItem == sgpCurrItem) {
CelDrawTo(out, { x - 54, y + 1 }, *PentSpin_cel, PentSpn2Spin());
CelDrawTo(out, { x + 4 + w, y + 1 }, *PentSpin_cel, PentSpn2Spin());

10
Source/inv.cpp

@ -330,14 +330,8 @@ void DrawInvBelt(const CelOutputBuffer &out)
if (AllItemsList[myPlayer.SpdList[i].IDidx].iUsable
&& myPlayer.SpdList[i]._iStatFlag
&& myPlayer.SpdList[i]._itype != ITYPE_GOLD) {
sprintf(tempstr, "%i", i + 1);
SDL_Rect rect {
InvRect[i + SLOTXY_BELT_FIRST].x + PANEL_X + InventorySlotSizeInPixels.width - GetLineWidth(tempstr),
InvRect[i + SLOTXY_BELT_FIRST].y + PANEL_Y - 1,
0,
0
};
DrawString(out, tempstr, rect, UIS_SILVER);
snprintf(tempstr, sizeof(tempstr) / sizeof(*tempstr), "%i", i + 1);
DrawString(out, tempstr, { position, InventorySlotSizeInPixels }, UIS_SILVER | UIS_RIGHT);
}
}
}

14
Source/items.cpp

@ -3689,37 +3689,37 @@ void DrawUniqueInfo(const CelOutputBuffer &out)
DrawUTextBack(GlobalBackBuffer());
SDL_Rect rect { 32 + RIGHT_PANEL - SPANEL_WIDTH, 44 + 2 * 12, 257, 0 };
Rectangle rect { 32 + RIGHT_PANEL - SPANEL_WIDTH, 44 + 2 * 12, 257, 0 };
const UItemStruct &uitem = UniqueItemList[curruitem._iUid];
DrawString(out, _(uitem.UIName), rect, UIS_CENTER);
DrawULine(out, 5);
rect.y += (12 - uitem.UINumPL) * 12;
rect.position.y += (12 - uitem.UINumPL) * 12;
PrintItemPower(uitem.UIPower1, &curruitem);
DrawString(out, tempstr, rect, UIS_SILVER | UIS_CENTER);
if (uitem.UINumPL > 1) {
rect.y += 2 * 12;
rect.position.y += 2 * 12;
PrintItemPower(uitem.UIPower2, &curruitem);
DrawString(out, tempstr, rect, UIS_SILVER | UIS_CENTER);
}
if (uitem.UINumPL > 2) {
rect.y += 2 * 12;
rect.position.y += 2 * 12;
PrintItemPower(uitem.UIPower3, &curruitem);
DrawString(out, tempstr, rect, UIS_SILVER | UIS_CENTER);
}
if (uitem.UINumPL > 3) {
rect.y += 2 * 12;
rect.position.y += 2 * 12;
PrintItemPower(uitem.UIPower4, &curruitem);
DrawString(out, tempstr, rect, UIS_SILVER | UIS_CENTER);
}
if (uitem.UINumPL > 4) {
rect.y += 2 * 12;
rect.position.y += 2 * 12;
PrintItemPower(uitem.UIPower5, &curruitem);
DrawString(out, tempstr, rect, UIS_SILVER | UIS_CENTER);
}
if (uitem.UINumPL > 5) {
rect.y += 2 * 12;
rect.position.y += 2 * 12;
PrintItemPower(uitem.UIPower6, &curruitem);
DrawString(out, tempstr, rect, UIS_SILVER | UIS_CENTER);
}

2
Source/scrollrt.cpp

@ -1441,7 +1441,7 @@ static void DrawFPS(const CelOutputBuffer &out)
frameend = 0;
}
snprintf(String, 12, "%i FPS", framerate);
DrawString(out, String, { 8, 65, 0, 0 }, UIS_RED);
DrawString(out, String, Point { 8, 65 }, UIS_RED);
}
}

16
Source/stores.cpp

@ -2219,21 +2219,21 @@ void FreeStoreMem()
pSTextSlidCels = std::nullopt;
}
static void DrawSelector(const CelOutputBuffer &out, const SDL_Rect &rect, const char *text, uint16_t flags)
static void DrawSelector(const CelOutputBuffer &out, const Rectangle &rect, const char *text, uint16_t flags)
{
int lineWidth = GetLineWidth(text);
int x1 = rect.x - 20;
int x1 = rect.position.x - 20;
if ((flags & UIS_CENTER) != 0)
x1 += (rect.w - lineWidth) / 2;
x1 += (rect.size.width - lineWidth) / 2;
CelDrawTo(out, { x1, rect.y + 1 }, *pSPentSpn2Cels, PentSpn2Spin());
CelDrawTo(out, { x1, rect.position.y + 1 }, *pSPentSpn2Cels, PentSpn2Spin());
int x2 = rect.x + rect.w + 5;
int x2 = rect.position.x + rect.size.width + 5;
if ((flags & UIS_CENTER) != 0)
x2 = rect.x + (rect.w - lineWidth) / 2 + lineWidth + 5;
x2 = rect.position.x + (rect.size.width - lineWidth) / 2 + lineWidth + 5;
CelDrawTo(out, { x2, rect.y + 1 }, *pSPentSpn2Cels, PentSpn2Spin());
CelDrawTo(out, { x2, rect.position.y + 1 }, *pSPentSpn2Cels, PentSpn2Spin());
}
void PrintSString(const CelOutputBuffer &out, int margin, int line, const char *text, uint16_t flags, int price)
@ -2251,7 +2251,7 @@ void PrintSString(const CelOutputBuffer &out, int margin, int line, const char *
}
width -= margin * 2;
const SDL_Rect rect { sx, sy, width, 0 };
const Rectangle rect { sx, sy, width, 0 };
DrawString(out, text, rect, flags);
if (price > 0) {
char valstr[32];

Loading…
Cancel
Save