Implement Triforce ID parsing

This commit is contained in:
Zopolis4 2021-12-17 18:56:48 +11:00
parent 71f654cdc4
commit 8d94d25203
No known key found for this signature in database
GPG Key ID: C1117D56FBC82774
11 changed files with 99 additions and 17 deletions

View File

@ -0,0 +1,10 @@
TITLES = (type: Triforce language: EN version: 20210908)
S000 = Triforce Firmware Update For Compact Flash Box (4.01)
SBEY = Virtua Striker 2002
SBFX = The Key Of Avalon
SBGG = F-Zero AX
SBHZ = Virtua Striker 4 (Asia)
SBJA = Virtua Striker 4 (Export)
SBJN = The Key Of Avalon 2.5: War of the Key
SBLK = Virtua Striker 4 Ver.2006 (Japan)
SBLL = Virtua Striker 4 Ver.2006 (Export)

View File

@ -126,6 +126,12 @@ const std::string SConfig::GetTitleDescription() const
return m_title_description;
}
std::string SConfig::GetTriforceID() const
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
return m_triforce_id;
}
u64 SConfig::GetTitleID() const
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
@ -141,7 +147,7 @@ u16 SConfig::GetRevision() const
void SConfig::ResetRunningGameMetadata()
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
SetRunningGameMetadata("00000000", "", 0, 0, DiscIO::Region::Unknown);
SetRunningGameMetadata("00000000", "", "", 0, 0, DiscIO::Region::Unknown);
}
void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume,
@ -150,14 +156,14 @@ void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume,
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
if (partition == volume.GetGamePartition())
{
SetRunningGameMetadata(volume.GetGameID(), volume.GetGameTDBID(),
SetRunningGameMetadata(volume.GetGameID(), volume.GetGameTDBID(), volume.GetTriforceID(),
volume.GetTitleID().value_or(0), volume.GetRevision().value_or(0),
volume.GetRegion());
}
else
{
SetRunningGameMetadata(volume.GetGameID(partition), volume.GetGameTDBID(partition),
volume.GetTitleID(partition).value_or(0),
volume.GetTriforceID(), volume.GetTitleID(partition).value_or(0),
volume.GetRevision(partition).value_or(0), volume.GetRegion());
}
}
@ -175,25 +181,28 @@ void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Plat
!Core::System::GetInstance().GetDVDInterface().UpdateRunningGameMetadata(tmd_title_id))
{
// If not launching a disc game, just read everything from the TMD.
SetRunningGameMetadata(tmd.GetGameID(), tmd.GetGameTDBID(), tmd_title_id, tmd.GetTitleVersion(),
tmd.GetRegion());
SetRunningGameMetadata(tmd.GetGameID(), tmd.GetGameTDBID(), "", tmd_title_id,
tmd.GetTitleVersion(), tmd.GetRegion());
}
}
void SConfig::SetRunningGameMetadata(const std::string& game_id)
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
SetRunningGameMetadata(game_id, "", 0, 0, DiscIO::Region::Unknown);
SetRunningGameMetadata(game_id, "", "", 0, 0, DiscIO::Region::Unknown);
}
void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
u64 title_id, u16 revision, DiscIO::Region region)
std::string triforce_id, u64 title_id, u16 revision,
DiscIO::Region region)
{
std::lock_guard<std::recursive_mutex> lock(m_metadata_lock);
const bool was_changed = m_game_id != game_id || m_gametdb_id != gametdb_id ||
m_title_id != title_id || m_revision != revision;
m_triforce_id != triforce_id || m_title_id != title_id ||
m_revision != revision;
m_game_id = game_id;
m_gametdb_id = gametdb_id;
m_triforce_id = triforce_id;
m_title_id = title_id;
m_revision = revision;
@ -226,7 +235,7 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::stri
const Core::TitleDatabase title_database;
auto& system = Core::System::GetInstance();
const DiscIO::Language language = GetLanguageAdjustedForRegion(system.IsWii(), region);
m_title_name = title_database.GetTitleName(m_gametdb_id, language);
m_title_name = title_database.GetTitleName(m_gametdb_id, m_triforce_id, language);
m_title_description = title_database.Describe(m_gametdb_id, language);
NOTICE_LOG_FMT(CORE, "Active title: {}", m_title_description);
Host_TitleChanged();

View File

@ -67,6 +67,7 @@ struct SConfig
const std::string GetGameTDBID() const;
const std::string GetTitleName() const;
const std::string GetTitleDescription() const;
std::string GetTriforceID() const;
u64 GetTitleID() const;
u16 GetRevision() const;
void ResetRunningGameMetadata();
@ -121,13 +122,15 @@ private:
static void ReloadTextures(Core::System& system);
void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
u64 title_id, u16 revision, DiscIO::Region region);
std::string triforce_id, u64 title_id, u16 revision,
DiscIO::Region region);
static SConfig* m_Instance;
mutable std::recursive_mutex m_metadata_lock;
std::string m_game_id;
std::string m_gametdb_id;
std::string m_triforce_id;
std::string m_title_name;
std::string m_title_description;
u64 m_title_id;

View File

@ -56,6 +56,9 @@ void TitleDatabase::AddLazyMap(DiscIO::Language language, const std::string& lan
m_title_maps[language] = [language_code]() -> Map {
return LoadMap(File::GetSysDirectory() + "wiitdb-" + language_code + ".txt");
};
m_triforce_title_maps[language] = [language_code]() -> Map {
return LoadMap(File::GetSysDirectory() + "triforcetdb-" + language_code + ".txt");
};
}
TitleDatabase::TitleDatabase()
@ -91,8 +94,32 @@ TitleDatabase::TitleDatabase()
TitleDatabase::~TitleDatabase() = default;
const std::string& TitleDatabase::GetTitleName(const std::string& gametdb_id,
const std::string& triforce_id,
DiscIO::Language language) const
{
if (triforce_id != "")
{
const Map& map = *m_triforce_title_maps.at(DiscIO::Language::English);
auto it = map.find(triforce_id);
if (it != map.end())
return it->second;
// This code has been commented out as there is currently only a english title map, and all
// Triforce games are detected as Japanese.
// if (language != DiscIO::Language::English)
//{
// const Map& english_triforce_map = *m_triforce_title_maps.at(DiscIO::Language::English);
// it = english_triforce_map.find(triforce_id);
// if (it != english_triforce_map.end())
// return it->second;
//}
// it = m_base_map.find(triforce_id);
// if (it != m_base_map.end())
// return it->second;
}
auto it = m_user_title_map.find(gametdb_id);
if (it != m_user_title_map.end())
return it->second;
@ -125,12 +152,12 @@ const std::string& TitleDatabase::GetChannelName(u64 title_id, DiscIO::Language
const std::string id{
{static_cast<char>((title_id >> 24) & 0xff), static_cast<char>((title_id >> 16) & 0xff),
static_cast<char>((title_id >> 8) & 0xff), static_cast<char>(title_id & 0xff)}};
return GetTitleName(id, language);
return GetTitleName(id, "", language);
}
std::string TitleDatabase::Describe(const std::string& gametdb_id, DiscIO::Language language) const
{
const std::string& title_name = GetTitleName(gametdb_id, language);
const std::string& title_name = GetTitleName(gametdb_id, "", language);
if (title_name.empty())
return gametdb_id;
return fmt::format("{} ({})", title_name, gametdb_id);

View File

@ -25,7 +25,8 @@ public:
// Get a user friendly title name for a GameTDB ID.
// This falls back to returning an empty string if none could be found.
const std::string& GetTitleName(const std::string& gametdb_id, DiscIO::Language language) const;
const std::string& GetTitleName(const std::string& gametdb_id, const std::string& triforce_id,
DiscIO::Language language) const;
// Same as above, but takes a title ID instead of a GameTDB ID, and only works for channels.
const std::string& GetChannelName(u64 title_id, DiscIO::Language language) const;
@ -38,6 +39,8 @@ private:
std::unordered_map<DiscIO::Language, Common::Lazy<std::unordered_map<std::string, std::string>>>
m_title_maps;
std::unordered_map<DiscIO::Language, Common::Lazy<std::unordered_map<std::string, std::string>>>
m_triforce_title_maps;
std::unordered_map<std::string, std::string> m_base_map;
std::unordered_map<std::string, std::string> m_user_title_map;
};

View File

@ -96,6 +96,7 @@ public:
}
virtual std::string GetGameID(const Partition& partition = PARTITION_NONE) const = 0;
virtual std::string GetGameTDBID(const Partition& partition = PARTITION_NONE) const = 0;
virtual std::string GetTriforceID() const { return ""; }
virtual std::string GetMakerID(const Partition& partition = PARTITION_NONE) const = 0;
virtual std::optional<u16> GetRevision(const Partition& partition = PARTITION_NONE) const = 0;
virtual std::string GetInternalName(const Partition& partition = PARTITION_NONE) const = 0;

View File

@ -48,11 +48,14 @@ VolumeGC::VolumeGC(std::unique_ptr<BlobReader> reader)
std::unique_ptr<FileInfo> file_info = tmp_fs->FindFileInfo("boot.id");
if (!file_info)
return;
u32 triforce_magic; // "BTID"
BootID triforce_header;
const u64 file_size = ReadFile(*this, PARTITION_NONE, file_info.get(),
reinterpret_cast<u8*>(&triforce_magic), sizeof(triforce_magic));
if (file_size >= 4 && triforce_magic == BTID_MAGIC)
reinterpret_cast<u8*>(&triforce_header), sizeof(BootID));
if (file_size >= 4 && triforce_header.magic == BTID_MAGIC)
{
m_is_triforce = true;
m_triforce_id = triforce_header.id;
}
}
}
@ -90,6 +93,14 @@ std::string VolumeGC::GetGameTDBID(const Partition& partition) const
return GetGameID(partition);
}
std::string VolumeGC::GetTriforceID() const
{
if (m_is_triforce)
return (std::string(m_triforce_id.data(), m_triforce_id.size()));
else
return "";
}
Region VolumeGC::GetRegion() const
{
return RegionCodeToRegion(m_reader->ReadSwapped<u32>(0x458));

View File

@ -34,6 +34,7 @@ public:
const Partition& partition = PARTITION_NONE) const override;
const FileSystem* GetFileSystem(const Partition& partition = PARTITION_NONE) const override;
std::string GetGameTDBID(const Partition& partition = PARTITION_NONE) const override;
std::string GetTriforceID() const override;
std::map<Language, std::string> GetShortNames() const override;
std::map<Language, std::string> GetLongNames() const override;
std::map<Language, std::string> GetShortMakers() const override;
@ -76,6 +77,13 @@ private:
// (only one for BNR1 type)
};
struct BootID
{
u32 magic; // "BTID"
u32 padding[11];
std::array<char, 4> id;
};
struct ConvertedGCBanner
{
ConvertedGCBanner();
@ -105,6 +113,7 @@ private:
std::unique_ptr<BlobReader> m_reader;
bool m_is_triforce;
std::array<char, 4> m_triforce_id;
};
} // namespace DiscIO

View File

@ -106,11 +106,13 @@ QGroupBox* InfoWidget::CreateGameDetails()
.arg(m_game.GetRevision()));
QString game_id_string = QString::fromStdString(m_game.GetGameID());
QString triforce_id_string = QString::fromStdString(m_game.GetTriforceID());
if (const u64 title_id = m_game.GetTitleID())
game_id_string += QStringLiteral(" (%1)").arg(title_id, 16, 16, QLatin1Char('0'));
QLineEdit* game_id = CreateValueDisplay(game_id_string);
QLineEdit* triforce_id = CreateValueDisplay(triforce_id_string);
QLineEdit* country = CreateValueDisplay(DiscIO::GetName(m_game.GetCountry(), true));
@ -121,6 +123,8 @@ QGroupBox* InfoWidget::CreateGameDetails()
m_game.GetMakerID() + ")");
layout->addRow(tr("Name:"), internal_name);
if (m_game.GetPlatform() == DiscIO::Platform::Triforce)
layout->addRow(tr("Triforce ID:"), triforce_id);
layout->addRow(tr("Game ID:"), game_id);
layout->addRow(tr("Country:"), country);
layout->addRow(tr("Maker:"), maker);

View File

@ -131,6 +131,7 @@ GameFile::GameFile(std::string path) : m_file_path(std::move(path))
m_internal_name = volume->GetInternalName();
m_game_id = volume->GetGameID();
m_gametdb_id = volume->GetGameTDBID();
m_triforce_id = volume->GetTriforceID();
m_title_id = volume->GetTitleID().value_or(0);
m_maker_id = volume->GetMakerID();
m_revision = volume->GetRevision().value_or(0);
@ -311,6 +312,7 @@ void GameFile::DoState(PointerWrap& p)
p.Do(m_internal_name);
p.Do(m_game_id);
p.Do(m_gametdb_id);
p.Do(m_triforce_id);
p.Do(m_title_id);
p.Do(m_maker_id);
@ -499,7 +501,8 @@ const std::string& GameFile::GetName(const Core::TitleDatabase& title_database)
if (IsModDescriptor())
return GetName(Variant::LongAndPossiblyCustom);
const std::string& database_name = title_database.GetTitleName(m_gametdb_id, GetConfigLanguage());
const std::string& database_name =
title_database.GetTitleName(m_gametdb_id, m_triforce_id, GetConfigLanguage());
return database_name.empty() ? GetName(Variant::LongAndPossiblyCustom) : database_name;
}

View File

@ -76,6 +76,7 @@ public:
const std::string& GetInternalName() const { return m_internal_name; }
const std::string& GetGameID() const { return m_game_id; }
const std::string& GetGameTDBID() const { return m_gametdb_id; }
std::string GetTriforceID() const { return m_triforce_id; }
u64 GetTitleID() const { return m_title_id; }
const std::string& GetMakerID() const { return m_maker_id; }
u16 GetRevision() const { return m_revision; }
@ -159,6 +160,7 @@ private:
std::string m_internal_name;
std::string m_game_id;
std::string m_gametdb_id;
std::string m_triforce_id;
u64 m_title_id{};
std::string m_maker_id;