diff --git a/src/core/achievements.cpp b/src/core/achievements.cpp
index eaad3c0ef..e1817d02d 100644
--- a/src/core/achievements.cpp
+++ b/src/core/achievements.cpp
@@ -1281,11 +1281,11 @@ void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
if (g_settings.achievements_notifications && FullscreenUI::Initialize())
{
std::string title = fmt::format(TRANSLATE_FS("Achievements", "Mastered {}"), s_game_title);
- std::string message =
- fmt::format(TRANSLATE_FS("Achievements", "{0}, {1}"),
- TRANSLATE_PLURAL_STR("Achievements", "%n achievements", "Mastery popup",
- s_game_summary.num_unlocked_achievements),
- TRANSLATE_PLURAL_STR("Achievements", "%n points", "Mastery popup", s_game_summary.points_unlocked));
+ std::string message = fmt::format(
+ TRANSLATE_FS("Achievements", "{0}, {1}"),
+ TRANSLATE_PLURAL_STR("Achievements", "%n achievements", "Mastery popup",
+ s_game_summary.num_unlocked_achievements),
+ TRANSLATE_PLURAL_STR("Achievements", "%n points", "Achievement points", s_game_summary.points_unlocked));
ImGuiFullscreen::AddNotification("achievement_mastery", GAME_COMPLETE_NOTIFICATION_TIME, std::move(title),
std::move(message), s_game_icon);
@@ -2418,8 +2418,8 @@ void Achievements::DrawAchievementsWindow()
{
if (s_game_summary.num_unlocked_achievements == s_game_summary.num_core_achievements)
{
- text.format(TRANSLATE_FS("Achievements", "You have unlocked all achievements and earned {} points!"),
- s_game_summary.points_unlocked);
+ text = TRANSLATE_PLURAL_SSTR("Achievements", "You have unlocked all achievements and earned {} points!",
+ "Point count", s_game_summary.points_unlocked);
}
else
{
@@ -2584,9 +2584,7 @@ void Achievements::DrawAchievement(const rc_client_achievement_t* cheevo)
SmallString text;
const float midpoint = bb.Min.y + g_large_font->FontSize + spacing;
- text.format((cheevo->points != 1) ? TRANSLATE_FS("Achievements", "{} points") :
- TRANSLATE_FS("Achievements", "{} point"),
- cheevo->points);
+ text = TRANSLATE_PLURAL_SSTR("Achievements", "%n points", "Achievement points", cheevo->points);
const ImVec2 points_size(
g_medium_font->CalcTextSizeA(g_medium_font->FontSize, FLT_MAX, 0.0f, text.c_str(), text.end_ptr()));
const float points_template_start = bb.Max.x - points_template_size.x;
@@ -2822,7 +2820,7 @@ void Achievements::DrawLeaderboardsWindow()
u32 count = 0;
for (u32 i = 0; i < s_leaderboard_list->num_buckets; i++)
count += s_leaderboard_list->buckets[i].num_leaderboards;
- text.format(TRANSLATE_FS("Achievements", "This game has {} leaderboards."), count);
+ text = TRANSLATE_PLURAL_SSTR("Achievements", "This game has %n leaderboards.", "Leaderboard count", count);
}
const ImRect summary_bb(ImVec2(left, top), ImVec2(right, top + g_medium_font->FontSize));
diff --git a/src/duckstation-qt/translations/create-update-and-edit-language.bat b/src/duckstation-qt/translations/create-update-and-edit-language.bat
index 548cd9188..53b7b32cf 100644
--- a/src/duckstation-qt/translations/create-update-and-edit-language.bat
+++ b/src/duckstation-qt/translations/create-update-and-edit-language.bat
@@ -66,7 +66,7 @@ REM A good .ts file has been passed
ECHO Updating %filename%...
ECHO.
SET "linguist=..\..\..\dep\msvc\deps-x64\bin"
-SET "context=.././ ../../core/ ../../util/ -tr-function-alias QT_TRANSLATE_NOOP+=TRANSLATE,QT_TRANSLATE_NOOP+=TRANSLATE_SV,QT_TRANSLATE_NOOP+=TRANSLATE_STR,QT_TRANSLATE_NOOP+=TRANSLATE_FS,QT_TRANSLATE_N_NOOP3+=TRANSLATE_FMT,QT_TRANSLATE_NOOP+=TRANSLATE_NOOP,translate+=TRANSLATE_PLURAL_STR,translate+=TRANSLATE_PLURAL_FS"
+SET "context=.././ ../../core/ ../../util/ -tr-function-alias QT_TRANSLATE_NOOP+=TRANSLATE,QT_TRANSLATE_NOOP+=TRANSLATE_SV,QT_TRANSLATE_NOOP+=TRANSLATE_STR,QT_TRANSLATE_NOOP+=TRANSLATE_FS,QT_TRANSLATE_N_NOOP3+=TRANSLATE_FMT,QT_TRANSLATE_NOOP+=TRANSLATE_NOOP,translate+=TRANSLATE_PLURAL_STR,translate+=TRANSLATE_PLURAL_SSTR,translate+=TRANSLATE_PLURAL_FS"
"%linguist%\lupdate.exe" %context% -ts %filename%
ECHO.
diff --git a/src/duckstation-qt/translations/duckstation-qt_en.ts b/src/duckstation-qt/translations/duckstation-qt_en.ts
index 40433c9bd..5c1e859ce 100644
--- a/src/duckstation-qt/translations/duckstation-qt_en.ts
+++ b/src/duckstation-qt/translations/duckstation-qt_en.ts
@@ -16,7 +16,7 @@
Achievements
-
+
Achievement popup
@@ -25,7 +25,7 @@
-
+
Achievement popup
@@ -34,7 +34,7 @@
-
+
Mastery popup
@@ -43,19 +43,38 @@
-
+
+
- Mastery popup
+ Achievement points
%n point
%n points
+
+
+
+ Point count
+
+ You have unlocked all achievements and earned {} point!
+ You have unlocked all achievements and earned {} points!
+
+
+
+
+
+ Leaderboard count
+
+ This game has %n leaderboard.
+ This game has %n leaderboards.
+
+
EmulationSettingsWidget
-
+
Rewind for %n frame, lasting %1 second(s) will require up to %2MB of RAM and %3MB of VRAM.
@@ -66,7 +85,17 @@
GameList
-
+
+
+
+
+ %n hour
+ %n hours
+
+
+
+
+
%n minute
@@ -77,7 +106,7 @@
InputBindingWidget
-
+
%n binding
@@ -88,7 +117,7 @@
MemoryCardEditorWindow
-
+
%n block free%1
@@ -99,7 +128,7 @@
System
-
+
%n cheat is now active.
@@ -107,7 +136,7 @@
-
+
%n cheat is now inactive.
@@ -115,7 +144,7 @@
-
+
%n cheat is enabled. This may crash games.
diff --git a/src/duckstation-qt/translations/update-and-edit-english.bat b/src/duckstation-qt/translations/update-and-edit-english.bat
index 02046879a..ef13900e5 100644
--- a/src/duckstation-qt/translations/update-and-edit-english.bat
+++ b/src/duckstation-qt/translations/update-and-edit-english.bat
@@ -1,7 +1,7 @@
@echo off
set "linguist=..\..\..\dep\msvc\deps-x64\bin"
-set context=../ ../../core/ ../../util/ -tr-function-alias QT_TRANSLATE_NOOP+=TRANSLATE,QT_TRANSLATE_NOOP+=TRANSLATE_SV,QT_TRANSLATE_NOOP+=TRANSLATE_STR,QT_TRANSLATE_NOOP+=TRANSLATE_FS,QT_TRANSLATE_N_NOOP3+=TRANSLATE_FMT,QT_TRANSLATE_NOOP+=TRANSLATE_NOOP,translate+=TRANSLATE_PLURAL_STR,translate+=TRANSLATE_PLURAL_FS -pluralonly -no-obsolete
+set context=../ ../../core/ ../../util/ -tr-function-alias QT_TRANSLATE_NOOP+=TRANSLATE,QT_TRANSLATE_NOOP+=TRANSLATE_SV,QT_TRANSLATE_NOOP+=TRANSLATE_STR,QT_TRANSLATE_NOOP+=TRANSLATE_FS,QT_TRANSLATE_N_NOOP3+=TRANSLATE_FMT,QT_TRANSLATE_NOOP+=TRANSLATE_NOOP,translate+=TRANSLATE_PLURAL_STR,translate+=TRANSLATE_PLURAL_SSTR,translate+=TRANSLATE_PLURAL_FS -pluralonly -no-obsolete
"%linguist%\lupdate.exe" %context% -ts duckstation-qt_en.ts
pause
diff --git a/src/duckstation-qt/translations/update-and-edit-language.bat b/src/duckstation-qt/translations/update-and-edit-language.bat
index 195ff9cf6..0f15ebe84 100644
--- a/src/duckstation-qt/translations/update-and-edit-language.bat
+++ b/src/duckstation-qt/translations/update-and-edit-language.bat
@@ -3,7 +3,7 @@
if not defined lang (echo Please set your language first & pause & exit)
set "linguist=..\..\..\dep\msvc\deps-x64\bin"
-SET "context=.././ ../../core/ ../../util/ -tr-function-alias QT_TRANSLATE_NOOP+=TRANSLATE,QT_TRANSLATE_NOOP+=TRANSLATE_SV,QT_TRANSLATE_NOOP+=TRANSLATE_STR,QT_TRANSLATE_NOOP+=TRANSLATE_FS,QT_TRANSLATE_N_NOOP3+=TRANSLATE_FMT,QT_TRANSLATE_NOOP+=TRANSLATE_NOOP,translate+=TRANSLATE_PLURAL_STR,translate+=TRANSLATE_PLURAL_FS"
+SET "context=.././ ../../core/ ../../util/ -tr-function-alias QT_TRANSLATE_NOOP+=TRANSLATE,QT_TRANSLATE_NOOP+=TRANSLATE_SV,QT_TRANSLATE_NOOP+=TRANSLATE_STR,QT_TRANSLATE_NOOP+=TRANSLATE_FS,QT_TRANSLATE_N_NOOP3+=TRANSLATE_FMT,QT_TRANSLATE_NOOP+=TRANSLATE_NOOP,translate+=TRANSLATE_PLURAL_STR,translate+=TRANSLATE_PLURAL_SSTR,translate+=TRANSLATE_PLURAL_FS"
"%linguist%\lupdate.exe" %context% -noobsolete -ts duckstation-qt_%lang%.ts
pause
diff --git a/src/util/imgui_glyph_ranges.inl b/src/util/imgui_glyph_ranges.inl
index f1979b5fa..4359b2813 100644
--- a/src/util/imgui_glyph_ranges.inl
+++ b/src/util/imgui_glyph_ranges.inl
@@ -1,8 +1,8 @@
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin
// SPDX-License-Identifier: (GPL-3.0 OR PolyForm-Strict-1.0.0)
-static constexpr ImWchar FA_ICON_RANGE[] = { 0xe06f,0xe06f,0xe086,0xe086,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf011,0xf013,0xf013,0xf017,0xf017,0xf019,0xf019,0xf01c,0xf01c,0xf021,0xf021,0xf025,0xf025,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03d,0xf04a,0xf04c,0xf050,0xf050,0xf05e,0xf05e,0xf062,0xf063,0xf067,0xf067,0xf071,0xf071,0xf075,0xf075,0xf077,0xf078,0xf07b,0xf07c,0xf084,0xf085,0xf091,0xf091,0xf0a0,0xf0a0,0xf0ac,0xf0ad,0xf0c5,0xf0c5,0xf0c7,0xf0c9,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e2,0xf0e2,0xf0e7,0xf0e7,0xf0eb,0xf0eb,0xf0f1,0xf0f1,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf110,0xf110,0xf119,0xf119,0xf11b,0xf11c,0xf140,0xf140,0xf14a,0xf14a,0xf15b,0xf15b,0xf15d,0xf15d,0xf191,0xf192,0xf1ab,0xf1ab,0xf1dd,0xf1de,0xf1e6,0xf1e6,0xf1eb,0xf1eb,0xf1f8,0xf1f8,0xf1fc,0xf1fc,0xf240,0xf240,0xf242,0xf242,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2d0,0xf2d0,0xf2db,0xf2db,0xf2f2,0xf2f2,0xf3fd,0xf3fd,0xf410,0xf410,0xf466,0xf466,0xf4ce,0xf4ce,0xf500,0xf500,0xf51f,0xf51f,0xf538,0xf538,0xf545,0xf545,0xf547,0xf548,0xf57a,0xf57a,0xf5a2,0xf5a2,0xf5aa,0xf5aa,0xf5e7,0xf5e7,0xf65d,0xf65e,0xf6cf,0xf6cf,0xf70c,0xf70c,0xf794,0xf794,0xf7a0,0xf7a0,0xf7c2,0xf7c2,0xf807,0xf807,0xf815,0xf815,0xf818,0xf818,0xf84c,0xf84c,0xf8cc,0xf8cc,0x0,0x0 };
+static constexpr ImWchar FA_ICON_RANGE[] = { 0xe06f,0xe06f,0xe086,0xe086,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf011,0xf013,0xf013,0xf017,0xf017,0xf019,0xf019,0xf01c,0xf01c,0xf021,0xf021,0xf023,0xf023,0xf025,0xf025,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03d,0xf04a,0xf04c,0xf050,0xf050,0xf05e,0xf05e,0xf062,0xf063,0xf067,0xf067,0xf071,0xf071,0xf075,0xf075,0xf077,0xf078,0xf07b,0xf07c,0xf084,0xf085,0xf091,0xf091,0xf0a0,0xf0a0,0xf0ac,0xf0ad,0xf0c5,0xf0c5,0xf0c7,0xf0c9,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e2,0xf0e2,0xf0e7,0xf0e7,0xf0eb,0xf0eb,0xf0f1,0xf0f1,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf110,0xf110,0xf119,0xf119,0xf11b,0xf11c,0xf140,0xf140,0xf14a,0xf14a,0xf15b,0xf15b,0xf15d,0xf15d,0xf191,0xf192,0xf1ab,0xf1ab,0xf1dd,0xf1de,0xf1e6,0xf1e6,0xf1eb,0xf1eb,0xf1f8,0xf1f8,0xf1fc,0xf1fc,0xf240,0xf240,0xf242,0xf242,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2d0,0xf2d0,0xf2db,0xf2db,0xf2f2,0xf2f2,0xf3fd,0xf3fd,0xf410,0xf410,0xf466,0xf466,0xf4ce,0xf4ce,0xf500,0xf500,0xf51f,0xf51f,0xf538,0xf538,0xf545,0xf545,0xf547,0xf548,0xf57a,0xf57a,0xf5a2,0xf5a2,0xf5aa,0xf5aa,0xf5e7,0xf5e7,0xf65d,0xf65e,0xf6cf,0xf6cf,0xf70c,0xf70c,0xf794,0xf794,0xf7a0,0xf7a0,0xf7c2,0xf7c2,0xf807,0xf807,0xf815,0xf815,0xf818,0xf818,0xf84c,0xf84c,0xf8cc,0xf8cc,0x0,0x0 };
static constexpr ImWchar PF_ICON_RANGE[] = { 0x2196,0x2199,0x219e,0x21a1,0x21b0,0x21b3,0x21ba,0x21c3,0x21c7,0x21ca,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21ed,0x21ee,0x21f7,0x21f8,0x21fa,0x21fb,0x227a,0x227f,0x2284,0x2284,0x235e,0x235e,0x2360,0x2361,0x2364,0x2366,0x23b2,0x23b4,0x23ce,0x23ce,0x23f4,0x23f7,0x2427,0x243a,0x243c,0x243e,0x2460,0x246b,0x24f5,0x24fd,0x24ff,0x24ff,0x2717,0x2717,0x278a,0x278e,0x27fc,0x27fc,0xe001,0xe001,0xff21,0xff3a,0x1f52b,0x1f52b,0x0,0x0 };
-static constexpr ImWchar EMOJI_ICON_RANGE[] = { 0x2139,0x2139,0x23e9,0x23ea,0x23f8,0x23f8,0x26a0,0x26a0,0x1f3a5,0x1f3a5,0x1f4be,0x1f4be,0x1f4c2,0x1f4c2,0x1f4f7,0x1f4f8,0x1f507,0x1f507,0x1f509,0x1f50a,0x1f50d,0x1f50d,0x1f512,0x1f513,0x0,0x0 };
+static constexpr ImWchar EMOJI_ICON_RANGE[] = { 0x2139,0x2139,0x23e9,0x23ea,0x23f8,0x23f8,0x26a0,0x26a0,0x1f3a5,0x1f3a5,0x1f4be,0x1f4be,0x1f4c2,0x1f4c2,0x1f4f7,0x1f4f8,0x1f507,0x1f507,0x1f509,0x1f50a,0x1f50d,0x1f50d,0x1f513,0x1f513,0x0,0x0 };