mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
Merge pull request #2958 from JosJuice/dol-elf-banners
DolphinWX: Support banners in Homebrew Channel format
This commit is contained in:
commit
8a993e1fbc
@ -85,7 +85,7 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||||||
std::unique_ptr<DiscIO::IVolume> volume(DiscIO::CreateVolumeFromFilename(_rFileName));
|
std::unique_ptr<DiscIO::IVolume> volume(DiscIO::CreateVolumeFromFilename(_rFileName));
|
||||||
if (volume != nullptr)
|
if (volume != nullptr)
|
||||||
{
|
{
|
||||||
ReadBanner(*volume);
|
ReadVolumeBanner(*volume);
|
||||||
if (!m_pImage.empty())
|
if (!m_pImage.empty())
|
||||||
SaveToCache();
|
SaveToCache();
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||||||
m_disc_number = pVolume->GetDiscNumber();
|
m_disc_number = pVolume->GetDiscNumber();
|
||||||
m_Revision = pVolume->GetRevision();
|
m_Revision = pVolume->GetRevision();
|
||||||
|
|
||||||
ReadBanner(*pVolume);
|
ReadVolumeBanner(*pVolume);
|
||||||
|
|
||||||
delete pVolume;
|
delete pVolume;
|
||||||
|
|
||||||
@ -138,24 +138,28 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||||||
m_Platform = DiscIO::IVolume::ELF_DOL;
|
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())
|
if (!m_pImage.empty())
|
||||||
{
|
{
|
||||||
wxImage Image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
|
wxImage image(m_ImageWidth, m_ImageHeight, &m_pImage[0], true);
|
||||||
double Scale = wxTheApp->GetTopWindow()->GetContentScaleFactor();
|
m_Bitmap = ScaleBanner(&image);
|
||||||
// Note: This uses nearest neighbor, which subjectively looks a lot
|
return;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback in case no banner is available.
|
||||||
|
ReadPNGBanner(File::GetThemeDir(SConfig::GetInstance().theme_name) + "nobanner.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
GameListItem::~GameListItem()
|
GameListItem::~GameListItem()
|
||||||
@ -211,7 +215,8 @@ std::string GameListItem::CreateCacheFilename()
|
|||||||
return fullname;
|
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);
|
std::vector<u32> Buffer = volume.GetBanner(&m_ImageWidth, &m_ImageHeight);
|
||||||
u32* pData = Buffer.data();
|
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
|
std::string GameListItem::GetDescription(DiscIO::IVolume::ELanguage language) const
|
||||||
{
|
{
|
||||||
return GetLanguageString(language, m_descriptions);
|
return GetLanguageString(language, m_descriptions);
|
||||||
|
@ -84,5 +84,10 @@ private:
|
|||||||
|
|
||||||
std::string CreateCacheFilename();
|
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…
x
Reference in New Issue
Block a user