diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index a143e55e07..f242c06ebc 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -1194,13 +1194,12 @@ static void PrintSecretString(const char *string, bool thislevel) else colstr = TEXTCOLOR_GREEN; } } - FBrokenLines *brok = V_BreakLines(ConFont, screen->GetWidth()*95/100, string); + auto brok = V_BreakLines(ConFont, screen->GetWidth()*95/100, string); for (int k = 0; brok[k].Width >= 0; k++) { Printf("%s%s\n", colstr, brok[k].Text.GetChars()); } - V_FreeBrokenLines(brok); } } diff --git a/src/c_console.cpp b/src/c_console.cpp index bc552c3b8e..eb078033e1 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -732,8 +732,8 @@ void FNotifyBuffer::Shift(int maxlines) void FNotifyBuffer::AddString(int printlevel, FString source) { - FBrokenLines *lines; - int i, width; + TArray lines; + int width; if ((printlevel != 128 && !show_messages) || source.IsEmpty() || @@ -764,14 +764,14 @@ void FNotifyBuffer::AddString(int printlevel, FString source) } } - if (lines == NULL) + if (lines.Size() == 0) return; - for (i = 0; lines[i].Width >= 0; i++) + for (auto &line : lines) { FNotifyText newline; - newline.Text = lines[i].Text; + newline.Text = line.Text; newline.TimeOut = gametic + int(con_notifytime * TICRATE); newline.PrintLevel = printlevel; if (AddType == NEWLINE || Text.Size() == 0) @@ -789,9 +789,6 @@ void FNotifyBuffer::AddString(int printlevel, FString source) AddType = NEWLINE; } - V_FreeBrokenLines (lines); - lines = NULL; - switch (source[source.Len()-1]) { case '\r': AddType = REPLACELINE; break; @@ -1185,22 +1182,22 @@ void C_DrawConsole () // No more enqueuing because adding new text to the console won't touch the actual print data. conbuffer->FormatText(ConFont, ConWidth / textScale); unsigned int consolelines = conbuffer->GetFormattedLineCount(); - FBrokenLines **blines = conbuffer->GetLines(); - FBrokenLines **printline = blines + consolelines - 1 - RowAdjust; + FBrokenLines *blines = conbuffer->GetLines(); + FBrokenLines *printline = blines + consolelines - 1 - RowAdjust; int bottomline = ConBottom / textScale - ConFont->GetHeight()*2 - 4; ConsoleDrawing = true; - for(FBrokenLines **p = printline; p >= blines && lines > 0; p--, lines--) + for(FBrokenLines *p = printline; p >= blines && lines > 0; p--, lines--) { if (textScale == 1) { - screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), (*p)->Text, TAG_DONE); + screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), p->Text, TAG_DONE); } else { - screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), (*p)->Text, + screen->DrawText(ConFont, CR_TAN, LEFTMARGIN, offset + lines * ConFont->GetHeight(), p->Text, DTA_VirtualWidth, screen->GetWidth() / textScale, DTA_VirtualHeight, screen->GetHeight() / textScale, DTA_KeepRatio, true, TAG_DONE); diff --git a/src/c_consolebuffer.cpp b/src/c_consolebuffer.cpp index 0b501a7748..9d32efffbb 100644 --- a/src/c_consolebuffer.cpp +++ b/src/c_consolebuffer.cpp @@ -74,11 +74,11 @@ FConsoleBuffer::~FConsoleBuffer() void FConsoleBuffer::FreeBrokenText(unsigned start, unsigned end) { - if (end > mBrokenConsoleText.Size()) end = mBrokenConsoleText.Size(); + if (end > m_BrokenConsoleText.Size()) end = m_BrokenConsoleText.Size(); for (unsigned i = start; i < end; i++) { - if (mBrokenConsoleText[i] != NULL) V_FreeBrokenLines(mBrokenConsoleText[i]); - mBrokenConsoleText[i] = NULL; + m_BrokenConsoleText[i].Clear(); + m_BrokenConsoleText[i].ShrinkToFit(); } } @@ -260,7 +260,7 @@ void FConsoleBuffer::FormatText(FFont *formatfont, int displaywidth) if (formatfont != mLastFont || displaywidth != mLastDisplayWidth || mBufferWasCleared) { FreeBrokenText(); - mBrokenConsoleText.Clear(); + m_BrokenConsoleText.Clear(); mBrokenStart.Clear(); mBrokenStart.Push(0); mBrokenLines.Clear(); @@ -268,7 +268,7 @@ void FConsoleBuffer::FormatText(FFont *formatfont, int displaywidth) mLastDisplayWidth = displaywidth; mBufferWasCleared = false; } - unsigned brokensize = mBrokenConsoleText.Size(); + unsigned brokensize = m_BrokenConsoleText.Size(); if (brokensize == mConsoleText.Size()) { // The last line got text appended. We have to wait until here to format it because @@ -276,21 +276,19 @@ void FConsoleBuffer::FormatText(FFont *formatfont, int displaywidth) if (mLastLineNeedsUpdate) { brokensize--; - V_FreeBrokenLines(mBrokenConsoleText[brokensize]); - mBrokenConsoleText.Resize(brokensize); + m_BrokenConsoleText.Resize(brokensize); } } mBrokenLines.Resize(mBrokenStart[brokensize]); mBrokenStart.Resize(brokensize); for (unsigned i = brokensize; i < mConsoleText.Size(); i++) { - FBrokenLines *bl = V_BreakLines(formatfont, displaywidth, mConsoleText[i], true); - mBrokenConsoleText.Push(bl); + auto bl = V_BreakLines(formatfont, displaywidth, mConsoleText[i], true); + m_BrokenConsoleText.Push(bl); mBrokenStart.Push(mBrokenLines.Size()); - while (bl->Width != -1) + for(auto &bline : bl) { - mBrokenLines.Push(bl); - bl++; + mBrokenLines.Push(bline); } } mTextLines = mBrokenLines.Size(); diff --git a/src/c_consolebuffer.h b/src/c_consolebuffer.h index 710423012b..1b46156b29 100644 --- a/src/c_consolebuffer.h +++ b/src/c_consolebuffer.h @@ -49,9 +49,9 @@ enum EAddType class FConsoleBuffer { TArray mConsoleText; - TArray mBrokenConsoleText; // This holds the structures returned by V_BreakLines and is used for memory management. + TArray> m_BrokenConsoleText; // This holds the structures returned by V_BreakLines and is used for memory management. TArray mBrokenStart; - TArray mBrokenLines; // This holds the single lines, indexed by mBrokenStart and is used for printing. + TArray mBrokenLines; // This holds the single lines, indexed by mBrokenStart and is used for printing. FILE * mLogFile; EAddType mAddType; int mTextLines; @@ -80,6 +80,6 @@ public: mConsoleText.Clear(); } int GetFormattedLineCount() { return mTextLines; } - FBrokenLines **GetLines() { return &mBrokenLines[0]; } + FBrokenLines *GetLines() { return &mBrokenLines[0]; } }; diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index 14c6cd53ae..3e0db78746 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -194,7 +194,6 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h WrapWidth = 0; HandleAspect = true; Top = y; - Lines = NULL; HoldTics = (int)(holdTime * TICRATE); Tics = 0; TextColor = textColor; @@ -215,11 +214,6 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h void DHUDMessage::OnDestroy() { - if (Lines) - { - V_FreeBrokenLines (Lines); - Lines = NULL; - } if (SourceText != NULL) { delete[] SourceText; @@ -260,7 +254,6 @@ void DHUDMessage::Serialize(FSerializer &arc) if (arc.isReading()) { - Lines = NULL; ResetText(SourceText); } } @@ -329,24 +322,16 @@ void DHUDMessage::ResetText (const char *text) width = SCREENWIDTH / active_con_scaletext(); } - if (Lines != NULL) - { - V_FreeBrokenLines (Lines); - } - Lines = V_BreakLines (Font, NoWrap ? INT_MAX : width, (uint8_t *)text); - NumLines = 0; + NumLines = Lines.Size(); Width = 0; Height = 0; - if (Lines) + for (auto &line : Lines) { - for (; Lines[NumLines].Width >= 0; NumLines++) - { - Height += Font->GetHeight (); - Width = MAX (Width, Lines[NumLines].Width); - } + Height += Font->GetHeight (); + Width = MAX (Width, line.Width); } } diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 968c917602..9f7bbb4cc7 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -133,7 +133,7 @@ public: } protected: - FBrokenLines *Lines; + TArray Lines; int Width, Height, NumLines; float Left, Top; bool CenterX, NoWrap; diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index 15b0663aff..0eba791b37 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -686,12 +686,11 @@ class CommandDrawString : public SBarInfoCommand { if(lineBreaks) { - FBrokenLines *lines = V_BreakLines(font, breakWidth, str.GetChars()); - for(int i = 0;lines[i].Width >= 0;i++) + auto lines = V_BreakLines(font, breakWidth, str.GetChars()); + for(unsigned i = 0; i < lines.Size();i++) { statusBar->DrawString(font, lines[i].Text, x, y+i*(font->GetHeight()+4), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), translation, spacing, shadow, shadowX, shadowY); } - V_FreeBrokenLines(lines); } else statusBar->DrawString(font, str.GetChars(), x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), translation, spacing, shadow, shadowX, shadowY); diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 4fc4720a09..4fe157e804 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -1106,10 +1106,10 @@ void DBaseStatusBar::DrawLog () hudheight = SCREENHEIGHT / scale; int linelen = hudwidth<640? Scale(hudwidth,9,10)-40 : 560; - FBrokenLines *lines = V_BreakLines (SmallFont, linelen, CPlayer->LogText); + auto lines = V_BreakLines (SmallFont, linelen, CPlayer->LogText); int height = 20; - for (int i = 0; lines[i].Width != -1; i++) height += SmallFont->GetHeight () + 1; + for (unsigned i = 0; i < lines.Size(); i++) height += SmallFont->GetHeight () + 1; int x,y,w; @@ -1138,8 +1138,6 @@ void DBaseStatusBar::DrawLog () DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); y += SmallFont->GetHeight ()+1; } - - V_FreeBrokenLines (lines); } } @@ -1882,13 +1880,12 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString) if (wrapwidth > 0) { - FBrokenLines *brk = V_BreakLines(font->mFont, wrapwidth, string, true); - for (int i = 0; brk[i].Width >= 0; i++) + auto brk = V_BreakLines(font->mFont, wrapwidth, string, true); + for (auto &line : brk) { - self->DrawString(font->mFont, brk[i].Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY); + self->DrawString(font->mFont, line.Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY); y += font->mFont->GetHeight() + linespacing; } - V_FreeBrokenLines(brk); } else { diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 8d49ddc2d4..8211cc57fc 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -535,13 +535,10 @@ void FSavegameManager::UnloadSaveData() { delete SavePic; } - if (SaveComment != nullptr) - { - V_FreeBrokenLines(SaveComment); - } + SaveComment.Clear(); + SaveComment.ShrinkToFit(); SavePic = nullptr; - SaveComment = nullptr; SavePicData.Clear(); } @@ -615,7 +612,7 @@ void FSavegameManager::DrawSaveComment(FFont *font, int cr, int x, int y, int sc // I'm not sure why SaveComment would go nullptr in this loop, but I got // a crash report where it was nullptr when i reached 1, so now I check // for that. - for (int i = 0; SaveComment != nullptr && SaveComment[i].Width >= 0 && i < maxlines; ++i) + for (int i = 0; i < maxlines && (unsigned)i < SaveComment.Size(); ++i) { screen->DrawText(font, cr, x, y + font->GetHeight() * i * scalefactor, SaveComment[i].Text, DTA_CleanNoMove, true, TAG_DONE); } @@ -647,14 +644,9 @@ void FSavegameManager::SetFileInfo(int Selected) { if (!SaveGames[Selected]->Filename.IsEmpty()) { - char workbuf[512]; - - mysnprintf(workbuf, countof(workbuf), "File on disk:\n%s", SaveGames[Selected]->Filename.GetChars()); - if (SaveComment != nullptr) - { - V_FreeBrokenLines(SaveComment); - } - SaveComment = V_BreakLines(SmallFont, WindowSize, workbuf); + FString work; + work.Format("File on disk:\n%s", SaveGames[Selected]->Filename.GetChars()); + SaveComment = V_BreakLines(SmallFont, WindowSize, work); } } diff --git a/src/menu/menu.h b/src/menu/menu.h index b374d29e15..83f4f66da5 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -73,7 +73,7 @@ private: int LastAccessed = -1; TArray SavePicData; FTexture *SavePic = nullptr; - FBrokenLines *SaveComment = nullptr; + TArray SaveComment; public: int WindowSize = 0; diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index cabb85edfd..c577a4c2c3 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -715,27 +715,6 @@ DEFINE_ACTION_FUNCTION(DConversationMenu, SendConversationReply) } -// Needed for the conversion process. -class DBrokenLines : public DObject -{ - DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject) - -public: - FBrokenLines *mBroken; - unsigned int mCount; - - DBrokenLines(FBrokenLines *broken, unsigned int count) - { - mBroken = broken; - mCount = count; - } - - void OnDestroy() override - { - V_FreeBrokenLines(mBroken); - } -}; - //============================================================================ // // P_FreeStrifeConversations diff --git a/src/p_destructible.cpp b/src/p_destructible.cpp index 3cb00d5f91..998504a9aa 100755 --- a/src/p_destructible.cpp +++ b/src/p_destructible.cpp @@ -358,7 +358,7 @@ void P_GeometryRadiusAttack(AActor* bombspot, AActor* bombsource, int bombdamage TArray lines; while ((ln = it.Next())) // iterator and Trace both use validcount and interfere with each other lines.Push(ln); - for (int i = 0; i < lines.Size(); i++) + for (unsigned i = 0; i < lines.Size(); i++) { ln = lines[i]; DVector2 pos2d = bombspot->Pos().XY(); diff --git a/src/v_font.cpp b/src/v_font.cpp index 0a7d742151..4678c56b95 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -87,6 +87,7 @@ The FON2 header is followed by variable length data: #include "cmdlib.h" #include "sc_man.h" #include "hu_stuff.h" +#include "gstrings.h" #include "v_text.h" #include "vm.h" @@ -919,7 +920,9 @@ DEFINE_ACTION_FUNCTION(FFont, StringWidth) { PARAM_SELF_STRUCT_PROLOGUE(FFont); PARAM_STRING(str); - ACTION_RETURN_INT(self->StringWidth(str)); + const char *txt = str[0] == '$' ? GStrings(&str[1]) : str.GetChars(); + + ACTION_RETURN_INT(self->StringWidth(txt)); } //========================================================================== diff --git a/src/v_text.cpp b/src/v_text.cpp index 30d8972fb9..6fea75bb5c 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -345,7 +345,7 @@ static void breakit (FBrokenLines *line, FFont *font, const uint8_t *start, cons line->Width = font->StringWidth (line->Text); } -FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bool preservecolor, unsigned int *count) +TArray V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bool preservecolor, unsigned int *count) { TArray Lines(128); @@ -448,21 +448,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo } } } - - // Make a copy of the broken lines and return them - FBrokenLines *broken = new FBrokenLines[Lines.Size() + 1]; - - for (unsigned ii = 0; ii < Lines.Size(); ++ii) - { - broken[ii] = Lines[ii]; - } - broken[Lines.Size()].Width = -1; - if (count != nullptr) - { - *count = Lines.Size(); - } - - return broken; + return Lines; } void V_FreeBrokenLines (FBrokenLines *lines) @@ -478,18 +464,11 @@ class DBrokenLines : public DObject DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject) public: - FBrokenLines *mBroken; - unsigned int mCount; + TArray mBroken; - DBrokenLines(FBrokenLines *broken, unsigned int count) + DBrokenLines(TArray &broken) { - mBroken = broken; - mCount = count; - } - - void OnDestroy() override - { - V_FreeBrokenLines(mBroken); + mBroken = std::move(broken); } }; @@ -498,21 +477,21 @@ IMPLEMENT_CLASS(DBrokenLines, true, false); DEFINE_ACTION_FUNCTION(DBrokenLines, Count) { PARAM_SELF_PROLOGUE(DBrokenLines); - ACTION_RETURN_INT(self->mCount); + ACTION_RETURN_INT(self->mBroken.Size()); } DEFINE_ACTION_FUNCTION(DBrokenLines, StringWidth) { PARAM_SELF_PROLOGUE(DBrokenLines); PARAM_INT(index); - ACTION_RETURN_INT((unsigned)index >= self->mCount? -1 : self->mBroken[index].Width); + ACTION_RETURN_INT((unsigned)index >= self->mBroken.Size()? -1 : self->mBroken[index].Width); } DEFINE_ACTION_FUNCTION(DBrokenLines, StringAt) { PARAM_SELF_PROLOGUE(DBrokenLines); PARAM_INT(index); - ACTION_RETURN_STRING((unsigned)index >= self->mCount? -1 : self->mBroken[index].Text); + ACTION_RETURN_STRING((unsigned)index >= self->mBroken.Size() ? -1 : self->mBroken[index].Text); } DEFINE_ACTION_FUNCTION(FFont, BreakLines) @@ -522,6 +501,6 @@ DEFINE_ACTION_FUNCTION(FFont, BreakLines) PARAM_INT(maxwidth); unsigned int count; - FBrokenLines *broken = V_BreakLines(self, maxwidth, text, true, &count); - ACTION_RETURN_OBJECT(Create(broken, count)); + TArray broken = V_BreakLines(self, maxwidth, text, true, &count); + ACTION_RETURN_OBJECT(Create(broken)); } diff --git a/src/v_text.h b/src/v_text.h index cd7d3e6ad4..1ae2ca3a57 100644 --- a/src/v_text.h +++ b/src/v_text.h @@ -39,7 +39,7 @@ struct FBrokenLines { - int Width; + unsigned Width; FString Text; }; @@ -79,11 +79,10 @@ struct FBrokenLines #define TEXTCOLOR_CHAT "\034*" #define TEXTCOLOR_TEAMCHAT "\034!" -FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *str, bool preservecolor = false, unsigned int *count = nullptr); -void V_FreeBrokenLines (FBrokenLines *lines); -inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false, unsigned int *count = nullptr) +TArray V_BreakLines (FFont *font, int maxwidth, const uint8_t *str, bool preservecolor = false, unsigned int *count = nullptr); +inline TArray V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false, unsigned int *count = nullptr) { return V_BreakLines (font, maxwidth, (const uint8_t *)str, preservecolor, count); } -inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr) +inline TArray V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr) { return V_BreakLines (font, maxwidth, (const uint8_t *)str.GetChars(), preservecolor, count); } int GetCharFromString(const uint8_t *&string);