Skip to content

Commit 2d350b9

Browse files
committed
FSUI: Support non-English game titles
1 parent e44aff0 commit 2d350b9

File tree

3 files changed

+41
-14
lines changed

3 files changed

+41
-14
lines changed

pcsx2-qt/MainWindow.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "pcsx2/GSDumpReplayer.h"
3434
#include "pcsx2/GameList.h"
3535
#include "pcsx2/Host.h"
36+
#include "pcsx2/ImGui/FullscreenUI.h"
3637
#include "pcsx2/MTGS.h"
3738
#include "pcsx2/PerformanceMetrics.h"
3839
#include "pcsx2/Recording/InputRecording.h"
@@ -2643,6 +2644,7 @@ SettingsWindow* MainWindow::getSettingsWindow()
26432644
connect(m_settings_window->getInterfaceSettingsWidget(), &InterfaceSettingsWidget::backgroundChanged, m_game_list_widget, [this] { m_game_list_widget->setCustomBackground(); });
26442645
connect(m_settings_window->getGameListSettingsWidget(), &GameListSettingsWidget::preferEnglishGameListChanged, this, [] {
26452646
g_main_window->m_game_list_widget->refreshGridCovers();
2647+
Host::RunOnGSThread([]{ FullscreenUI::PreferEnglishGameListChanged(); });
26462648
});
26472649
}
26482650

pcsx2/ImGui/FullscreenUI.cpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,9 @@ namespace FullscreenUI
696696
// For when we have no GameList entry
697697
static void DrawFallbackCover(const ImVec2& size);
698698
static void DrawFallbackCover(ImDrawList* draw_list, const ImVec2& min, const ImVec2& max);
699+
static std::string_view TrimString(const std::pair<ImFont*, float>& font, std::string_view str, float available_space);
700+
static constexpr const char* g_ellipsis = "\xe2\x80\xa6";
701+
static bool s_prefer_english_titles = false;
699702

700703
// Lazily populated cover images.
701704
static std::unordered_map<std::string, std::string> s_cover_image_map;
@@ -909,6 +912,11 @@ void FullscreenUI::GamepadLayoutChanged()
909912
ApplyLayoutSettings();
910913
}
911914

915+
void FullscreenUI::PreferEnglishGameListChanged()
916+
{
917+
s_prefer_english_titles = Host::GetBaseBoolSettingValue("UI", "PreferEnglishGameList", false);
918+
}
919+
912920
// When drawing an svg to a non-integer size, we get a padded texture.
913921
// This function crops off this padding by setting the image UV for the draw.
914922
// We currently only use integer sizes for images, but I wrote this before checking that.
@@ -970,6 +978,7 @@ bool FullscreenUI::Initialize()
970978
ImGuiFullscreen::UpdateLayoutScale();
971979
ImGuiFullscreen::UpdateFontScale();
972980
ApplyLayoutSettings();
981+
PreferEnglishGameListChanged();
973982

974983
if (!ImGuiFullscreen::Initialize("fullscreenui/placeholder.png") || !LoadResources())
975984
{
@@ -987,7 +996,7 @@ bool FullscreenUI::Initialize()
987996

988997
if (VMManager::HasValidVM())
989998
{
990-
UpdateGameDetails(VMManager::GetDiscPath(), VMManager::GetDiscSerial(), VMManager::GetTitle(true), VMManager::GetDiscCRC(),
999+
UpdateGameDetails(VMManager::GetDiscPath(), VMManager::GetDiscSerial(), VMManager::GetTitle(s_prefer_english_titles), VMManager::GetDiscCRC(),
9911000
VMManager::GetCurrentCRC());
9921001
}
9931002
else
@@ -3710,7 +3719,7 @@ void FullscreenUI::DrawSettingsWindow()
37103719
if (s_game_settings_entry)
37113720
{
37123721
NavTitle(SmallString::from_format(
3713-
"{} ({})", Host::TranslateToCString(TR_CONTEXT, titles[static_cast<u32>(pages[index])]), s_game_settings_entry->GetTitle(true)));
3722+
"{} ({})", Host::TranslateToCString(TR_CONTEXT, titles[static_cast<u32>(pages[index])]), s_game_settings_entry->GetTitle(s_prefer_english_titles)));
37143723
}
37153724
else
37163725
{
@@ -3860,8 +3869,8 @@ void FullscreenUI::DrawSummarySettingsPage()
38603869

38613870
if (s_game_settings_entry)
38623871
{
3863-
if (MenuButton(FSUI_ICONSTR(ICON_FA_TAG, "Title"), s_game_settings_entry->GetTitle(true).c_str(), true))
3864-
CopyTextToClipboard(FSUI_STR("Game title copied to clipboard."), s_game_settings_entry->GetTitle(true));
3872+
if (MenuButton(FSUI_ICONSTR(ICON_FA_TAG, "Title"), s_game_settings_entry->GetTitle(s_prefer_english_titles).c_str(), true))
3873+
CopyTextToClipboard(FSUI_STR("Game title copied to clipboard."), s_game_settings_entry->GetTitle(s_prefer_english_titles));
38653874
if (MenuButton(FSUI_ICONSTR(ICON_FA_PAGER, "Serial"), s_game_settings_entry->serial.c_str(), true))
38663875
CopyTextToClipboard(FSUI_STR("Game serial copied to clipboard."), s_game_settings_entry->serial);
38673876
if (MenuButton(FSUI_ICONSTR(ICON_FA_CODE, "CRC"), fmt::format("{:08X}", s_game_settings_entry->crc).c_str(), true))
@@ -7749,7 +7758,7 @@ void FullscreenUI::PopulateGameListEntryList()
77497758
}
77507759

77517760
// fallback to title when all else is equal
7752-
const int res = StringUtil::Strcasecmp(lhs->GetTitleSort(true).c_str(), rhs->GetTitleSort(true).c_str());
7761+
const int res = StringUtil::Strcasecmp(lhs->GetTitleSort(s_prefer_english_titles).c_str(), rhs->GetTitleSort(s_prefer_english_titles).c_str());
77537762
return reverse ? (res > 0) : (res < 0);
77547763
});
77557764
}
@@ -7855,6 +7864,19 @@ void FullscreenUI::DrawGameListWindow()
78557864
}
78567865
}
78577866

7867+
std::string_view FullscreenUI::TrimString(const std::pair<ImFont*, float>& font, std::string_view str, float available_space)
7868+
{
7869+
const char* beg = str.data();
7870+
const char* end = beg + str.size();
7871+
float full_width = font.first->CalcTextSizeA(font.second, INFINITY, 0, beg, end).x;
7872+
if (full_width <= available_space)
7873+
return str;
7874+
float ellipsis_width = ImGui::CalcTextSize(g_ellipsis).x;
7875+
const char* trimmed = end;
7876+
font.first->CalcTextSizeA(font.second, available_space - ellipsis_width, 0, beg, end, &trimmed);
7877+
return std::string_view(beg, trimmed);
7878+
}
7879+
78587880
void FullscreenUI::DrawGameList(const ImVec2& heading_size)
78597881
{
78607882
ImGui::PushStyleColor(ImGuiCol_WindowBg, UIBackgroundColor);
@@ -7905,10 +7927,10 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
79057927
const float text_start_x = bb.Min.x + image_size.x + LayoutScale(15.0f);
79067928
const ImRect title_bb(ImVec2(text_start_x, bb.Min.y), ImVec2(bb.Max.x, midpoint));
79077929
const ImRect summary_bb(ImVec2(text_start_x, midpoint), bb.Max);
7930+
const std::string& title = entry->GetTitle(s_prefer_english_titles);
79087931

79097932
ImGui::PushFont(g_large_font.first, g_large_font.second);
7910-
// TODO: Fix font fallback issues and enable native-language titles
7911-
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, entry->GetTitle(true).c_str(), entry->GetTitle(true).c_str() + entry->GetTitle(true).size(), nullptr,
7933+
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, title.c_str(), title.c_str() + title.size(), nullptr,
79127934
ImVec2(0.0f, 0.0f), &title_bb);
79137935
ImGui::PopFont();
79147936

@@ -7986,13 +8008,14 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
79868008
{
79878009
// title
79888010
ImGui::PushFont(g_large_font.first, g_large_font.second);
7989-
const std::string_view title(std::string_view(selected_entry->GetTitle(true)).substr(0, 37));
8011+
const std::string_view full_title(selected_entry->GetTitle(s_prefer_english_titles));
8012+
std::string_view title = TrimString(g_large_font, full_title, work_width);
79908013
text_width = ImGui::CalcTextSize(title.data(), title.data() + title.length(), false, work_width).x;
7991-
if (title.length() != selected_entry->GetTitle(true).length())
7992-
text_width += ImGui::CalcTextSize("...", nullptr, false, -1.0f).x;
8014+
if (title.length() != full_title.length())
8015+
text_width += ImGui::CalcTextSize(g_ellipsis).x;
79938016
ImGui::SetCursorPosX((work_width - text_width) / 2.0f);
79948017
ImGui::TextWrapped(
7995-
"%.*s%s", static_cast<int>(title.size()), title.data(), (title.length() == selected_entry->GetTitle(true).length()) ? "" : "...");
8018+
"%.*s%s", static_cast<int>(title.size()), title.data(), (title.length() == full_title.length()) ? "" : g_ellipsis);
79968019
ImGui::PopFont();
79978020

79988021
ImGui::PushFont(g_medium_font.first, g_medium_font.second);
@@ -8147,9 +8170,10 @@ void FullscreenUI::DrawGameGrid(const ImVec2& heading_size)
81478170
if (show_titles)
81488171
{
81498172
const ImRect title_bb(ImVec2(bb.Min.x, bb.Min.y + image_height + title_spacing), bb.Max);
8150-
const std::string_view title(std::string_view(entry->GetTitle(true)).substr(0, 31));
8173+
const std::string_view full_title(entry->GetTitle(s_prefer_english_titles));
8174+
const std::string_view title = TrimString(g_medium_font, full_title, title_bb.GetWidth());
81518175
draw_title.clear();
8152-
fmt::format_to(std::back_inserter(draw_title), "{}{}", title, (title.length() == entry->GetTitle(true).length()) ? "" : "...");
8176+
fmt::format_to(std::back_inserter(draw_title), "{}{}", title, (title.length() == full_title.length()) ? "" : g_ellipsis);
81538177
ImGui::PushFont(g_medium_font.first, g_medium_font.second);
81548178
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, draw_title.c_str(), draw_title.c_str() + draw_title.length(), nullptr,
81558179
ImVec2(0.5f, 0.0f), &title_bb);
@@ -8198,7 +8222,7 @@ void FullscreenUI::HandleGameListOptions(const GameList::Entry* entry)
81988222
options.emplace_back(FSUI_ICONSTR(ICON_FA_SQUARE_XMARK, "Close Menu"), false);
81998223

82008224
const bool has_resume_state = VMManager::HasSaveStateInSlot(entry->serial.c_str(), entry->crc, -1);
8201-
OpenChoiceDialog(entry->GetTitle(true).c_str(), false, std::move(options),
8225+
OpenChoiceDialog(entry->GetTitle(s_prefer_english_titles).c_str(), false, std::move(options),
82028226
[has_resume_state, entry_path = entry->path, entry_serial = entry->serial, entry_title = entry->title, entry_played_time]
82038227
(s32 index, const std::string& title, bool checked) {
82048228
switch (index)

pcsx2/ImGui/FullscreenUI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace FullscreenUI
3535
void SetStandardSelectionFooterText(bool back_instead_of_cancel);
3636
void LocaleChanged();
3737
void GamepadLayoutChanged();
38+
void PreferEnglishGameListChanged();
3839

3940
void Shutdown(bool clear_state);
4041
void Render();

0 commit comments

Comments
 (0)