From 8793f7c325f7164f0cfe3095f697ef9bf5473344 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 13 Jun 2015 16:37:37 +0200 Subject: [PATCH 1/2] DolphinQt: Store GameFile banner as empty if missing --- Source/Core/DolphinQt/GameList/GameFile.cpp | 15 +++------------ Source/Core/DolphinQt/GameList/GameFile.h | 10 +++++++++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Source/Core/DolphinQt/GameList/GameFile.cpp b/Source/Core/DolphinQt/GameList/GameFile.cpp index a89b5ce9ad..df363410f3 100644 --- a/Source/Core/DolphinQt/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt/GameList/GameFile.cpp @@ -22,7 +22,6 @@ #include "DiscIO/Filesystem.h" #include "DolphinQt/GameList/GameFile.h" -#include "DolphinQt/Utils/Resources.h" #include "DolphinQt/Utils/Utils.h" static const u32 CACHE_REVISION = 0x00A; @@ -72,12 +71,9 @@ static QString GetLanguageString(DiscIO::IVolume::ELanguage language, QMap> 0)); } + m_valid = true; + if (!banner.isNull()) { - hasBanner = true; m_banner = QPixmap::fromImage(banner); - } - - m_valid = true; - if (hasBanner) SaveToCache(); + } } } @@ -138,9 +132,6 @@ GameFile::GameFile(const QString& fileName) ini.GetIfExists("EmuState", "EmulationIssues", &issues_temp); m_issues = QString::fromStdString(issues_temp); } - - if (!hasBanner) - m_banner = Resources::GetPixmap(Resources::BANNER_MISSING); } bool GameFile::LoadFromCache() diff --git a/Source/Core/DolphinQt/GameList/GameFile.h b/Source/Core/DolphinQt/GameList/GameFile.h index 00e79c7720..4c603e2236 100644 --- a/Source/Core/DolphinQt/GameList/GameFile.h +++ b/Source/Core/DolphinQt/GameList/GameFile.h @@ -13,6 +13,8 @@ #include "DiscIO/Volume.h" #include "DiscIO/VolumeCreator.h" +#include "DolphinQt/Utils/Resources.h" + class GameFile final { public: @@ -39,7 +41,13 @@ public: u64 GetVolumeSize() const { return m_volume_size; } // 0 is the first disc, 1 is the second disc u8 GetDiscNumber() const { return m_disc_number; } - const QPixmap GetBitmap() const { return m_banner; } + const QPixmap GetBitmap() const + { + if (m_banner.isNull()) + return Resources::GetPixmap(Resources::BANNER_MISSING); + + return m_banner; + } private: QString m_file_name; From a7d374bcb99310d3181a796da04eb919d7e65baa Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 13 Jun 2015 20:06:27 +0200 Subject: [PATCH 2/2] Cache games without banners Games without banners were not cached before, because a banner could become available at any time, making the cache outdated without it becoming invalidated. Instead of not caching anything, this change makes Dolphin check for a banner every time a cache that lacks a banner is read. This is faster than reading all metadata, because reading a Wii banner only reads from the game's save file, not the volume and its filesystem. The cache revision is incremented, because otherwise banners will be missing if a cache without a banner is created in the new version and the user switches to an old version and creates a savefile. --- Source/Core/DolphinQt/GameList/GameFile.cpp | 51 ++++++++++++++------- Source/Core/DolphinQt/GameList/GameFile.h | 2 + Source/Core/DolphinWX/ISOFile.cpp | 47 ++++++++++++------- Source/Core/DolphinWX/ISOFile.h | 2 + 4 files changed, 69 insertions(+), 33 deletions(-) diff --git a/Source/Core/DolphinQt/GameList/GameFile.cpp b/Source/Core/DolphinQt/GameList/GameFile.cpp index df363410f3..03c3ddd037 100644 --- a/Source/Core/DolphinQt/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt/GameList/GameFile.cpp @@ -24,7 +24,7 @@ #include "DolphinQt/GameList/GameFile.h" #include "DolphinQt/Utils/Utils.h" -static const u32 CACHE_REVISION = 0x00A; +static const u32 CACHE_REVISION = 0x00B; // Last changed in PR 2598 static const u32 DATASTREAM_REVISION = 15; // Introduced in Qt 5.2 static QMap ConvertLocalizedStrings(std::map strings) @@ -74,6 +74,20 @@ GameFile::GameFile(const QString& fileName) if (LoadFromCache()) { m_valid = true; + + // Wii banners can only be read if there is a savefile, + // so sometimes caches don't contain banners. Let's check + // if a banner has become available after the cache was made. + if (m_banner.isNull()) + { + std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(fileName.toStdString())); + if (volume != nullptr) + { + ReadBanner(*volume); + if (!m_banner.isNull()) + SaveToCache(); + } + } } else { @@ -100,24 +114,10 @@ GameFile::GameFile(const QString& fileName) QFileInfo info(m_file_name); m_folder_name = info.absoluteDir().dirName(); - 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)); - } + ReadBanner(*volume); m_valid = true; - - if (!banner.isNull()) - { - m_banner = QPixmap::fromImage(banner); - SaveToCache(); - } + SaveToCache(); } } @@ -238,6 +238,23 @@ QString GameFile::CreateCacheFilename() return fullname; } +void GameFile::ReadBanner(const DiscIO::IVolume& 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 (!banner.isNull()) + m_banner = QPixmap::fromImage(banner); +} + QString GameFile::GetDescription(DiscIO::IVolume::ELanguage language) const { return GetLanguageString(language, m_descriptions); diff --git a/Source/Core/DolphinQt/GameList/GameFile.h b/Source/Core/DolphinQt/GameList/GameFile.h index 4c603e2236..e62fcd1a79 100644 --- a/Source/Core/DolphinQt/GameList/GameFile.h +++ b/Source/Core/DolphinQt/GameList/GameFile.h @@ -79,4 +79,6 @@ private: void SaveToCache(); QString CreateCacheFilename(); + + void ReadBanner(const DiscIO::IVolume& volume); }; diff --git a/Source/Core/DolphinWX/ISOFile.cpp b/Source/Core/DolphinWX/ISOFile.cpp index a7a4706fad..2ae56e8fb1 100644 --- a/Source/Core/DolphinWX/ISOFile.cpp +++ b/Source/Core/DolphinWX/ISOFile.cpp @@ -34,7 +34,7 @@ #include "DolphinWX/ISOFile.h" #include "DolphinWX/WxUtils.h" -static const u32 CACHE_REVISION = 0x124; +static const u32 CACHE_REVISION = 0x125; // Last changed in PR 2598 #define DVD_BANNER_WIDTH 96 #define DVD_BANNER_HEIGHT 32 @@ -74,6 +74,20 @@ GameListItem::GameListItem(const std::string& _rFileName) if (LoadFromCache()) { m_Valid = true; + + // Wii banners can only be read if there is a savefile, + // so sometimes caches don't contain banners. Let's check + // if a banner has become available after the cache was made. + if (m_pImage.empty()) + { + std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(_rFileName)); + if (volume != nullptr) + { + ReadBanner(*volume); + if (!m_pImage.empty()) + SaveToCache(); + } + } } else { @@ -96,25 +110,12 @@ GameListItem::GameListItem(const std::string& _rFileName) m_disc_number = pVolume->GetDiscNumber(); m_Revision = pVolume->GetRevision(); - std::vector Buffer = pVolume->GetBanner(&m_ImageWidth, &m_ImageHeight); - u32* pData = Buffer.data(); - m_pImage.resize(m_ImageWidth * m_ImageHeight * 3); - - for (int i = 0; i < m_ImageWidth * m_ImageHeight; i++) - { - m_pImage[i * 3 + 0] = (pData[i] & 0xFF0000) >> 16; - m_pImage[i * 3 + 1] = (pData[i] & 0x00FF00) >> 8; - m_pImage[i * 3 + 2] = (pData[i] & 0x0000FF) >> 0; - } + ReadBanner(*pVolume); delete pVolume; m_Valid = true; - - // Create a cache file only if we have an image. - // Wii ISOs create their images after you have generated the first savegame - if (!m_pImage.empty()) - SaveToCache(); + SaveToCache(); } } @@ -201,6 +202,20 @@ std::string GameListItem::CreateCacheFilename() return fullname; } +void GameListItem::ReadBanner(const DiscIO::IVolume& volume) +{ + std::vector Buffer = volume.GetBanner(&m_ImageWidth, &m_ImageHeight); + u32* pData = Buffer.data(); + m_pImage.resize(m_ImageWidth * m_ImageHeight * 3); + + for (int i = 0; i < m_ImageWidth * m_ImageHeight; i++) + { + m_pImage[i * 3 + 0] = (pData[i] & 0xFF0000) >> 16; + m_pImage[i * 3 + 1] = (pData[i] & 0x00FF00) >> 8; + m_pImage[i * 3 + 2] = (pData[i] & 0x0000FF) >> 0; + } +} + std::string GameListItem::GetDescription(DiscIO::IVolume::ELanguage language) const { return GetLanguageString(language, m_descriptions); diff --git a/Source/Core/DolphinWX/ISOFile.h b/Source/Core/DolphinWX/ISOFile.h index f2a843cf67..ce9e6684f6 100644 --- a/Source/Core/DolphinWX/ISOFile.h +++ b/Source/Core/DolphinWX/ISOFile.h @@ -81,4 +81,6 @@ private: void SaveToCache(); std::string CreateCacheFilename(); + + void ReadBanner(const DiscIO::IVolume& volume); };