GameList: Show (Disc 1) for first disc of two-disc games

Append disc label to the first disc of two-disc games too, rather than
only labelling the second disc.
This commit is contained in:
Dentomologist 2024-04-11 16:35:18 -07:00
parent 1fa5c3485c
commit 37b89d5b71
4 changed files with 82 additions and 6 deletions

View File

@ -92,14 +92,14 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
{ {
QString name = QString::fromStdString(game.GetName(m_title_database)); QString name = QString::fromStdString(game.GetName(m_title_database));
// Add disc numbers > 1 to title if not present. const int disc_number = game.GetDiscNumber() + 1;
const int disc_nr = game.GetDiscNumber() + 1; if (disc_number > 1 || game.IsTwoDiscGame())
if (disc_nr > 1)
{ {
if (!name.contains(QRegularExpression(QStringLiteral("disc ?%1").arg(disc_nr), // Add disc number to title if not present.
if (!name.contains(QRegularExpression(QStringLiteral("disc ?%1").arg(disc_number),
QRegularExpression::CaseInsensitiveOption))) QRegularExpression::CaseInsensitiveOption)))
{ {
name.append(tr(" (Disc %1)").arg(disc_nr)); name.append(tr(" (Disc %1)").arg(disc_number));
} }
} }

View File

@ -135,6 +135,7 @@ GameFile::GameFile(std::string path) : m_file_path(std::move(path))
m_maker_id = volume->GetMakerID(); m_maker_id = volume->GetMakerID();
m_revision = volume->GetRevision().value_or(0); m_revision = volume->GetRevision().value_or(0);
m_disc_number = volume->GetDiscNumber().value_or(0); m_disc_number = volume->GetDiscNumber().value_or(0);
m_is_two_disc_game = CheckIfTwoDiscGame(m_game_id);
m_apploader_date = volume->GetApploaderDate(); m_apploader_date = volume->GetApploaderDate();
m_volume_banner.buffer = volume->GetBanner(&m_volume_banner.width, &m_volume_banner.height); m_volume_banner.buffer = volume->GetBanner(&m_volume_banner.width, &m_volume_banner.height);
@ -321,6 +322,7 @@ void GameFile::DoState(PointerWrap& p)
p.Do(m_compression_method); p.Do(m_compression_method);
p.Do(m_revision); p.Do(m_revision);
p.Do(m_disc_number); p.Do(m_disc_number);
p.Do(m_is_two_disc_game);
p.Do(m_apploader_date); p.Do(m_apploader_date);
p.Do(m_custom_name); p.Do(m_custom_name);
@ -547,6 +549,77 @@ std::vector<DiscIO::Language> GameFile::GetLanguages() const
return languages; return languages;
} }
bool GameFile::CheckIfTwoDiscGame(const std::string& game_id) const
{
constexpr size_t GAME_ID_PREFIX_SIZE = 3;
if (game_id.size() < GAME_ID_PREFIX_SIZE)
return false;
static constexpr std::array<std::string_view, 30> two_disc_game_id_prefixes = {
// Resident Evil
"DBJ",
// The Lord of the Rings: The Third Age
"G3A",
// Teenage Mutant Ninja Turtles 3: Mutant Nightmare
"G3Q",
// Resident Evil 4
"G4B",
// Tiger Woods PGA Tour 2005
"G5T",
// Resident Evil
"GBI",
// Resident Evil Zero
"GBZ",
// Conan
"GC9",
// Resident Evil Code: Veronica X
"GCD",
// Tom Clancy's Splinter Cell: Chaos Theory
"GCJ",
// Freaky Flyers
"GFF",
// GoldenEye: Rogue Agent
"GGI",
// Metal Gear Solid: The Twin Snakes
"GGS",
// Baten Kaitos Origins
"GK4",
// Killer7
"GK7",
// Baten Kaitos: Eternal Wings and the Lost Ocean
"GKB",
// Lupin the 3rd: Lost Treasure by the Sea
"GL3",
// Enter the Matrix
"GMX",
// Teenage Mutant Ninja Turtles 2: Battle Nexus
"GNI",
// GoldenEye: Rogue Agent
"GOY",
// Tales of Symphonia
"GQS",
// Medal of Honor: Rising Sun
"GR8",
"GRZ",
// Tales of Symphonia
"GTO",
// Tiger Woods PGA Tour 2004
"GW4",
// Tom Clancy's Splinter Cell: Double Agent (GC)
"GWY",
// Dragon Quest X: Mezameshi Itsutsu no Shuzoku Online
"S4M",
"S4S",
"S6T",
"SDQ",
};
static_assert(std::is_sorted(two_disc_game_id_prefixes.begin(), two_disc_game_id_prefixes.end()));
std::string_view game_id_prefix(game_id.data(), GAME_ID_PREFIX_SIZE);
return std::binary_search(two_disc_game_id_prefixes.begin(), two_disc_game_id_prefixes.end(),
game_id_prefix);
}
std::string GameFile::GetNetPlayName(const Core::TitleDatabase& title_database) const std::string GameFile::GetNetPlayName(const Core::TitleDatabase& title_database) const
{ {
std::vector<std::string> info; std::vector<std::string> info;

View File

@ -81,6 +81,7 @@ public:
u16 GetRevision() const { return m_revision; } u16 GetRevision() const { return m_revision; }
// 0 is the first disc, 1 is the second disc // 0 is the first disc, 1 is the second disc
u8 GetDiscNumber() const { return m_disc_number; } u8 GetDiscNumber() const { return m_disc_number; }
bool IsTwoDiscGame() const { return m_is_two_disc_game; }
std::string GetNetPlayName(const Core::TitleDatabase& title_database) const; std::string GetNetPlayName(const Core::TitleDatabase& title_database) const;
// This function is slow // This function is slow
@ -134,6 +135,7 @@ private:
bool ReadXMLMetadata(const std::string& path); bool ReadXMLMetadata(const std::string& path);
bool ReadPNGBanner(const std::string& path); bool ReadPNGBanner(const std::string& path);
bool TryLoadGameModDescriptorBanner(); bool TryLoadGameModDescriptorBanner();
bool CheckIfTwoDiscGame(const std::string& game_id) const;
// IMPORTANT: Nearly all data members must be save/restored in DoState. // IMPORTANT: Nearly all data members must be save/restored in DoState.
// If anything is changed, make sure DoState handles it properly and // If anything is changed, make sure DoState handles it properly and
@ -168,6 +170,7 @@ private:
std::string m_compression_method{}; std::string m_compression_method{};
u16 m_revision{}; u16 m_revision{};
u8 m_disc_number{}; u8 m_disc_number{};
bool m_is_two_disc_game{};
std::string m_apploader_date; std::string m_apploader_date;
std::string m_custom_name; std::string m_custom_name;

View File

@ -26,7 +26,7 @@
namespace UICommon namespace UICommon
{ {
static constexpr u32 CACHE_REVISION = 24; // Last changed in PR 11557 static constexpr u32 CACHE_REVISION = 25; // Last changed in PR 12702
std::vector<std::string> FindAllGamePaths(const std::vector<std::string>& directories_to_scan, std::vector<std::string> FindAllGamePaths(const std::vector<std::string>& directories_to_scan,
bool recursive_scan) bool recursive_scan)