From bc0472a2d660410abd02f8993191eb9b4708d81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 20 Aug 2023 13:03:01 +0200 Subject: [PATCH] Add `str_from_int` function Add more efficient function for formatting integer values as strings. A benchmark shows that using this function is significantly faster than using `str_format`. It is faster by a factor of 220 with Clang 15.0 O2 (https://quick-bench.com/q/BlNoLnlyqxipf4jvsFTUxKMHDJU) and by a factor of 11 with GCC 12.2 O2 (https://quick-bench.com/q/Fxf9lDCTqXBF4pIa_IyZ5R0IqYg). This increases FPS in the editor by ~25% when many numbers are rendered for switch/tele/speedup/tune layers or with "Show Info" being enabled. The additional static analysis for `std::to_chars` revealed that the wrong size was used in `CHud` for `aScoreTeam[TEAM_RED]` and `aScoreTeam[TEAM_BLUE]`. This requires incrementing the macOS deployment target from 10.13 to 10.15. --- CMakeLists.txt | 6 +++--- src/base/system.cpp | 8 ++++++++ src/base/system.h | 8 ++++++++ src/engine/server/server.cpp | 4 ++-- src/engine/server/upnp.cpp | 4 ++-- src/engine/shared/console.cpp | 2 +- src/engine/shared/jsonwriter.cpp | 2 +- src/game/client/components/debughud.cpp | 8 ++++---- src/game/client/components/hud.cpp | 12 ++++++------ src/game/client/components/mapimages.cpp | 4 ++-- src/game/client/components/menus.cpp | 2 +- src/game/client/components/menus_browser.cpp | 6 +++--- src/game/client/components/menus_demo.cpp | 6 +++--- src/game/client/components/menus_settings.cpp | 2 +- src/game/client/components/nameplates.cpp | 4 ++-- src/game/client/components/scoreboard.cpp | 12 ++++++------ src/game/client/components/statboard.cpp | 14 +++++++------- src/game/client/components/voting.cpp | 10 +++++----- src/game/client/lineinput.cpp | 2 +- src/game/client/render_map.cpp | 12 ++++++------ src/game/editor/editor.cpp | 6 +++--- src/game/editor/layer_tiles.cpp | 12 ++++++++++-- src/game/server/gamecontext.cpp | 2 +- 23 files changed, 86 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8b2d2480a2..7540f323e74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,9 @@ if(CMAKE_VERSION VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_VERSION}) endif() -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13 CACHE INTERNAL "Minimum macOS deployment version") -if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.13) - message(WARNING "Building for macOS < 10.13 is not supported") +set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE INTERNAL "Minimum macOS deployment version") +if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.15) + message(WARNING "Building for macOS < 10.15 is not supported") endif() file(STRINGS src/game/version.h VERSION_LINE diff --git a/src/base/system.cpp b/src/base/system.cpp index 7a5ce590bd4..93925d4a13e 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -2,6 +2,7 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include #include +#include #include #include #include @@ -3640,6 +3641,13 @@ float str_tofloat(const char *str) return strtod(str, nullptr); } +void str_from_int(int value, char *buffer, size_t buffer_size) +{ + buffer[0] = '\0'; // Fix false positive clang-analyzer-core.UndefinedBinaryOperatorResult when using result + auto result = std::to_chars(buffer, buffer + buffer_size - 1, value); + result.ptr[0] = '\0'; +} + int str_utf8_comp_nocase(const char *a, const char *b) { int code_a; diff --git a/src/base/system.h b/src/base/system.h index a07a85f0b92..98490f1edb1 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -2230,6 +2230,14 @@ unsigned long str_toulong_base(const char *str, int base); int64_t str_toint64_base(const char *str, int base = 10); float str_tofloat(const char *str); +void str_from_int(int value, char *buffer, size_t buffer_size); + +template +void str_from_int(int value, char (&dst)[N]) +{ + str_from_int(value, dst, N); +} + /** * Determines whether a character is whitespace. * diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 9e27b51240c..6247219e191 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1944,7 +1944,7 @@ void CServer::CacheServerInfo(CCache *pCache, int Type, bool SendClients) #define ADD_INT(p, x) \ do \ { \ - str_format(aBuf, sizeof(aBuf), "%d", x); \ + str_from_int(x, aBuf); \ (p).AddString(aBuf, 0); \ } while(0) @@ -2205,7 +2205,7 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen #define ADD_INT(p, x) \ do \ { \ - str_format(aBuf, sizeof(aBuf), "%d", x); \ + str_from_int(x, aBuf); \ (p).AddString(aBuf, 0); \ } while(0) diff --git a/src/engine/server/upnp.cpp b/src/engine/server/upnp.cpp index c8f4cc3221f..e6639c07d2d 100644 --- a/src/engine/server/upnp.cpp +++ b/src/engine/server/upnp.cpp @@ -32,7 +32,7 @@ void CUPnP::Open(NETADDR Address) { m_Enabled = true; dbg_msg("upnp", "found valid IGD: %s", m_pUPnPUrls->controlURL); - str_format(aPort, sizeof(aPort), "%d", m_Addr.port); + str_from_int(m_Addr.port, aPort); Error = UPNP_AddPortMapping(m_pUPnPUrls->controlURL, m_pUPnPData->first.servicetype, aPort, aPort, aLanAddr, "DDNet Server " GAME_RELEASE_VERSION, @@ -55,7 +55,7 @@ void CUPnP::Shutdown() if(m_Enabled) { char aPort[6]; - str_format(aPort, sizeof(aPort), "%d", m_Addr.port); + str_from_int(m_Addr.port, aPort); int Error = UPNP_DeletePortMapping(m_pUPnPUrls->controlURL, m_pUPnPData->first.servicetype, aPort, "UDP", NULL); if(Error != 0) diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index e2951ba8ddf..9ceb75ed68b 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -732,7 +732,7 @@ void CConsole::ConUserCommandStatus(IResult *pResult, void *pUser) CResult Result; Result.m_pCommand = "access_status"; char aBuf[4]; - str_format(aBuf, sizeof(aBuf), "%d", IConsole::ACCESS_LEVEL_USER); + str_from_int((int)IConsole::ACCESS_LEVEL_USER, aBuf); Result.AddArgument(aBuf); pConsole->ConCommandStatus(&Result, pConsole); diff --git a/src/engine/shared/jsonwriter.cpp b/src/engine/shared/jsonwriter.cpp index 6c0931a36fc..2df12b21a7a 100644 --- a/src/engine/shared/jsonwriter.cpp +++ b/src/engine/shared/jsonwriter.cpp @@ -79,7 +79,7 @@ void CJsonWriter::WriteIntValue(int Value) dbg_assert(CanWriteDatatype(), "Cannot write value here"); WriteIndent(false); char aBuf[32]; - str_format(aBuf, sizeof(aBuf), "%d", Value); + str_from_int(Value, aBuf); WriteInternal(aBuf); CompleteDataType(); } diff --git a/src/game/client/components/debughud.cpp b/src/game/client/components/debughud.cpp index f958779403b..59691408e4b 100644 --- a/src/game/client/components/debughud.cpp +++ b/src/game/client/components/debughud.cpp @@ -52,10 +52,10 @@ void CDebugHud::RenderNetCorrections() str_format(aBuf, sizeof(aBuf), "%.2f", Ramp); RenderRow("Ramp:", aBuf); - str_format(aBuf, sizeof(aBuf), "%d", pCharacter == nullptr ? -1 : pCharacter->m_TeleCheckpoint); + str_from_int(pCharacter == nullptr ? -1 : pCharacter->m_TeleCheckpoint, aBuf); RenderRow("Checkpoint:", aBuf); - str_format(aBuf, sizeof(aBuf), "%d", pCharacter == nullptr ? -1 : pCharacter->m_TuneZone); + str_from_int(pCharacter == nullptr ? -1 : pCharacter->m_TuneZone, aBuf); RenderRow("Tune zone:", aBuf); str_format(aBuf, sizeof(aBuf), "%.2f", m_pClient->m_Snap.m_pLocalCharacter->m_X / 32.0f); @@ -64,10 +64,10 @@ void CDebugHud::RenderNetCorrections() str_format(aBuf, sizeof(aBuf), "%.2f", m_pClient->m_Snap.m_pLocalCharacter->m_Y / 32.0f); RenderRow("Pos.y:", aBuf); - str_format(aBuf, sizeof(aBuf), "%d", m_pClient->m_Snap.m_pLocalCharacter->m_Angle); + str_from_int(m_pClient->m_Snap.m_pLocalCharacter->m_Angle, aBuf); RenderRow("Angle:", aBuf); - str_format(aBuf, sizeof(aBuf), "%d", m_pClient->NetobjNumCorrections()); + str_from_int(m_pClient->NetobjNumCorrections(), aBuf); RenderRow("Netobj corrections", aBuf); RenderRow(" on:", m_pClient->NetobjCorrectedOn()); } diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 47e2015cc15..86bfca2faf2 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -171,8 +171,8 @@ void CHud::RenderScoreHud() if(GameFlags & GAMEFLAG_TEAMS && m_pClient->m_Snap.m_pGameDataObj) { char aScoreTeam[2][16]; - str_format(aScoreTeam[TEAM_RED], sizeof(aScoreTeam), "%d", m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed); - str_format(aScoreTeam[TEAM_BLUE], sizeof(aScoreTeam), "%d", m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue); + str_from_int(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed, aScoreTeam[TEAM_RED]); + str_from_int(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue, aScoreTeam[TEAM_BLUE]); bool aRecreateTeamScore[2] = {str_comp(aScoreTeam[0], m_aScoreInfo[0].m_aScoreText) != 0, str_comp(aScoreTeam[1], m_aScoreInfo[1].m_aScoreText) != 0}; @@ -324,7 +324,7 @@ void CHud::RenderScoreHud() aScore[t][0] = 0; } else - str_format(aScore[t], sizeof(aScore) / 2, "%d", apPlayerInfo[t]->m_Score); + str_from_int(apPlayerInfo[t]->m_Score, aScore[t]); } else aScore[t][0] = 0; @@ -484,7 +484,7 @@ void CHud::RenderWarmupTimer() if(Seconds < 5) str_format(aBuf, sizeof(aBuf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer * 10 / SERVER_TICK_SPEED) % 10); else - str_format(aBuf, sizeof(aBuf), "%d", Seconds); + str_from_int(Seconds, aBuf); w = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(150 * Graphics()->ScreenAspect() + -w / 2, 75, FontSize, aBuf, -1.0f); } @@ -498,7 +498,7 @@ void CHud::RenderTextInfo() m_FrameTimeAvg = m_FrameTimeAvg * 0.9f + Client()->RenderFrameTime() * 0.1f; char aBuf[64]; int FrameTime = (int)(1.0f / m_FrameTimeAvg + 0.5f); - str_format(aBuf, sizeof(aBuf), "%d", FrameTime); + str_from_int(FrameTime, aBuf); static float s_TextWidth0 = TextRender()->TextWidth(12.f, "0", -1, -1.0f); static float s_TextWidth00 = TextRender()->TextWidth(12.f, "00", -1, -1.0f); @@ -527,7 +527,7 @@ void CHud::RenderTextInfo() if(g_Config.m_ClShowpred) { char aBuf[64]; - str_format(aBuf, sizeof(aBuf), "%d", Client()->GetPredictionTime()); + str_from_int(Client()->GetPredictionTime(), aBuf); TextRender()->Text(m_Width - 10 - TextRender()->TextWidth(12, aBuf, -1, -1.0f), g_Config.m_ClShowfps ? 20 : 5, 12, aBuf, -1.0f); } } diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp index ffcf38768ab..0076eb88ed5 100644 --- a/src/game/client/components/mapimages.cpp +++ b/src/game/client/components/mapimages.cpp @@ -451,7 +451,7 @@ void CMapImages::UpdateEntityLayerText(void *pTexBuffer, int ImageColorChannelCo if(MaxNumber == -1) MaxNumber = CurrentNumber * 10 - 1; - str_format(aBuf, sizeof(aBuf), "%d", CurrentNumber); + str_from_int(CurrentNumber, aBuf); int CurrentNumberSuitableFontSize = TextRender()->AdjustFontSize(aBuf, DigitsCount, TextureSize, MaxWidth); int UniversalSuitableFontSize = CurrentNumberSuitableFontSize * 0.92f; // should be smoothed enough to fit any digits combination @@ -460,7 +460,7 @@ void CMapImages::UpdateEntityLayerText(void *pTexBuffer, int ImageColorChannelCo for(; CurrentNumber <= MaxNumber; ++CurrentNumber) { - str_format(aBuf, sizeof(aBuf), "%d", CurrentNumber); + str_from_int(CurrentNumber, aBuf); float x = (CurrentNumber % 16) * 64; float y = (CurrentNumber / 16) * 64; diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 8c9b1c4774a..4d645834ddc 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -444,7 +444,7 @@ int CMenus::DoButton_CheckBox(const void *pID, const char *pText, int Checked, c int CMenus::DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { char aBuf[16]; - str_format(aBuf, sizeof(aBuf), "%d", Checked); + str_from_int(Checked, aBuf); return DoButton_CheckBox_Common(pID, pText, aBuf, pRect); } diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 30fd88ea9c2..e5dff168b45 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -37,7 +37,7 @@ void FormatServerbrowserPing(char *pBuffer, int BufferLength, const CServerInfo { if(!pInfo->m_LatencyIsEstimated) { - str_format(pBuffer, BufferLength, "%d", pInfo->m_Latency); + str_from_int(pInfo->m_Latency, pBuffer, BufferLength); return; } static const char *LOCATION_NAMES[CServerInfo::NUM_LOCS] = { @@ -345,7 +345,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) if(FriendsOnServer > 1) { char aBufFriendsOnServer[64]; - str_format(aBufFriendsOnServer, sizeof(aBufFriendsOnServer), "%i", FriendsOnServer); + str_from_int(FriendsOnServer, aBufFriendsOnServer); TextRender()->TextColor(0.94f, 0.8f, 0.8f, 1); UI()->DoLabel(&IconText, aBufFriendsOnServer, 10.0f, TEXTALIGN_MC); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1); @@ -1192,7 +1192,7 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) } else if(ClientScoreKind == CServerInfo::CLIENT_SCORE_KIND_POINTS) { - str_format(aTemp, sizeof(aTemp), "%d", CurrentClient.m_Score); + str_from_int(CurrentClient.m_Score, aTemp); } else { diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 4f32c79fc88..8682342a850 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -984,13 +984,13 @@ void CMenus::RenderDemoList(CUIRect MainView) Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Version:"), 14.0f, TEXTALIGN_ML); - str_format(aBuf, sizeof(aBuf), "%d", m_vDemos[m_DemolistSelectedIndex].m_Info.m_Version); + str_from_int(m_vDemos[m_DemolistSelectedIndex].m_Info.m_Version, aBuf); UI()->DoLabel(&Right, aBuf, 14.0f, TEXTALIGN_ML); Labels.HSplitTop(5.0f, 0, &Labels); Labels.HSplitTop(20.0f, &Left, &Labels); Left.VSplitLeft(150.0f, &Left, &Right); UI()->DoLabel(&Left, Localize("Markers:"), 14.0f, TEXTALIGN_ML); - str_format(aBuf, sizeof(aBuf), "%d", m_vDemos[m_DemolistSelectedIndex].NumMarkers()); + str_from_int(m_vDemos[m_DemolistSelectedIndex].NumMarkers(), aBuf); UI()->DoLabel(&Right, aBuf, 14.0f, TEXTALIGN_ML); // right side @@ -1181,7 +1181,7 @@ void CMenus::RenderDemoList(CUIRect MainView) else if(ID == COL_MARKERS && !Item.m_IsDir && Item.m_InfosLoaded && Item.m_Valid) { char aBuf[3]; - str_format(aBuf, sizeof(aBuf), "%d", Item.NumMarkers()); + str_from_int(Item.NumMarkers(), aBuf); Button.VMargin(4.0f, &Button); UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR); } diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 577ec65eea2..740fd39c719 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1192,7 +1192,7 @@ void CMenus::DoJoystickAxisPicker(CUIRect View) // Axis label char aBuf[16]; - str_format(aBuf, sizeof(aBuf), "%d", i + 1); + str_from_int(i + 1, aBuf); if(Active) TextRender()->TextColor(TextRender()->DefaultTextColor()); else diff --git a/src/game/client/components/nameplates.cpp b/src/game/client/components/nameplates.cpp index 53bbbaa101a..ca08c694669 100644 --- a/src/game/client/components/nameplates.cpp +++ b/src/game/client/components/nameplates.cpp @@ -206,7 +206,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP { YOffset -= FontSize; char aBuf[128]; - str_format(aBuf, sizeof(aBuf), "%d", pPlayerInfo->m_ClientID); + str_from_int(pPlayerInfo->m_ClientID, aBuf); float XOffset = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f) / 2.0f; TextRender()->TextColor(rgb); TextRender()->Text(Position.x - XOffset, YOffset, FontSize, aBuf, -1.0f); @@ -266,7 +266,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP { YOffset -= FontSize; char aBuf[12]; - str_format(aBuf, sizeof(aBuf), "%d", pCharacter->GetStrongWeakID()); + str_from_int(pCharacter->GetStrongWeakID(), aBuf); float XOffset = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f) / 2.0f; TextRender()->Text(Position.x - XOffset, YOffset, FontSize, aBuf, -1.0f); } diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index 2ce8762798f..b84f07159d5 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -202,7 +202,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch if(m_pClient->m_Snap.m_pGameDataObj) { int Score = Team == TEAM_RED ? m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed : m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue; - str_format(aBuf, sizeof(aBuf), "%d", Score); + str_from_int(Score, aBuf); } } else @@ -211,12 +211,12 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch m_pClient->m_Snap.m_apPlayerInfos[m_pClient->m_Snap.m_SpecInfo.m_SpectatorID]) { int Score = m_pClient->m_Snap.m_apPlayerInfos[m_pClient->m_Snap.m_SpecInfo.m_SpectatorID]->m_Score; - str_format(aBuf, sizeof(aBuf), "%d", Score); + str_from_int(Score, aBuf); } else if(m_pClient->m_Snap.m_pLocalInfo) { int Score = m_pClient->m_Snap.m_pLocalInfo->m_Score; - str_format(aBuf, sizeof(aBuf), "%d", Score); + str_from_int(Score, aBuf); } } @@ -370,7 +370,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch if(DDTeam == TEAM_SUPER) str_copy(aBuf, Localize("Super")); else - str_format(aBuf, sizeof(aBuf), "%d", DDTeam); + str_from_int(DDTeam, aBuf); TextRender()->SetCursor(&Cursor, x - 10.0f, y + Spacing + FontSize - (FontSize / 1.5f), FontSize / 1.5f, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = NameLength + 3; } @@ -405,7 +405,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch str_time((int64_t)absolute(pInfo->m_Score) * 100, TIME_HOURS, aBuf, sizeof(aBuf)); } else - str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Score, -999, 99999)); + str_from_int(clamp(pInfo->m_Score, -999, 99999), aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->SetCursor(&Cursor, ScoreOffset + ScoreLength - tw, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER); TextRender()->TextEx(&Cursor, aBuf, -1); @@ -494,7 +494,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch ColorRGBA rgb = color_cast(ColorHSLA((300.0f - clamp(pInfo->m_Latency, 0, 300)) / 1000.0f, 1.0f, 0.5f)); TextRender()->TextColor(rgb); } - str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Latency, 0, 999)); + str_from_int(clamp(pInfo->m_Latency, 0, 999), aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->SetCursor(&Cursor, PingOffset + PingLength - tw, y + (LineHeight - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = PingLength; diff --git a/src/game/client/components/statboard.cpp b/src/game/client/components/statboard.cpp index b3ef5083f14..30136742b4c 100644 --- a/src/game/client/components/statboard.cpp +++ b/src/game/client/components/statboard.cpp @@ -293,14 +293,14 @@ void CStatboard::RenderGlobalStats() // FRAGS { - str_format(aBuf, sizeof(aBuf), "%d", pStats->m_Frags); + str_from_int(pStats->m_Frags, aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(x - tw + px, y + (LineHeight * 0.95f - FontSize) / 2.f, FontSize, aBuf, -1.0f); px += 85; } // DEATHS { - str_format(aBuf, sizeof(aBuf), "%d", pStats->m_Deaths); + str_from_int(pStats->m_Deaths, aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(x - tw + px, y + (LineHeight * 0.95f - FontSize) / 2.f, FontSize, aBuf, -1.0f); px += 85; @@ -308,7 +308,7 @@ void CStatboard::RenderGlobalStats() // SUICIDES { px += 10; - str_format(aBuf, sizeof(aBuf), "%d", pStats->m_Suicides); + str_from_int(pStats->m_Suicides, aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(x - tw + px, y + (LineHeight * 0.95f - FontSize) / 2.f, FontSize, aBuf, -1.0f); px += 85; @@ -340,14 +340,14 @@ void CStatboard::RenderGlobalStats() } // SPREE { - str_format(aBuf, sizeof(aBuf), "%d", pStats->m_CurrentSpree); + str_from_int(pStats->m_CurrentSpree, aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(x - tw + px, y + (LineHeight * 0.95f - FontSize) / 2.f, FontSize, aBuf, -1.0f); px += 85; } // BEST SPREE { - str_format(aBuf, sizeof(aBuf), "%d", pStats->m_BestSpree); + str_from_int(pStats->m_BestSpree, aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(x - tw + px, y + (LineHeight * 0.95f - FontSize) / 2.f, FontSize, aBuf, -1.0f); px += 85; @@ -355,7 +355,7 @@ void CStatboard::RenderGlobalStats() // GRABS if(GameWithFlags) { - str_format(aBuf, sizeof(aBuf), "%d", pStats->m_FlagGrabs); + str_from_int(pStats->m_FlagGrabs, aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(x - tw + px, y + (LineHeight * 0.95f - FontSize) / 2.f, FontSize, aBuf, -1.0f); px += 85; @@ -375,7 +375,7 @@ void CStatboard::RenderGlobalStats() // FLAGS if(GameWithFlags) { - str_format(aBuf, sizeof(aBuf), "%d", pStats->m_FlagCaptures); + str_from_int(pStats->m_FlagCaptures, aBuf); tw = TextRender()->TextWidth(FontSize, aBuf, -1, -1.0f); TextRender()->Text(x - tw + px, y + (LineHeight * 0.95f - FontSize) / 2.f, FontSize, aBuf, -1.0f); } diff --git a/src/game/client/components/voting.cpp b/src/game/client/components/voting.cpp index 392b1937112..dd9dca5c6fa 100644 --- a/src/game/client/components/voting.cpp +++ b/src/game/client/components/voting.cpp @@ -44,7 +44,7 @@ void CVoting::CallvoteSpectate(int ClientID, const char *pReason, bool ForceVote else { char aBuf[32]; - str_format(aBuf, sizeof(aBuf), "%d", ClientID); + str_from_int(ClientID, aBuf); Callvote("spectate", aBuf, pReason); } } @@ -60,7 +60,7 @@ void CVoting::CallvoteKick(int ClientID, const char *pReason, bool ForceVote) else { char aBuf[32]; - str_format(aBuf, sizeof(aBuf), "%d", ClientID); + str_from_int(ClientID, aBuf); Callvote("kick", aBuf, pReason); } } @@ -327,7 +327,7 @@ void CVoting::RenderBars(CUIRect Bars, bool Text) if(Text) { char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "%d", m_Yes); + str_from_int(m_Yes, aBuf); UI()->DoLabel(&YesArea, aBuf, Bars.h * 0.75f, TEXTALIGN_MC); } @@ -345,7 +345,7 @@ void CVoting::RenderBars(CUIRect Bars, bool Text) if(Text) { char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "%d", m_No); + str_from_int(m_No, aBuf); UI()->DoLabel(&NoArea, aBuf, Bars.h * 0.75f, TEXTALIGN_MC); } @@ -355,7 +355,7 @@ void CVoting::RenderBars(CUIRect Bars, bool Text) if(Text && m_Pass) { char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "%d", m_Pass); + str_from_int(m_Pass, aBuf); UI()->DoLabel(&PassArea, aBuf, Bars.h * 0.75f, TEXTALIGN_MC); } } diff --git a/src/game/client/lineinput.cpp b/src/game/client/lineinput.cpp index bb5579a53ae..9f7d3e05045 100644 --- a/src/game/client/lineinput.cpp +++ b/src/game/client/lineinput.cpp @@ -643,7 +643,7 @@ void CLineInputNumber::SetInteger(int Number, int Base, int HexPrefix) switch(Base) { case 10: - str_format(aBuf, sizeof(aBuf), "%d", Number); + str_from_int(Number, aBuf); break; case 16: str_format(aBuf, sizeof(aBuf), "%0*X", HexPrefix, Number); diff --git a/src/game/client/render_map.cpp b/src/game/client/render_map.cpp index d0b983e620b..b04cbbaa5e0 100644 --- a/src/game/client/render_map.cpp +++ b/src/game/client/render_map.cpp @@ -720,7 +720,7 @@ void CRenderTools::RenderTeleOverlay(CTeleTile *pTele, int w, int h, float Scale if(Index && IsTeleTileNumberUsed(pTele[c].m_Type)) { char aBuf[16]; - str_format(aBuf, sizeof(aBuf), "%d", Index); + str_from_int(Index, aBuf); TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha); TextRender()->Text(mx * Scale - 3.f, (my + ToCenterOffset) * Scale, Size * Scale, aBuf, -1.0f); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); @@ -782,13 +782,13 @@ void CRenderTools::RenderSpeedupOverlay(CSpeedupTile *pSpeedup, int w, int h, fl { // draw force char aBuf[16]; - str_format(aBuf, sizeof(aBuf), "%d", Force); + str_from_int(Force, aBuf); TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha); TextRender()->Text(mx * Scale, (my + 0.5f + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); if(MaxSpeed) { - str_format(aBuf, sizeof(aBuf), "%d", MaxSpeed); + str_from_int(MaxSpeed, aBuf); TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha); TextRender()->Text(mx * Scale, (my + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); @@ -839,7 +839,7 @@ void CRenderTools::RenderSwitchOverlay(CSwitchTile *pSwitch, int w, int h, float if(Index && IsSwitchTileNumberUsed(pSwitch[c].m_Type)) { char aBuf[16]; - str_format(aBuf, sizeof(aBuf), "%d", Index); + str_from_int(Index, aBuf); TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha); TextRender()->Text(mx * Scale, (my + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); @@ -849,7 +849,7 @@ void CRenderTools::RenderSwitchOverlay(CSwitchTile *pSwitch, int w, int h, float if(Delay && IsSwitchTileDelayUsed(pSwitch[c].m_Type)) { char aBuf[16]; - str_format(aBuf, sizeof(aBuf), "%d", Delay); + str_from_int(Delay, aBuf); TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha); TextRender()->Text(mx * Scale, (my + 0.5f + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); @@ -898,7 +898,7 @@ void CRenderTools::RenderTuneOverlay(CTuneTile *pTune, int w, int h, float Scale if(Index) { char aBuf[16]; - str_format(aBuf, sizeof(aBuf), "%d", Index); + str_from_int(Index, aBuf); TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha); TextRender()->Text(mx * Scale + 11.f, my * Scale + 6.f, Size * Scale / 1.5f - 5.f, aBuf, -1.0f); // numbers shouldn't be too big and in the center of the tile TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 71450c551de..79b19b6b2ac 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -682,7 +682,7 @@ int CEditor::UiDoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, in else if(IsHex) str_format(aBuf, sizeof(aBuf), "#%06X", Current); else - str_format(aBuf, sizeof(aBuf), "%d", Current); + str_from_int(Current, aBuf); pRect->Draw(pColor ? *pColor : GetButtonColor(pID, 0), Corners, 5.0f); UI()->DoLabel(pRect, aBuf, 10, TEXTALIGN_MC); } @@ -3393,7 +3393,7 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * Shifter.VSplitRight(10.0f, &Shifter, &Inc); Shifter.VSplitLeft(10.0f, &Dec, &Shifter); - str_format(aBuf, sizeof(aBuf), "%d", pProps[i].m_Value); + str_from_int(pProps[i].m_Value, aBuf); int NewValue = UiDoValueSelector((char *)&pIDs[i], &Shifter, "", pProps[i].m_Value, pProps[i].m_Min, pProps[i].m_Max, 1, 1.0f, "Use left mouse button to drag and change the value. Hold shift to be more precise. Rightclick to edit as text.", false, false, 0, &Color); if(NewValue != pProps[i].m_Value) { @@ -6355,7 +6355,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) char aValueBuffer[16]; if(UnitsPerLineY >= 1.0f) { - str_format(aValueBuffer, sizeof(aValueBuffer), "%d", static_cast(Value)); + str_from_int(static_cast(Value), aValueBuffer); } else { diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index b5f19222bdc..9c56b43f6eb 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -641,8 +641,16 @@ void CLayerTiles::ShowInfo() int c = x + y * m_Width; if(m_pTiles[c].m_Index) { - char aBuf[64]; - str_format(aBuf, sizeof(aBuf), m_pEditor->m_ShowTileInfo == CEditor::SHOW_TILE_HEXADECIMAL ? "%02X" : "%i", m_pTiles[c].m_Index); + char aBuf[4]; + if(m_pEditor->m_ShowTileInfo == CEditor::SHOW_TILE_HEXADECIMAL) + { + str_hex(aBuf, sizeof(aBuf), &m_pTiles[c].m_Index, 1); + aBuf[2] = '\0'; // would otherwise be a space + } + else + { + str_from_int(m_pTiles[c].m_Index, aBuf); + } m_pEditor->Graphics()->QuadsText(x * 32, y * 32, 16.0f, aBuf); char aFlags[4] = {m_pTiles[c].m_Flags & TILEFLAG_XFLIP ? 'X' : ' ', diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 46f1c0ca67a..82e8b00d411 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -4212,7 +4212,7 @@ void CGameContext::Converse(int ClientID, char *pStr) bool CGameContext::IsVersionBanned(int Version) { char aVersion[16]; - str_format(aVersion, sizeof(aVersion), "%d", Version); + str_from_int(Version, aVersion); return str_in_list(g_Config.m_SvBannedVersions, ",", aVersion); }