From 235ecfbed71986f0be2ecf469a10e1105dcb3c96 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 9 Apr 2015 17:44:53 +0200 Subject: Return GetNames languages, to avoid hardcoded language lists in callers This makes the code cleaner and also leads to some user-visible changes: The wx game properties will no longer let the user select WAD languages that don't have any names. The Qt game list will now display names using the languages set in the configuration instead of always using English for PAL GC games and Japanese for WADs. If a WAD doesn't have a name in the user's preferred language, English is now selected as a fallback before Japanese. --- Source/Core/DolphinQt/GameList/GameFile.cpp | 127 ++++++++++++++++------------ 1 file changed, 73 insertions(+), 54 deletions(-) (limited to 'Source/Core/DolphinQt/GameList/GameFile.cpp') diff --git a/Source/Core/DolphinQt/GameList/GameFile.cpp b/Source/Core/DolphinQt/GameList/GameFile.cpp index 67b7d7855f..9b36e86069 100644 --- a/Source/Core/DolphinQt/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt/GameList/GameFile.cpp @@ -26,23 +26,48 @@ #include "DolphinQt/Utils/Resources.h" #include "DolphinQt/Utils/Utils.h" -static const u32 CACHE_REVISION = 0x006; +static const u32 CACHE_REVISION = 0x007; static const u32 DATASTREAM_REVISION = 15; // Introduced in Qt 5.2 -static QStringList VectorToStringList(std::vector vec, bool trim = false) +static QMap ConvertLocalizedStrings(std::map strings) { - QStringList result; - if (trim) - { - for (const std::string& member : vec) - result.append(QString::fromStdString(member).trimmed()); - } - else + QMap result; + + for (auto entry : strings) + result.insert(entry.first, QString::fromStdString(entry.second).trimmed()); + + return result; +} + +template +static QMap CastLocalizedStrings(QMap strings) +{ + QMap result; + + auto end = strings.cend(); + for (auto it = strings.cbegin(); it != end; ++it) + result.insert((to)it.key(), it.value()); + + return result; +} + +static QString GetLanguageString(IVolume::ELanguage language, QMap strings) +{ + if (strings.contains(language)) + return strings.value(language); + + // English tends to be a good fallback when the requested language isn't available + if (language != IVolume::ELanguage::LANGUAGE_ENGLISH) { - for (const std::string& member : vec) - result.append(QString::fromStdString(member)); + if (strings.contains(IVolume::ELanguage::LANGUAGE_ENGLISH)) + return strings.value(IVolume::ELanguage::LANGUAGE_ENGLISH); } - return result; + + // If English isn't available either, just pick something + if (!strings.empty()) + return strings.cbegin().value(); + + return SL(""); } GameFile::GameFile(const QString& fileName) @@ -66,7 +91,7 @@ GameFile::GameFile(const QString& fileName) else m_platform = WII_WAD; - m_volume_names = VectorToStringList(volume->GetNames()); + m_volume_names = ConvertLocalizedStrings(volume->GetNames()); m_country = volume->GetCountry(); m_file_size = volume->GetRawSize(); @@ -92,9 +117,9 @@ GameFile::GameFile(const QString& fileName) if (bannerLoader->IsValid()) { if (m_platform != WII_WAD) - m_names = VectorToStringList(bannerLoader->GetNames()); + m_names = ConvertLocalizedStrings(bannerLoader->GetNames()); m_company = QString::fromStdString(bannerLoader->GetCompany()); - m_descriptions = VectorToStringList(bannerLoader->GetDescriptions(), true); + m_descriptions = ConvertLocalizedStrings(bannerLoader->GetDescriptions()); int width, height; std::vector buffer = bannerLoader->GetBanner(&width, &height); @@ -158,11 +183,15 @@ bool GameFile::LoadFromCache() if (cache_rev != CACHE_REVISION) return false; - int country; + u32 country; + QMap volume_names; + QMap names; + QMap descriptions; stream >> m_folder_name - >> m_volume_names + >> volume_names + >> names >> m_company - >> m_descriptions + >> descriptions >> m_unique_id >> m_file_size >> m_volume_size @@ -173,6 +202,9 @@ bool GameFile::LoadFromCache() >> m_is_disc_two >> m_revision; m_country = (DiscIO::IVolume::ECountry)country; + m_volume_names = CastLocalizedStrings(volume_names); + m_names = CastLocalizedStrings(names); + m_descriptions = CastLocalizedStrings(descriptions); file.close(); return true; } @@ -198,13 +230,14 @@ void GameFile::SaveToCache() stream << CACHE_REVISION; stream << m_folder_name - << m_volume_names + << CastLocalizedStrings(m_volume_names) + << CastLocalizedStrings(m_names) << m_company - << m_descriptions + << CastLocalizedStrings(m_descriptions) << m_unique_id << m_file_size << m_volume_size - << (int)m_country + << (u32)m_country << m_banner << m_compressed << m_platform @@ -233,55 +266,36 @@ QString GameFile::CreateCacheFilename() QString GameFile::GetCompany() const { - if (m_company.isEmpty()) - return QObject::tr("N/A"); - else - return m_company; + return m_company; } -// For all of the following functions that accept an "index" parameter, -// (-1 = Japanese, 0 = English, etc)? - -QString GameFile::GetDescription(int index) const +QString GameFile::GetDescription(IVolume::ELanguage language) const { - if (index < m_descriptions.size()) - return m_descriptions[index]; - - if (!m_descriptions.empty()) - return m_descriptions[0]; - - return SL(""); + return GetLanguageString(language, m_descriptions); } -QString GameFile::GetVolumeName(int index) const +QString GameFile::GetDescription() const { - if (index < m_volume_names.size() && !m_volume_names[index].isEmpty()) - return m_volume_names[index]; - - if (!m_volume_names.isEmpty()) - return m_volume_names[0]; - - return SL(""); + return GetDescription(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_platform != GAMECUBE_DISC)); } -QString GameFile::GetBannerName(int index) const +QString GameFile::GetVolumeName(IVolume::ELanguage language) const { - if (index < m_names.size() && !m_names[index].isEmpty()) - return m_names[index]; - - if (!m_names.isEmpty()) - return m_names[0]; + return GetLanguageString(language, m_volume_names); +} - return SL(""); +QString GameFile::GetBannerName(IVolume::ELanguage language) const +{ + return GetLanguageString(language, m_names); } -QString GameFile::GetName(int index) const +QString GameFile::GetName(IVolume::ELanguage language) const { // Prefer name from banner, fallback to name from volume, fallback to filename - QString name = GetBannerName(index); + QString name = GetBannerName(language); if (name.isEmpty()) - name = GetVolumeName(index); + name = GetVolumeName(language); if (name.isEmpty()) { @@ -294,6 +308,11 @@ QString GameFile::GetName(int index) const return name; } +QString GameFile::GetName() const +{ + return GetName(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_platform != GAMECUBE_DISC)); +} + const QString GameFile::GetWiiFSPath() const { std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(m_file_name.toStdString())); -- cgit v1.2.3 From ee694e327ada8c42949a3907d6fa222f73f276b0 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 10 Apr 2015 22:10:49 +0200 Subject: Get rid of banner loaders and move their functionality to volumes Having some data available in banner loaders and some other data data available in volumes gets messy, especially with GetNames(), which is available in both but returns different results depending on which one is used. This change drops support for reading names and descriptions from Wii save data. --- Source/Core/DolphinQt/GameList/GameFile.cpp | 84 ++++++++--------------------- 1 file changed, 22 insertions(+), 62 deletions(-) (limited to 'Source/Core/DolphinQt/GameList/GameFile.cpp') diff --git a/Source/Core/DolphinQt/GameList/GameFile.cpp b/Source/Core/DolphinQt/GameList/GameFile.cpp index 9b36e86069..e97117d033 100644 --- a/Source/Core/DolphinQt/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt/GameList/GameFile.cpp @@ -18,7 +18,6 @@ #include "Core/ConfigManager.h" -#include "DiscIO/BannerLoader.h" #include "DiscIO/CompressedBlob.h" #include "DiscIO/Filesystem.h" @@ -82,7 +81,7 @@ GameFile::GameFile(const QString& fileName) } else { - DiscIO::IVolume* volume = DiscIO::CreateVolumeFromFilename(fileName.toStdString()); + std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(fileName.toStdString())); if (volume != nullptr) { @@ -91,7 +90,9 @@ GameFile::GameFile(const QString& fileName) else m_platform = WII_WAD; - m_volume_names = ConvertLocalizedStrings(volume->GetNames()); + m_names = ConvertLocalizedStrings(volume->GetNames()); + m_descriptions = ConvertLocalizedStrings(volume->GetDescriptions()); + m_company = QString::fromStdString(volume->GetCompany()); m_country = volume->GetCountry(); m_file_size = volume->GetRawSize(); @@ -105,43 +106,22 @@ GameFile::GameFile(const QString& fileName) QFileInfo info(m_file_name); m_folder_name = info.absoluteDir().dirName(); - // check if we can get some info from the banner file too - DiscIO::IFileSystem* fileSystem = DiscIO::CreateFileSystem(volume); + int width, height; + std::vector buffer = volume->GetBanner(&width, &height); + QImage banner(width, height, QImage::Format_RGB888); + for (int i = 0; i < width * height; i++) + { + int x = i % width, y = i / width; + banner.setPixel(x, y, qRgb((buffer[i] & 0xFF0000) >> 16, + (buffer[i] & 0x00FF00) >> 8, + (buffer[i] & 0x0000FF) >> 0)); + } - if (fileSystem != nullptr || m_platform == WII_WAD) + if (!banner.isNull()) { - std::unique_ptr bannerLoader(DiscIO::CreateBannerLoader(*fileSystem, volume)); - - if (bannerLoader != nullptr) - { - if (bannerLoader->IsValid()) - { - if (m_platform != WII_WAD) - m_names = ConvertLocalizedStrings(bannerLoader->GetNames()); - m_company = QString::fromStdString(bannerLoader->GetCompany()); - m_descriptions = ConvertLocalizedStrings(bannerLoader->GetDescriptions()); - - int width, height; - std::vector buffer = bannerLoader->GetBanner(&width, &height); - QImage banner(width, height, QImage::Format_RGB888); - for (int i = 0; i < width * height; i++) - { - int x = i % width, y = i / width; - banner.setPixel(x, y, qRgb((buffer[i] & 0xFF0000) >> 16, - (buffer[i] & 0x00FF00) >> 8, - (buffer[i] & 0x0000FF) >> 0)); - } - - if (!banner.isNull()) - { - hasBanner = true; - m_banner = QPixmap::fromImage(banner); - } - } - } - delete fileSystem; + hasBanner = true; + m_banner = QPixmap::fromImage(banner); } - delete volume; m_valid = true; if (hasBanner) @@ -184,14 +164,12 @@ bool GameFile::LoadFromCache() return false; u32 country; - QMap volume_names; QMap names; QMap descriptions; stream >> m_folder_name - >> volume_names >> names - >> m_company >> descriptions + >> m_company >> m_unique_id >> m_file_size >> m_volume_size @@ -202,7 +180,6 @@ bool GameFile::LoadFromCache() >> m_is_disc_two >> m_revision; m_country = (DiscIO::IVolume::ECountry)country; - m_volume_names = CastLocalizedStrings(volume_names); m_names = CastLocalizedStrings(names); m_descriptions = CastLocalizedStrings(descriptions); file.close(); @@ -230,10 +207,9 @@ void GameFile::SaveToCache() stream << CACHE_REVISION; stream << m_folder_name - << CastLocalizedStrings(m_volume_names) << CastLocalizedStrings(m_names) - << m_company << CastLocalizedStrings(m_descriptions) + << m_company << m_unique_id << m_file_size << m_volume_size @@ -279,24 +255,14 @@ QString GameFile::GetDescription() const return GetDescription(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_platform != GAMECUBE_DISC)); } -QString GameFile::GetVolumeName(IVolume::ELanguage language) const -{ - return GetLanguageString(language, m_volume_names); -} - -QString GameFile::GetBannerName(IVolume::ELanguage language) const +QString GameFile::GetName(IVolume::ELanguage language) const { return GetLanguageString(language, m_names); } -QString GameFile::GetName(IVolume::ELanguage language) const +QString GameFile::GetName() const { - // Prefer name from banner, fallback to name from volume, fallback to filename - QString name = GetBannerName(language); - - if (name.isEmpty()) - name = GetVolumeName(language); - + QString name = GetName(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_platform != GAMECUBE_DISC)); if (name.isEmpty()) { // No usable name, return filename (better than nothing) @@ -304,15 +270,9 @@ QString GameFile::GetName(IVolume::ELanguage language) const SplitPath(m_file_name.toStdString(), nullptr, &nametemp, nullptr); name = QString::fromStdString(nametemp); } - return name; } -QString GameFile::GetName() const -{ - return GetName(SConfig::GetInstance().m_LocalCoreStartupParameter.GetCurrentLanguage(m_platform != GAMECUBE_DISC)); -} - const QString GameFile::GetWiiFSPath() const { std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(m_file_name.toStdString())); -- cgit v1.2.3