diff options
| author | JosJuice <josjuice@gmail.com> | 2018-03-10 22:41:49 +0100 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2018-05-20 15:34:03 +0200 |
| commit | cc42b4354d38055629ba3eeac92fa57582a26de0 (patch) | |
| tree | 94bd53000fce61c0dd39c7aad891021ca075c864 /Source/Core/UICommon/GameFile.cpp | |
| parent | 86c676ab0483dc53b3b08cb327816388d278a600 (diff) | |
Reimplement custom PNG banners in game list
Fixes https://bugs.dolphin-emu.org/issues/10938
and makes PNG banners available in DolphinQt2 for the first time.
Diffstat (limited to 'Source/Core/UICommon/GameFile.cpp')
| -rw-r--r-- | Source/Core/UICommon/GameFile.cpp | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/Source/Core/UICommon/GameFile.cpp b/Source/Core/UICommon/GameFile.cpp index cbd7077987..90f87bb016 100644 --- a/Source/Core/UICommon/GameFile.cpp +++ b/Source/Core/UICommon/GameFile.cpp @@ -13,6 +13,7 @@ #include <memory> #include <sstream> #include <string> +#include <tuple> #include <utility> #include <vector> @@ -21,9 +22,11 @@ #include "Common/CommonTypes.h" #include "Common/FileUtil.h" #include "Common/Hash.h" +#include "Common/Image.h" #include "Common/IniFile.h" #include "Common/NandPaths.h" #include "Common/StringUtil.h" +#include "Common/Swap.h" #include "Core/Boot/Boot.h" #include "Core/ConfigManager.h" @@ -39,6 +42,16 @@ namespace UICommon { static const std::string EMPTY_STRING; +bool operator==(const GameBanner& lhs, const GameBanner& rhs) +{ + return std::tie(lhs.buffer, lhs.width, lhs.height) == std::tie(rhs.buffer, rhs.width, rhs.height); +} + +bool operator!=(const GameBanner& lhs, const GameBanner& rhs) +{ + return !operator==(lhs, rhs); +} + const std::string& GameFile::Lookup(DiscIO::Language language, const std::map<DiscIO::Language, std::string>& strings) { @@ -177,6 +190,7 @@ void GameFile::DoState(PointerWrap& p) p.Do(m_apploader_date); m_volume_banner.DoState(p); + m_custom_banner.DoState(p); p.Do(m_custom_name); } @@ -190,7 +204,7 @@ bool GameFile::IsElfOrDol() const return name_end == ".elf" || name_end == ".dol"; } -bool GameFile::BannerChanged() +bool GameFile::WiiBannerChanged() { // Wii banners can only be read if there is a save file. // In case the cache was created without a save file existing, @@ -210,11 +224,62 @@ bool GameFile::BannerChanged() return !m_pending.volume_banner.buffer.empty(); } -void GameFile::BannerCommit() +void GameFile::WiiBannerCommit() { m_volume_banner = std::move(m_pending.volume_banner); } +bool GameFile::ReadPNGBanner(const std::string& path) +{ + File::IOFile file(path, "rb"); + if (!file) + return false; + + std::vector<u8> png_data(file.GetSize()); + if (!file.ReadBytes(png_data.data(), png_data.size())) + return false; + + GameBanner& banner = m_pending.custom_banner; + std::vector<u8> data_out; + if (!Common::LoadPNG(png_data, &data_out, &banner.width, &banner.height)) + return false; + + // Make an ARGB copy of the RGBA data + banner.buffer.resize(data_out.size() / sizeof(u32)); + for (size_t i = 0; i < banner.buffer.size(); i++) + { + const size_t j = i * sizeof(u32); + banner.buffer[i] = (Common::swap32(data_out.data() + j) >> 8) + (data_out[j] << 24); + } + + return true; +} + +bool GameFile::CustomBannerChanged() +{ + std::string path, name; + SplitPath(m_file_path, &path, &name, nullptr); + + // This icon naming format is intended as an alternative to Homebrew Channel icons + // for those who don't want to have a Homebrew Channel style folder structure. + if (!ReadPNGBanner(path + name + ".png")) + { + // Homebrew Channel icon naming. Typical for DOLs and ELFs, but we also support it for volumes. + if (!ReadPNGBanner(path + "icon.png")) + { + // If no custom icon is found, go back to the non-custom one. + m_pending.custom_banner = {}; + } + } + + return m_pending.custom_banner != m_custom_banner; +} + +void GameFile::CustomBannerCommit() +{ + m_custom_banner = std::move(m_pending.custom_banner); +} + const std::string& GameFile::GetName(bool long_name) const { if (!m_custom_name.empty()) @@ -287,4 +352,9 @@ std::string GameFile::GetWiiFSPath() const return Common::GetTitleDataPath(m_title_id, Common::FROM_CONFIGURED_ROOT); } +const GameBanner& GameFile::GetBannerImage() const +{ + return m_custom_banner.empty() ? m_volume_banner : m_custom_banner; +} + } // namespace UICommon |
