Merge pull request #2958 from JosJuice/dol-elf-banners

DolphinWX: Support banners in Homebrew Channel format
This commit is contained in:
Pierre Bourdon 2015-09-05 23:08:07 +02:00
commit 8a993e1fbc
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);
};