DolphinWX: Support banners in Homebrew Channel format

HBC uses files named icon.png for icons. This change makes Dolphin
support that file name, and also [executable file name].png
in case someone wants to have multiple files in one folder.

The HBC banner support is mainly intended for DOL and ELF files,
but it can also be used to override banners of disc images,
something that wasn't possible in the past.

There are currently issues with banner scaling not preserving
the aspect ratio and looking bad in general.
This commit is contained in:
JosJuice 2015-09-04 19:08:30 +02:00
parent ad978122d9
commit 41315b19f1
2 changed files with 55 additions and 19 deletions

View File

@ -85,7 +85,7 @@ GameListItem::GameListItem(const std::string& _rFileName)
std::unique_ptr<DiscIO::IVolume> volume(DiscIO::CreateVolumeFromFilename(_rFileName));
if (volume != nullptr)
{
ReadBanner(*volume);
ReadVolumeBanner(*volume);
if (!m_pImage.empty())
SaveToCache();
}
@ -112,7 +112,7 @@ GameListItem::GameListItem(const std::string& _rFileName)
m_disc_number = pVolume->GetDiscNumber();
m_Revision = pVolume->GetRevision();
ReadBanner(*pVolume);
ReadVolumeBanner(*pVolume);
delete pVolume;
@ -138,24 +138,28 @@ GameListItem::GameListItem(const std::string& _rFileName)
m_Platform = DiscIO::IVolume::ELF_DOL;
}
std::string path, name;
SplitPath(m_FileName, &path, &name, nullptr);
// A bit like the Homebrew Channel icon, except there can be multiple files in a folder with their own icons.
// Useful for those who don't want to have a Homebrew Channel-style folder structure.
if (ReadPNGBanner(path + name + ".png"))
return;
// Homebrew Channel icon. Typical for DOLs and ELFs, but can be also used with volumes.
if (ReadPNGBanner(path + "icon.png"))
return;
// Volume banner. Typical for everything that isn't a DOL or ELF.
if (!m_pImage.empty())
{
wxImage Image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
double Scale = wxTheApp->GetTopWindow()->GetContentScaleFactor();
// Note: This uses nearest neighbor, which subjectively looks a lot
// better for GC banners than smooth scaling.
Image.Rescale(DVD_BANNER_WIDTH * Scale, DVD_BANNER_HEIGHT * Scale);
#ifdef __APPLE__
m_Bitmap = wxBitmap(Image, -1, Scale);
#else
m_Bitmap = wxBitmap(Image, -1);
#endif
}
else
{
// default banner
m_Bitmap.LoadFile(StrToWxStr(File::GetThemeDir(SConfig::GetInstance().theme_name)) + "nobanner.png", wxBITMAP_TYPE_PNG);
wxImage image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
m_Bitmap = ScaleBanner(&image);
return;
}
// Fallback in case no banner is available.
ReadPNGBanner(File::GetThemeDir(SConfig::GetInstance().theme_name) + "nobanner.png");
}
GameListItem::~GameListItem()
@ -211,7 +215,8 @@ std::string GameListItem::CreateCacheFilename()
return fullname;
}
void GameListItem::ReadBanner(const DiscIO::IVolume& volume)
// Outputs to m_pImage
void GameListItem::ReadVolumeBanner(const DiscIO::IVolume& volume)
{
std::vector<u32> Buffer = volume.GetBanner(&m_ImageWidth, &m_ImageHeight);
u32* pData = Buffer.data();
@ -225,6 +230,32 @@ void GameListItem::ReadBanner(const DiscIO::IVolume& volume)
}
}
// Outputs to m_Bitmap
bool GameListItem::ReadPNGBanner(const std::string& path)
{
if (!File::Exists(path))
return false;
wxImage image;
image.LoadFile(StrToWxStr(path), wxBITMAP_TYPE_PNG);
m_Bitmap = ScaleBanner(&image);
return true;
}
wxBitmap GameListItem::ScaleBanner(wxImage* image)
{
double scale = wxTheApp->GetTopWindow()->GetContentScaleFactor();
// Note: This uses nearest neighbor, which subjectively looks a lot
// better for GC banners than smooth scaling.
// TODO: Make scaling less bad for Homebrew Channel banners.
image->Rescale(DVD_BANNER_WIDTH * scale, DVD_BANNER_HEIGHT * scale);
#ifdef __APPLE__
return wxBitmap(*image, -1, scale);
#else
return wxBitmap(*image, -1);
#endif
}
std::string GameListItem::GetDescription(DiscIO::IVolume::ELanguage language) const
{
return GetLanguageString(language, m_descriptions);

View File

@ -84,5 +84,10 @@ private:
std::string CreateCacheFilename();
void ReadBanner(const DiscIO::IVolume& volume);
// Outputs to m_pImage
void ReadVolumeBanner(const DiscIO::IVolume& volume);
// Outputs to m_Bitmap
bool ReadPNGBanner(const std::string& path);
static wxBitmap ScaleBanner(wxImage* image);
};