mirror of
https://github.com/stenzek/duckstation.git
synced 2026-07-11 01:24:11 +02:00
FullscreenUI: Add custom title/disc set title/serial editing
This commit is contained in:
@@ -101,6 +101,11 @@ static void ProcessImageVerificationResults(std::string path, GameDatabase::Trac
|
||||
|
||||
static void DrawSummarySettingsPage(bool show_localized_titles);
|
||||
static void DrawSummarySettingsTrackList();
|
||||
static void OpenGameTitleActions(const std::string_view& path, const std::string_view& title, bool has_custom_title,
|
||||
bool is_disc_set_title);
|
||||
static void OpenGameSerialActions(const std::string& path, const std::string& serial, bool has_custom_serial);
|
||||
static void SaveCustomTitle(const std::string& path, const std::string& title);
|
||||
static void SaveCustomSerial(const std::string& path, const std::string& serial);
|
||||
static void DrawInterfaceSettingsPage();
|
||||
static void DrawGameListSettingsPage();
|
||||
static void DrawBIOSSettingsPage();
|
||||
@@ -1720,7 +1725,7 @@ bool FullscreenUI::SwitchToGameSettingsForPath(const std::string& path, Settings
|
||||
const GameList::Entry* entry = !path.empty() ? GameList::GetEntryForPath(path) : nullptr;
|
||||
|
||||
// playlists will always contain the first disc's serial, so use the current game instead
|
||||
if (!entry || entry->serial.empty() || entry->type == GameList::EntryType::Playlist)
|
||||
if (!entry || entry->serial.empty() || (entry->type == GameList::EntryType::Playlist && VideoThread::HasGPUBackend()))
|
||||
{
|
||||
Host::RunOnCoreThread([page]() {
|
||||
Error error;
|
||||
@@ -2142,6 +2147,8 @@ void FullscreenUI::DrawSettingsWindow()
|
||||
|
||||
void FullscreenUI::DrawSummarySettingsPage(bool show_localized_titles)
|
||||
{
|
||||
SmallString sstr;
|
||||
|
||||
BeginMenuButtons();
|
||||
ResetFocusHere();
|
||||
|
||||
@@ -2156,14 +2163,68 @@ void FullscreenUI::DrawSummarySettingsPage(bool show_localized_titles)
|
||||
|
||||
if (s_settings_locals.game_settings_entry)
|
||||
{
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_WINDOW_MAXIMIZE, "Title"),
|
||||
s_settings_locals.game_settings_entry->GetDisplayTitle(show_localized_titles), true))
|
||||
const bool allow_customization = !s_settings_locals.game_settings_entry->is_runtime_populated;
|
||||
const std::string_view title = s_settings_locals.game_settings_entry->GetDisplayTitle(show_localized_titles);
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_WINDOW_MAXIMIZE, "Title"), title, true))
|
||||
{
|
||||
CopyTextToClipboard(FSUI_STR("Game title copied to clipboard."),
|
||||
s_settings_locals.game_settings_entry->GetDisplayTitle(show_localized_titles));
|
||||
if (allow_customization)
|
||||
{
|
||||
OpenGameTitleActions(s_settings_locals.game_settings_entry->path, title,
|
||||
s_settings_locals.game_settings_entry->has_custom_title, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyTextToClipboard(FSUI_STR("Game title copied to clipboard."), title);
|
||||
}
|
||||
}
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_PAGER, "Serial"), s_settings_locals.game_settings_entry->serial, true))
|
||||
CopyTextToClipboard(FSUI_STR("Game serial copied to clipboard."), s_settings_locals.game_settings_entry->serial);
|
||||
|
||||
if (s_settings_locals.game_settings_entry->disc_set_member)
|
||||
{
|
||||
const std::string_view disc_set_name = s_settings_locals.game_settings_entry->GetDiscSetEntry()->GetSaveTitle();
|
||||
std::string disc_set_title;
|
||||
bool has_custom_disc_set_title = false;
|
||||
{
|
||||
const auto lock = GameList::GetLock();
|
||||
const GameList::Entry* const disc_set_entry = GameList::GetEntryForPath(disc_set_name);
|
||||
if (disc_set_entry)
|
||||
{
|
||||
disc_set_title = disc_set_entry->GetDisplayTitle(show_localized_titles);
|
||||
has_custom_disc_set_title = disc_set_entry->has_custom_title;
|
||||
}
|
||||
}
|
||||
|
||||
if (!disc_set_title.empty() &&
|
||||
MenuButton(FSUI_ICONVSTR(ICON_FA_LAYER_GROUP, "Disc Set Title"), disc_set_title, true))
|
||||
{
|
||||
if (allow_customization)
|
||||
OpenGameTitleActions(disc_set_name, disc_set_title, has_custom_disc_set_title, true);
|
||||
else
|
||||
CopyTextToClipboard(FSUI_STR("Disc set title copied to clipboard."), disc_set_title);
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view visible_serial = s_settings_locals.game_settings_entry->serial;
|
||||
if (s_settings_locals.game_settings_entry->has_custom_serial)
|
||||
{
|
||||
sstr.format(FSUI_FSTR("{} (Custom)"), s_settings_locals.game_settings_entry->serial);
|
||||
visible_serial = sstr;
|
||||
}
|
||||
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_PAGER, "Serial"), visible_serial, true))
|
||||
{
|
||||
if (allow_customization)
|
||||
{
|
||||
OpenGameSerialActions(s_settings_locals.game_settings_entry->path,
|
||||
s_settings_locals.game_settings_entry->serial,
|
||||
s_settings_locals.game_settings_entry->has_custom_serial);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyTextToClipboard(FSUI_STR("Game serial copied to clipboard."),
|
||||
s_settings_locals.game_settings_entry->serial);
|
||||
}
|
||||
}
|
||||
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_COMPACT_DISC, "Type"),
|
||||
GameList::GetEntryTypeDisplayName(s_settings_locals.game_settings_entry->type), true))
|
||||
{
|
||||
@@ -2226,6 +2287,125 @@ void FullscreenUI::DrawSummarySettingsPage(bool show_localized_titles)
|
||||
EndMenuButtons();
|
||||
}
|
||||
|
||||
void FullscreenUI::OpenGameTitleActions(const std::string_view& path, const std::string_view& title,
|
||||
bool has_custom_title, bool is_disc_set_title)
|
||||
{
|
||||
ChoiceDialogOptions options;
|
||||
options.reserve(has_custom_title ? 4 : 3);
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_FILE_PEN, "Change Title"), false);
|
||||
if (has_custom_title)
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_ARROW_ROTATE_LEFT, "Reset Title"), false);
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_COPY, "Copy Title"), false);
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_SQUARE_XMARK, "Close Menu"), false);
|
||||
|
||||
OpenChoiceDialog(is_disc_set_title ? FSUI_ICONVSTR(ICON_FA_LAYER_GROUP, "Disc Set Title") :
|
||||
FSUI_ICONVSTR(ICON_FA_WINDOW_MAXIMIZE, "Game Title"),
|
||||
false, std::move(options),
|
||||
[path = std::string(path), title = std::string(title), has_custom_title,
|
||||
is_disc_set_title](s32 index, const std::string&, bool) mutable {
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
OpenInputStringDialog(is_disc_set_title ?
|
||||
FSUI_ICONSTR(ICON_FA_LAYER_GROUP, "Change Disc Set Title") :
|
||||
FSUI_ICONSTR(ICON_FA_WINDOW_MAXIMIZE, "Change Game Title"),
|
||||
is_disc_set_title ? FSUI_STR("Enter a new title for this disc set.") :
|
||||
FSUI_STR("Enter a new title for this game."),
|
||||
FSUI_STR("Title:"), FSUI_ICONSTR(ICON_FA_CHECK, "Save"), title,
|
||||
[path = std::move(path)](std::string new_title) mutable {
|
||||
if (!new_title.empty())
|
||||
SaveCustomTitle(std::move(path), std::move(new_title));
|
||||
});
|
||||
}
|
||||
else if (has_custom_title && index == 1)
|
||||
{
|
||||
SaveCustomTitle(std::move(path), {});
|
||||
}
|
||||
else if (index == (has_custom_title ? 2 : 1))
|
||||
{
|
||||
CopyTextToClipboard(is_disc_set_title ? FSUI_STR("Disc set title copied to clipboard.") :
|
||||
FSUI_STR("Game title copied to clipboard."),
|
||||
title);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FullscreenUI::OpenGameSerialActions(const std::string& path, const std::string& serial, bool has_custom_serial)
|
||||
{
|
||||
ChoiceDialogOptions options;
|
||||
options.reserve(has_custom_serial ? 4 : 3);
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_FILE_PEN, "Change Serial"), false);
|
||||
if (has_custom_serial)
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_ARROW_ROTATE_LEFT, "Reset Serial"), false);
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_COPY, "Copy Serial"), false);
|
||||
options.emplace_back(FSUI_ICONSTR(ICON_FA_SQUARE_XMARK, "Close Menu"), false);
|
||||
|
||||
OpenChoiceDialog(FSUI_ICONVSTR(ICON_FA_PAGER, "Game Serial"), false, std::move(options),
|
||||
[path, serial, has_custom_serial](s32 index, const std::string&, bool) mutable {
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
OpenInputStringDialog(FSUI_ICONSTR(ICON_FA_PAGER, "Change Game Serial"),
|
||||
FSUI_STR("Enter a new serial for this game."), FSUI_STR("Serial:"),
|
||||
FSUI_ICONSTR(ICON_FA_CHECK, "Save"), serial,
|
||||
[path = std::move(path)](std::string new_serial) mutable {
|
||||
StringUtil::StripWhitespace(&new_serial);
|
||||
if (!new_serial.empty())
|
||||
SaveCustomSerial(std::move(path), std::move(new_serial));
|
||||
});
|
||||
}
|
||||
else if (has_custom_serial && index == 1)
|
||||
{
|
||||
SaveCustomSerial(std::move(path), {});
|
||||
}
|
||||
else if (index == (has_custom_serial ? 2 : 1))
|
||||
{
|
||||
CopyTextToClipboard(FSUI_STR("Game serial copied to clipboard."), serial);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FullscreenUI::SaveCustomTitle(const std::string& path, const std::string& title)
|
||||
{
|
||||
if (!GameList::SaveCustomTitleForPath(path, title))
|
||||
{
|
||||
ShowToast(OSDMessageType::Error, {}, FSUI_STR("Failed to save custom title."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!s_settings_locals.game_settings_entry || s_settings_locals.game_settings_entry->path != path)
|
||||
return;
|
||||
|
||||
const auto lock = GameList::GetLock();
|
||||
const GameList::Entry* const entry = GameList::GetEntryForPath(path);
|
||||
if (entry)
|
||||
{
|
||||
SwitchToGameSettings(entry, SettingsPage::Summary);
|
||||
ShowToast(OSDMessageType::Info, {}, FSUI_STR("Game title updated."));
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::SaveCustomSerial(const std::string& path, const std::string& serial)
|
||||
{
|
||||
if (!GameList::SaveCustomSerialForPath(path, serial))
|
||||
{
|
||||
ShowToast(OSDMessageType::Error, {}, FSUI_STR("Failed to save custom serial."));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto lock = GameList::GetLock();
|
||||
const GameList::Entry* const entry = GameList::GetEntryForPath(path);
|
||||
if (entry)
|
||||
{
|
||||
SwitchToGameSettings(entry, SettingsPage::Summary);
|
||||
ShowToast(OSDMessageType::Info, {}, FSUI_STR("Game serial updated."));
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawSummarySettingsTrackList()
|
||||
{
|
||||
DebugAssert(!s_settings_locals.image_track_list.empty());
|
||||
|
||||
@@ -143,8 +143,13 @@ TRANSLATE_NOOP("FullscreenUI", "Cancel");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Capture");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Challenge Indicators");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Disc");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Disc Set Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Game Serial");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Game Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Page");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Selection");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Serial");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Change View");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Changes settings for the application.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Changes the aspect ratio used to display the console's output to the screen.");
|
||||
@@ -185,7 +190,9 @@ TRANSLATE_NOOP("FullscreenUI", "Controls the volume of the audio played on the h
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copies the current global settings to this game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copies the global controller configuration to this game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copy Global Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copy Serial");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copy Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Copy Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Could not find any CD/DVD-ROM devices. Please ensure you have a drive connected and sufficient permissions to access it.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Cover Download Error");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Cover Downloader");
|
||||
@@ -265,6 +272,8 @@ TRANSLATE_NOOP("FullscreenUI", "Disabled");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disables texture emulation in the GPU, forcing all primitives to only show vertex colours.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disables vertex lighting in the GPU, forcing all primitives to only show raw texture colours.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disc");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disc Set Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disc set title copied to clipboard.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Discord Server");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Display Area");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Displays only the game title in the list, instead of the title and serial/file name.");
|
||||
@@ -332,6 +341,9 @@ TRANSLATE_NOOP("FullscreenUI", "Enables the replacement of background textures i
|
||||
TRANSLATE_NOOP("FullscreenUI", "Encore Mode");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Ensures every frame generated is displayed for optimal pacing. Enable for variable refresh displays, such as GSync/FreeSync. Disable if you are having speed or sound issues.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enter Value");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enter a new serial for this game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enter a new title for this disc set.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enter a new title for this game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enter the name of the controller preset you wish to create.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Error");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Error Message Duration");
|
||||
@@ -351,6 +363,8 @@ TRANSLATE_NOOP("FullscreenUI", "Failed to load '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to load resume save state info.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to load shader {}. It may be invalid.\nError was:");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to save controller preset '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to save custom serial.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to save custom title.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Fast Boot");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Fast Forward Boot");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Fast Forward Memory Card Access");
|
||||
@@ -382,14 +396,18 @@ TRANSLATE_NOOP("FullscreenUI", "Game List Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Patches");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Properties");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Quick Save");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Serial");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Slot {0}##game_slot_{0}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game compatibility rating copied to clipboard.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game path copied to clipboard.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game region copied to clipboard.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game serial copied to clipboard.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game serial updated.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game settings have been cleared for '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game settings initialized with global settings for '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game title copied to clipboard.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game title updated.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game type copied to clipboard.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Gamepad Button Type");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Genre: ");
|
||||
@@ -613,7 +631,9 @@ TRANSLATE_NOOP("FullscreenUI", "Rescan All Games");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Reset");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Reset Controller Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Reset Play Time");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Reset Serial");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Reset Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Reset Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Reset To Default");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Resets all configuration to defaults (including bindings).");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Resets all settings to the defaults.");
|
||||
@@ -641,6 +661,7 @@ TRANSLATE_NOOP("FullscreenUI", "Runs the software renderer in parallel for VRAM
|
||||
TRANSLATE_NOOP("FullscreenUI", "SDL DualSense Player LED");
|
||||
TRANSLATE_NOOP("FullscreenUI", "SDL DualShock 4 / DualSense Enhanced Mode");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Safe Mode");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Save");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Save Controller Preset");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Save Locations");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Save Preset");
|
||||
@@ -698,6 +719,7 @@ TRANSLATE_NOOP("FullscreenUI", "Selects the type of emulated controller for this
|
||||
TRANSLATE_NOOP("FullscreenUI", "Selects the view that the game list will open to.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Selects which location on the screen messages are displayed.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Serial");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Serial:");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Session: {}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Set Cover Image");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Set Input Binding");
|
||||
@@ -812,6 +834,7 @@ TRANSLATE_NOOP("FullscreenUI", "Time Played");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Time Played: ");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Timing out in {:.0f} seconds...");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Title");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Title:");
|
||||
TRANSLATE_NOOP("FullscreenUI", "To use achievements, please log in with your retroachievements.org account.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Toggle Analog");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Toggle Fast Forward");
|
||||
@@ -900,6 +923,7 @@ TRANSLATE_NOOP("FullscreenUI", "change disc");
|
||||
TRANSLATE_NOOP("FullscreenUI", "restart");
|
||||
TRANSLATE_NOOP("FullscreenUI", "shut down");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{0} achievement unlocks have not been confirmed by the server. Continuing to {1} will result in loss of these unlocks. Once network connectivity has been re-established, these unlocks will be confirmed automatically.\n\nDo you want to {1} anyway?");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} (Custom)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} Frames");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} deleted.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} does not exist.");
|
||||
|
||||
Reference in New Issue
Block a user