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:
parent
ad978122d9
commit
41315b19f1
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue