dolphin/Source/Core/Core/TitleDatabase.cpp

140 lines
4.2 KiB
C++

// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "Core/TitleDatabase.h"
#include <cstddef>
#include <fstream>
#include <functional>
#include <string>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <fmt/format.h>
#include "Common/FileUtil.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
#include "Core/ConfigManager.h"
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/Enums.h"
namespace Core
{
static const std::string EMPTY_STRING;
using Map = std::unordered_map<std::string, std::string>;
static Map LoadMap(const std::string& file_path)
{
Map map;
std::ifstream txt;
File::OpenFStream(txt, file_path, std::ios::in);
std::string line;
while (std::getline(txt, line))
{
if (line.empty())
continue;
const size_t equals_index = line.find('=');
if (equals_index != std::string::npos)
{
const std::string_view line_view(line);
const std::string_view game_id = StripSpaces(line_view.substr(0, equals_index));
if (game_id.length() >= 4)
map.emplace(game_id, StripSpaces(line_view.substr(equals_index + 1)));
}
}
return map;
}
void TitleDatabase::AddLazyMap(DiscIO::Language language, const std::string& language_code)
{
m_title_maps[language] = [language_code]() -> Map {
return LoadMap(File::GetSysDirectory() + "wiitdb-" + language_code + ".txt");
};
}
TitleDatabase::TitleDatabase()
{
// User database
const std::string& load_directory = File::GetUserPath(D_LOAD_IDX);
m_user_title_map = LoadMap(load_directory + "wiitdb.txt");
if (m_user_title_map.empty())
m_user_title_map = LoadMap(load_directory + "titles.txt");
// Pre-defined databases (one per language)
AddLazyMap(DiscIO::Language::Japanese, "ja");
AddLazyMap(DiscIO::Language::English, "en");
AddLazyMap(DiscIO::Language::German, "de");
AddLazyMap(DiscIO::Language::French, "fr");
AddLazyMap(DiscIO::Language::Spanish, "es");
AddLazyMap(DiscIO::Language::Italian, "it");
AddLazyMap(DiscIO::Language::Dutch, "nl");
AddLazyMap(DiscIO::Language::SimplifiedChinese, "zh_CN");
AddLazyMap(DiscIO::Language::TraditionalChinese, "zh_TW");
AddLazyMap(DiscIO::Language::Korean, "ko");
m_title_maps[DiscIO::Language::Unknown] = [] { return Map(); };
// Titles that aren't part of the Wii TDB, but common enough to justify having entries for them.
// i18n: "Wii Menu" (or System Menu) refers to the Wii's main menu,
// which is (usually) the first thing users see when a Wii console starts.
m_base_map.emplace("0000000100000002", Common::GetStringT("Wii Menu"));
for (const auto& id : {"HAXX", "00010001af1bf516"})
m_base_map.emplace(id, "The Homebrew Channel");
}
TitleDatabase::~TitleDatabase() = default;
const std::string& TitleDatabase::GetTitleName(const std::string& gametdb_id,
DiscIO::Language language) const
{
auto it = m_user_title_map.find(gametdb_id);
if (it != m_user_title_map.end())
return it->second;
if (!SConfig::GetInstance().m_use_builtin_title_database)
return EMPTY_STRING;
const Map& map = *m_title_maps.at(language);
it = map.find(gametdb_id);
if (it != map.end())
return it->second;
if (language != DiscIO::Language::English)
{
const Map& english_map = *m_title_maps.at(DiscIO::Language::English);
it = english_map.find(gametdb_id);
if (it != english_map.end())
return it->second;
}
it = m_base_map.find(gametdb_id);
if (it != m_base_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);
}
std::string TitleDatabase::Describe(const std::string& gametdb_id, DiscIO::Language language) const
{
const std::string& title_name = GetTitleName(gametdb_id, language);
if (title_name.empty())
return gametdb_id;
return fmt::format("{} ({})", title_name, gametdb_id);
}
} // namespace Core