mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
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.
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user