Qt: add custom game icons

This shouldn't interfere with emulation as replacing actual files would
This commit is contained in:
Megamouse 2020-10-07 14:20:35 +02:00
parent 552d8e6aec
commit fe3c7926f7
4 changed files with 70 additions and 42 deletions

View File

@ -451,9 +451,17 @@ const bool Emulator::SetUsr(const std::string& user)
const std::string Emulator::GetBackgroundPicturePath() const
{
std::string path = m_sfo_dir + "/PIC1.PNG";
// Try to find a custom icon first
std::string path = fs::get_config_dir() + "/Icons/game_icons/" + Emu.GetTitleID() + "/PIC1.PNG";
if (!fs::exists(path))
if (fs::is_file(path))
{
return path;
}
path = m_sfo_dir + "/PIC1.PNG";
if (!fs::is_file(path))
{
const std::string disc_dir = vfs::get("/dev_bdvd/PS3_GAME");
@ -467,12 +475,12 @@ const std::string Emulator::GetBackgroundPicturePath() const
// Fallback to PIC1.PNG in disc dir
path = disc_dir + "/PIC1.PNG";
if (!fs::exists(path))
if (!fs::is_file(path))
{
// Fallback to ICON0.PNG in update dir
path = m_sfo_dir + "/ICON0.PNG";
if (!fs::exists(path))
if (!fs::is_file(path))
{
// Fallback to ICON0.PNG in disc dir
path = disc_dir + "/ICON0.PNG";

View File

@ -555,7 +555,6 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
GameInfo game;
game.path = dir;
game.icon_path = sfo_dir + "/ICON0.PNG";
game.serial = std::string(psf::get_string(psf, "TITLE_ID", ""));
game.name = std::string(psf::get_string(psf, "TITLE", cat_unknown_localized));
game.app_ver = std::string(psf::get_string(psf, "APP_VER", cat_unknown_localized));
@ -567,6 +566,12 @@ void game_list_frame::Refresh(const bool from_drive, const bool scroll_after)
game.sound_format = psf::get_integer(psf, "SOUND_FORMAT", 0);
game.bootable = psf::get_integer(psf, "BOOTABLE", 0);
game.attr = psf::get_integer(psf, "ATTRIBUTE", 0);
game.icon_path = fs::get_config_dir() + "/Icons/game_icons/" + game.serial + "/ICON0.PNG";
if (!fs::is_file(game.icon_path))
{
game.icon_path = sfo_dir + "/ICON0.PNG";
}
mutex_cat.lock();
@ -1900,7 +1905,7 @@ void game_list_frame::PopulateGameList()
{
int selected_row = -1;
std::string selected_item = CurrentSelectionIconPath();
std::string selected_item = CurrentSelectionPath();
m_game_list->clearSelection();
m_game_list->clearContents();
@ -2011,7 +2016,7 @@ void game_list_frame::PopulateGameList()
m_game_list->setItem(row, gui::column_playtime, new custom_table_widget_item(localized.GetVerboseTimeByMs(elapsed_ms), Qt::UserRole, elapsed_ms));
m_game_list->setItem(row, gui::column_compat, compat_item);
if (selected_item == game->info.icon_path)
if (selected_item == game->info.path + game->info.icon_path)
{
selected_row = row;
}
@ -2028,7 +2033,7 @@ void game_list_frame::PopulateGameGrid(int maxCols, const QSize& image_size, con
int r = 0;
int c = 0;
const std::string selected_item = CurrentSelectionIconPath();
const std::string selected_item = CurrentSelectionPath();
m_game_grid->deleteLater();
@ -2087,7 +2092,7 @@ void game_list_frame::PopulateGameGrid(int maxCols, const QSize& image_size, con
m_game_grid->item(r, c)->setToolTip(tr("%0 [%1]").arg(title).arg(serial));
}
if (selected_item == app->info.icon_path)
if (selected_item == app->info.path + app->info.icon_path)
{
m_game_grid->setCurrentCell(r, c);
}
@ -2128,7 +2133,7 @@ bool game_list_frame::SearchMatchesApp(const QString& name, const QString& seria
return true;
}
std::string game_list_frame::CurrentSelectionIconPath()
std::string game_list_frame::CurrentSelectionPath()
{
std::string selection;
@ -2158,7 +2163,7 @@ std::string game_list_frame::CurrentSelectionIconPath()
auto game = var.value<game_info>();
if (game)
{
selection = game->info.icon_path;
selection = game->info.path + game->info.icon_path;
}
}
}

View File

@ -121,7 +121,7 @@ private:
QString GetLastPlayedBySerial(const QString& serial);
std::string GetCacheDirBySerial(const std::string& serial);
std::string GetDataDirBySerial(const std::string& serial);
std::string CurrentSelectionIconPath();
std::string CurrentSelectionPath();
std::string GetStringFromU32(const u32& key, const std::map<u32, QString>& map, bool combined = false);
game_info GetGameInfoByMode(const QTableWidgetItem* item);

View File

@ -244,43 +244,58 @@ namespace gui
// Loads the app icon from path and embeds it centered into an empty square icon
QIcon get_app_icon_from_path(const std::string& path, const std::string& title_id)
{
// get Icon for the gs_frame from path. this handles presumably all possible use cases
const QString qpath = qstr(path);
const std::string path_list[] = { path, sstr(qpath.section("/", 0, -2, QString::SectionIncludeTrailingSep)),
sstr(qpath.section("/", 0, -3, QString::SectionIncludeTrailingSep)) };
// Try to find custom icon first
std::string icon_path = fs::get_config_dir() + "/Icons/game_icons/" + title_id + "/ICON0.PNG";
bool found_file = fs::is_file(icon_path);
for (const std::string& pth : path_list)
if (!found_file)
{
if (!fs::is_dir(pth))
// Get Icon for the gs_frame from path. this handles presumably all possible use cases
const QString qpath = qstr(path);
const std::string path_list[] = { path, sstr(qpath.section("/", 0, -2, QString::SectionIncludeTrailingSep)),
sstr(qpath.section("/", 0, -3, QString::SectionIncludeTrailingSep)) };
for (const std::string& pth : path_list)
{
continue;
}
if (!fs::is_dir(pth))
{
continue;
}
const std::string sfo_dir = Emulator::GetSfoDirFromGamePath(pth, Emu.GetUsr(), title_id);
const std::string ico = sfo_dir + "/ICON0.PNG";
if (fs::is_file(ico))
{
// load the image from path. It will most likely be a rectangle
QImage source = QImage(qstr(ico));
const int edge_max = std::max(source.width(), source.height());
const std::string sfo_dir = Emulator::GetSfoDirFromGamePath(pth, Emu.GetUsr(), title_id);
icon_path = sfo_dir + "/ICON0.PNG";
found_file = fs::is_file(icon_path);
// create a new transparent image with square size and same format as source (maybe handle other formats than RGB32 as well?)
QImage::Format format = source.format() == QImage::Format_RGB32 ? QImage::Format_ARGB32 : source.format();
QImage dest = QImage(edge_max, edge_max, format);
dest.fill(Qt::transparent);
// get the location to draw the source image centered within the dest image.
const QPoint dest_pos = source.width() > source.height() ? QPoint(0, (source.width() - source.height()) / 2) : QPoint((source.height() - source.width()) / 2, 0);
// Paint the source into/over the dest
QPainter painter(&dest);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.drawImage(dest_pos, source);
painter.end();
return QIcon(QPixmap::fromImage(dest));
if (found_file)
{
break;
}
}
}
if (found_file)
{
// load the image from path. It will most likely be a rectangle
QImage source = QImage(qstr(icon_path));
const int edge_max = std::max(source.width(), source.height());
// create a new transparent image with square size and same format as source (maybe handle other formats than RGB32 as well?)
QImage::Format format = source.format() == QImage::Format_RGB32 ? QImage::Format_ARGB32 : source.format();
QImage dest = QImage(edge_max, edge_max, format);
dest.fill(Qt::transparent);
// get the location to draw the source image centered within the dest image.
const QPoint dest_pos = source.width() > source.height() ? QPoint(0, (source.width() - source.height()) / 2) : QPoint((source.height() - source.width()) / 2, 0);
// Paint the source into/over the dest
QPainter painter(&dest);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.drawImage(dest_pos, source);
painter.end();
return QIcon(QPixmap::fromImage(dest));
}
// if nothing was found reset the icon to default
return QApplication::windowIcon();
}