Skip to content

Commit

Permalink
Implement Triforce ID parsing via filesystem method
Browse files Browse the repository at this point in the history
  • Loading branch information
Zopolis4 committed Feb 20, 2022
1 parent 44bb7c5 commit c4e2751
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 18 deletions.
10 changes: 10 additions & 0 deletions Data/Sys/tritdb.txt
Original file line number Diff line number Diff line change
@@ -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)
22 changes: 12 additions & 10 deletions Source/Core/Core/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void SConfig::LoadSettings()

void SConfig::ResetRunningGameMetadata()
{
SetRunningGameMetadata("00000000", "", 0, 0, DiscIO::Region::Unknown);
SetRunningGameMetadata("00000000", "", "", 0, 0, DiscIO::Region::Unknown);
}

void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume,
Expand All @@ -104,13 +104,13 @@ void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume,
if (partition == volume.GetGamePartition())
{
SetRunningGameMetadata(volume.GetGameID(), volume.GetGameTDBID(),
volume.GetTitleID().value_or(0), volume.GetRevision().value_or(0),
volume.GetRegion());
volume.GetTriID().value_or(""), volume.GetTitleID().value_or(0),
volume.GetRevision().value_or(0), volume.GetRegion());
}
else
{
SetRunningGameMetadata(volume.GetGameID(partition), volume.GetGameTDBID(),
volume.GetTitleID(partition).value_or(0),
volume.GetTriID().value_or(""), volume.GetTitleID(partition).value_or(0),
volume.GetRevision(partition).value_or(0), volume.GetRegion());
}
}
Expand All @@ -127,23 +127,25 @@ void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Plat
!DVDInterface::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)
{
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 tri_id, u64 title_id, u16 revision,
DiscIO::Region region)
{
const bool was_changed = m_game_id != game_id || m_gametdb_id != gametdb_id ||
m_title_id != title_id || m_revision != revision;
m_tri_id != tri_id || m_title_id != title_id || m_revision != revision;
m_game_id = game_id;
m_gametdb_id = gametdb_id;
m_tri_id = tri_id;
m_title_id = title_id;
m_revision = revision;

Expand Down Expand Up @@ -173,7 +175,7 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::stri

const Core::TitleDatabase title_database;
const DiscIO::Language language = GetLanguageAdjustedForRegion(bWii, region);
m_title_name = title_database.GetTitleName(m_gametdb_id, language);
m_title_name = title_database.GetTitleName(m_gametdb_id, m_tri_id, language);
m_title_description = title_database.Describe(m_gametdb_id, language);
NOTICE_LOG_FMT(CORE, "Active title: {}", m_title_description);
Host_TitleChanged();
Expand Down
5 changes: 4 additions & 1 deletion Source/Core/Core/ConfigManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct SConfig
const std::string& GetGameTDBID() const { return m_gametdb_id; }
const std::string& GetTitleName() const { return m_title_name; }
const std::string& GetTitleDescription() const { return m_title_description; }
std::string GetTriID() const { return m_tri_id; }
u64 GetTitleID() const { return m_title_id; }
u16 GetRevision() const { return m_revision; }
void ResetRunningGameMetadata();
Expand Down Expand Up @@ -112,12 +113,14 @@ struct SConfig
~SConfig();

void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id,
u64 title_id, u16 revision, DiscIO::Region region);
std::string tri_id, u64 title_id, u16 revision,
DiscIO::Region region);

static SConfig* m_Instance;

std::string m_game_id;
std::string m_gametdb_id;
std::string m_tri_id;
std::string m_title_name;
std::string m_title_description;
u64 m_title_id;
Expand Down
22 changes: 20 additions & 2 deletions Source/Core/Core/TitleDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ TitleDatabase::TitleDatabase()
{
// User database
const std::string& load_directory = File::GetUserPath(D_LOAD_IDX);
m_trititle_map = LoadMap(load_directory + "tritdb.txt");
m_user_title_map = LoadMap(load_directory + "wiitdb.txt");
if (m_user_title_map.empty())
m_user_title_map = LoadMap(load_directory + "titles.txt");
Expand Down Expand Up @@ -91,8 +92,12 @@ TitleDatabase::TitleDatabase()
TitleDatabase::~TitleDatabase() = default;

const std::string& TitleDatabase::GetTitleName(const std::string& gametdb_id,
const std::string& tri_id,
DiscIO::Language language) const
{
if (tri_id != "" || NULL)
TitleDatabase::GetTriTitleName(tri_id, language);

auto it = m_user_title_map.find(gametdb_id);
if (it != m_user_title_map.end())
return it->second;
Expand Down Expand Up @@ -120,17 +125,30 @@ const std::string& TitleDatabase::GetTitleName(const std::string& gametdb_id,
return EMPTY_STRING;
}

const std::string& TitleDatabase::GetTriTitleName(const std::string& tri_id,
DiscIO::Language language) const
{
if (!Config::Get(Config::MAIN_USE_BUILT_IN_TITLE_DATABASE))
return EMPTY_STRING;

auto it = m_trititle_map.find(tri_id);
if (it != m_trititle_map.end())
return it->second;

return EMPTY_STRING;
}

const std::string& TitleDatabase::GetChannelName(u64 title_id, DiscIO::Language language) const
{
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);
Expand Down
5 changes: 4 additions & 1 deletion Source/Core/Core/TitleDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class TitleDatabase final

// 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& tri_id,
DiscIO::Language language) const;
const std::string& GetTriTitleName(const std::string& tri_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;
Expand All @@ -38,6 +40,7 @@ class TitleDatabase final

std::unordered_map<DiscIO::Language, Common::Lazy<std::unordered_map<std::string, std::string>>>
m_title_maps;
std::unordered_map<std::string, std::string> m_trititle_map;
std::unordered_map<std::string, std::string> m_base_map;
std::unordered_map<std::string, std::string> m_user_title_map;
};
Expand Down
1 change: 1 addition & 0 deletions Source/Core/DiscIO/Volume.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class Volume
}
virtual std::string GetGameID(const Partition& partition = PARTITION_NONE) const = 0;
virtual std::string GetGameTDBID(const Partition& partition = PARTITION_NONE) const = 0;
virtual std::optional<std::string> GetTriID() 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;
Expand Down
20 changes: 17 additions & 3 deletions Source/Core/DiscIO/VolumeGC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "DiscIO/VolumeGC.h"

#include <charconv>
#include <cstddef>
#include <map>
#include <memory>
Expand Down Expand Up @@ -49,11 +50,12 @@ 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_tri_id = triforce_header.id;
}
}

Expand Down Expand Up @@ -82,6 +84,18 @@ std::string VolumeGC::GetGameTDBID(const Partition& partition) const
return game_id == "GNHE5d" && IsDatelDisc() ? "" : game_id;
}

std::optional<std::string> VolumeGC::GetTriID() const
{
if (m_is_triforce)
{
return (std::string(m_tri_id.data(), m_tri_id.size()));
}
else
{
return {};
}
}

Region VolumeGC::GetRegion() const
{
return RegionCodeToRegion(m_reader->ReadSwapped<u32>(0x458));
Expand Down
9 changes: 9 additions & 0 deletions Source/Core/DiscIO/VolumeGC.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class VolumeGC : public VolumeDisc
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::optional<std::string> GetTriID() 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;
Expand Down Expand Up @@ -76,6 +77,13 @@ class VolumeGC : public VolumeDisc
// (only one for BNR1 type)
};

struct BootID
{
u32 magic; // "BTID"
u32 padding[11];
std::array<char, 4> id;
};

struct ConvertedGCBanner
{
ConvertedGCBanner();
Expand Down Expand Up @@ -105,6 +113,7 @@ class VolumeGC : public VolumeDisc
std::unique_ptr<BlobReader> m_reader;

bool m_is_triforce;
std::array<char, 4> m_tri_id;
};

} // namespace DiscIO
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Config/InfoWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,13 @@ QGroupBox* InfoWidget::CreateGameDetails()
.arg(m_game.GetRevision()));

QString game_id_string = QString::fromStdString(m_game.GetGameID());
QString tri_id_string = QString::fromStdString(m_game.GetTriID());

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* tri_id = CreateValueDisplay(tri_id_string);

QLineEdit* country = CreateValueDisplay(DiscIO::GetName(m_game.GetCountry(), true));

Expand All @@ -120,6 +122,8 @@ QGroupBox* InfoWidget::CreateGameDetails()
m_game.GetMakerID() + ")");

layout->addRow(tr("Name:"), internal_name);
if (m_game.GetPlatform() == DiscIO::Platform::Triforce)
layout->addRow(tr("Boot (Triforce) ID:"), tri_id);
layout->addRow(tr("Game ID:"), game_id);
layout->addRow(tr("Country:"), country);
layout->addRow(tr("Maker:"), maker);
Expand Down
5 changes: 4 additions & 1 deletion Source/Core/UICommon/GameFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,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_tri_id = volume->GetTriID().value_or("");
m_title_id = volume->GetTitleID().value_or(0);
m_maker_id = volume->GetMakerID();
m_revision = volume->GetRevision().value_or(0);
Expand Down Expand Up @@ -361,6 +362,7 @@ void GameFile::DoState(PointerWrap& p)
p.Do(m_internal_name);
p.Do(m_game_id);
p.Do(m_gametdb_id);
p.Do(m_tri_id);
p.Do(m_title_id);
p.Do(m_maker_id);

Expand Down Expand Up @@ -547,7 +549,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_tri_id, GetConfigLanguage());
return database_name.empty() ? GetName(Variant::LongAndPossiblyCustom) : database_name;
}

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/UICommon/GameFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class GameFile final
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 GetTriID() const { return m_tri_id; }
u64 GetTitleID() const { return m_title_id; }
const std::string& GetMakerID() const { return m_maker_id; }
u16 GetRevision() const { return m_revision; }
Expand Down Expand Up @@ -157,6 +158,7 @@ class GameFile final
std::string m_internal_name;
std::string m_game_id;
std::string m_gametdb_id;
std::string m_tri_id;
u64 m_title_id{};
std::string m_maker_id;

Expand Down

0 comments on commit c4e2751

Please sign in to comment.