Browse Source

Reduces `stext` stack use (16K -> 4K)

1. Reduces the sizes of variables in `STextStruct`.
2. `char[128]` -> `std::string`
pull/4786/head
Gleb Mazovetskiy 4 years ago
parent
commit
8ba3387f54
  1. 100
      Source/stores.cpp
  2. 23
      Source/stores.h

100
Source/stores.cpp

@ -60,6 +60,37 @@ int stextsmax;
int stextlhold;
/** Currently selected text line from stext */
int stextsel;
struct STextStruct {
enum Type : uint8_t {
Label,
Divider,
Selectable,
};
std::string text;
int _sval;
int y;
UiFlags flags;
Type type;
uint8_t _sx;
uint8_t _syoff;
[[nodiscard]] bool isDivider() const
{
return type == Divider;
}
[[nodiscard]] bool isSelectable() const
{
return type == Selectable;
}
[[nodiscard]] bool hasText() const
{
return !text.empty();
}
};
/** Text lines */
STextStruct stext[STORE_LINES];
@ -148,7 +179,7 @@ void CalculateLineHeights()
if (IsSmallFontTall()) {
for (int i = 1; i < STORE_LINES; ++i) {
// Space out consecutive text lines, unless they are both selectable (never the case currently).
if (stext[i].IsText() && stext[i - 1].IsText() && !(stext[i]._ssel && stext[i - 1]._ssel)) {
if (stext[i].hasText() && stext[i - 1].hasText() && !(stext[i].isSelectable() && stext[i - 1].isSelectable())) {
stext[i].y = stext[i - 1].y + LargeTextHeight;
} else {
stext[i].y = i * LargeLineHeight;
@ -198,27 +229,28 @@ void DrawSSlider(const Surface &out, int y1, int y2)
CelDrawTo(out, { uiPosition.x + 601, (y1 + 1) * 12 + 44 + uiPosition.y + yd3 }, sprite, 12);
}
void AddSLine(int y)
void AddSLine(size_t y)
{
stext[y]._sx = 0;
stext[y]._syoff = 0;
stext[y]._sstr[0] = 0;
stext[y]._sline = 1;
stext[y].text.clear();
stext[y].text.shrink_to_fit();
stext[y].type = STextStruct::Divider;
}
void AddSTextVal(int y, int val)
void AddSTextVal(size_t y, int val)
{
stext[y]._sval = val;
}
void AddSText(int x, int y, string_view text, UiFlags flags, bool sel)
void AddSText(uint8_t x, size_t y, string_view text, UiFlags flags, bool sel)
{
stext[y]._sx = x;
stext[y]._syoff = 0;
CopyUtf8(stext[y]._sstr, text, sizeof(stext[y]._sstr));
stext[y].text.clear();
AppendStrView(stext[y].text, text);
stext[y].flags = flags;
stext[y]._sline = 0;
stext[y]._ssel = sel;
stext[y].type = sel ? STextStruct::Selectable : STextStruct::Label;
}
void AddOptionsBackButton()
@ -351,7 +383,7 @@ void ScrollSmithBuy(int idx)
}
}
if (stextsel != -1 && !stext[stextsel]._ssel && stextsel != BackButtonLine())
if (stextsel != -1 && !stext[stextsel].isSelectable() && stextsel != BackButtonLine())
stextsel = stextdown;
}
@ -413,7 +445,7 @@ void ScrollSmithPremiumBuy(int boughtitems)
}
idx++;
}
if (stextsel != -1 && !stext[stextsel]._ssel && stextsel != BackButtonLine())
if (stextsel != -1 && !stext[stextsel].isSelectable() && stextsel != BackButtonLine())
stextsel = stextdown;
}
@ -704,7 +736,7 @@ void ScrollWitchBuy(int idx)
}
}
if (stextsel != -1 && !stext[stextsel]._ssel && stextsel != BackButtonLine())
if (stextsel != -1 && !stext[stextsel].isSelectable() && stextsel != BackButtonLine())
stextsel = stextdown;
}
@ -1092,7 +1124,7 @@ void ScrollHealerBuy(int idx)
}
}
if (stextsel != -1 && !stext[stextsel]._ssel && stextsel != BackButtonLine())
if (stextsel != -1 && !stext[stextsel].isSelectable() && stextsel != BackButtonLine())
stextsel = stextdown;
}
@ -1916,7 +1948,7 @@ void ConfirmEnter(Item &item)
stextsel = stextlhold;
stextsval = std::min(stextvhold, stextsmax);
while (stextsel != -1 && !stext[stextsel]._ssel) {
while (stextsel != -1 && !stext[stextsel].isSelectable()) {
stextsel--;
}
}
@ -2133,7 +2165,7 @@ int TakeGold(Player &player, int cost, bool skipMaxPiles)
return cost;
}
void DrawSelector(const Surface &out, const Rectangle &rect, const char *text, UiFlags flags)
void DrawSelector(const Surface &out, const Rectangle &rect, string_view text, UiFlags flags)
{
int lineWidth = GetLineWidth(text);
@ -2217,9 +2249,13 @@ void SetupTownStores()
void FreeStoreMem()
{
stextflag = STORE_NONE;
for (STextStruct &entry : stext) {
entry.text.clear();
entry.text.shrink_to_fit();
}
}
void PrintSString(const Surface &out, int margin, int line, const char *text, UiFlags flags, int price)
void PrintSString(const Surface &out, int margin, int line, string_view text, UiFlags flags, int price)
{
const Point uiPosition = GetUIRectangle().position;
int sx = uiPosition.x + 32 + margin;
@ -2274,10 +2310,10 @@ void ClearSText(int s, int e)
for (int i = s; i < e; i++) {
stext[i]._sx = 0;
stext[i]._syoff = 0;
stext[i]._sstr[0] = 0;
stext[i].text.clear();
stext[i].text.shrink_to_fit();
stext[i].flags = UiFlags::None;
stext[i]._sline = 0;
stext[i]._ssel = false;
stext[i].type = STextStruct::Label;
stext[i]._sval = 0;
}
}
@ -2384,7 +2420,7 @@ void StartStore(talk_id s)
stextsel = -1;
for (int i = 0; i < STORE_LINES; i++) {
if (stext[i]._ssel) {
if (stext[i].isSelectable()) {
stextsel = i;
break;
}
@ -2429,10 +2465,10 @@ void DrawSText(const Surface &out)
CalculateLineHeights();
const Point uiPosition = GetUIRectangle().position;
for (int i = 0; i < STORE_LINES; i++) {
if (stext[i].IsDivider())
if (stext[i].isDivider())
DrawSLine(out, uiPosition.y + PaddingTop + stext[i].y + TextHeight() / 2);
if (stext[i].IsText())
PrintSString(out, stext[i]._sx, i, stext[i]._sstr, stext[i].flags, stext[i]._sval);
else if (stext[i].hasText())
PrintSString(out, stext[i]._sx, i, stext[i].text, stext[i].flags, stext[i]._sval);
}
if (RenderGold) {
@ -2534,7 +2570,7 @@ void StoreUp()
}
stextsel--;
while (!stext[stextsel]._ssel) {
while (!stext[stextsel].isSelectable()) {
if (stextsel == 0)
stextsel = STORE_LINES - 1;
else
@ -2548,7 +2584,7 @@ void StoreUp()
else
stextsel--;
while (!stext[stextsel]._ssel) {
while (!stext[stextsel].isSelectable()) {
if (stextsel == 0)
stextsel = STORE_LINES - 1;
else
@ -2571,7 +2607,7 @@ void StoreDown()
}
stextsel++;
while (!stext[stextsel]._ssel) {
while (!stext[stextsel].isSelectable()) {
if (stextsel == STORE_LINES - 1)
stextsel = 0;
else
@ -2585,7 +2621,7 @@ void StoreDown()
else
stextsel++;
while (!stext[stextsel]._ssel) {
while (!stext[stextsel].isSelectable()) {
if (stextsel == STORE_LINES - 1)
stextsel = 0;
else
@ -2765,7 +2801,7 @@ void CheckStoreBtn()
// Large small fonts draw beyond LineHeight. Check if the click was on the overflow text.
if (IsSmallFontTall() && y > 0 && y < STORE_LINES
&& stext[y - 1].IsText() && !stext[y].IsText()
&& stext[y - 1].hasText() && !stext[y].hasText()
&& relativeY < stext[y - 1].y + LargeTextHeight) {
--y;
}
@ -2773,14 +2809,14 @@ void CheckStoreBtn()
if (y >= 5) {
if (y >= BackButtonLine() + 1)
y = BackButtonLine();
if (stextscrl && y <= 20 && !stext[y]._ssel) {
if (stext[y - 2]._ssel) {
if (stextscrl && y <= 20 && !stext[y].isSelectable()) {
if (stext[y - 2].isSelectable()) {
y -= 2;
} else if (stext[y - 1]._ssel) {
} else if (stext[y - 1].isSelectable()) {
y--;
}
}
if (stext[y]._ssel || (stextscrl && y == BackButtonLine())) {
if (stext[y].isSelectable() || (stextscrl && y == BackButtonLine())) {
stextsel = y;
StoreEnter();
}

23
Source/stores.h

@ -46,27 +46,6 @@ enum talk_id : uint8_t {
STORE_BARMAID,
};
struct STextStruct {
int _sx;
int _syoff;
char _sstr[128];
UiFlags flags;
int _sline;
bool _ssel;
int _sval;
int y;
[[nodiscard]] bool IsDivider() const
{
return _sline != 0;
}
[[nodiscard]] bool IsText() const
{
return _sstr[0] != '\0';
}
};
/** Currently active store */
extern talk_id stextflag;
@ -107,7 +86,7 @@ void SetupTownStores();
void FreeStoreMem();
void PrintSString(const Surface &out, int margin, int line, const char *text, UiFlags flags, int price = 0);
void PrintSString(const Surface &out, int margin, int line, string_view text, UiFlags flags, int price = 0);
void DrawSLine(const Surface &out, int sy);
void DrawSTextHelp();
void ClearSText(int s, int e);

Loading…
Cancel
Save