mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 04:02:42 +01:00
Qt: implement hover pam in game list
This commit is contained in:
parent
aae155e954
commit
4dfda3240c
@ -22,4 +22,13 @@ struct GameInfo
|
||||
u32 resolution = 0;
|
||||
|
||||
u64 size_on_disk = umax;
|
||||
|
||||
std::string get_pam_path() const
|
||||
{
|
||||
if (icon_path.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
return icon_path.substr(0, icon_path.find_last_of("/")) + "/ICON1.PAM";
|
||||
}
|
||||
};
|
||||
|
@ -19,6 +19,7 @@ struct gui_game_info
|
||||
bool hasCustomConfig = false;
|
||||
bool hasCustomPadConfig = false;
|
||||
bool has_hover_gif = false;
|
||||
bool has_hover_pam = false;
|
||||
movie_item_base* item = nullptr;
|
||||
};
|
||||
|
||||
|
@ -614,6 +614,7 @@ void game_list_frame::OnParsingFinished()
|
||||
info.hasCustomConfig = fs::is_file(rpcs3::utils::get_custom_config_path(info.info.serial));
|
||||
info.hasCustomPadConfig = fs::is_file(rpcs3::utils::get_custom_input_config_path(info.info.serial));
|
||||
info.has_hover_gif = fs::is_file(game_icon_path + info.info.serial + "/hover.gif");
|
||||
info.has_hover_pam = fs::is_file(info.info.get_pam_path());
|
||||
|
||||
m_games.push(std::make_shared<gui_game_info>(std::move(info)));
|
||||
};
|
||||
|
@ -75,16 +75,16 @@ void game_list_grid::populate(
|
||||
item->setToolTip(tr("%0 [%1]\n\nNotes:\n%2").arg(title).arg(serial).arg(notes));
|
||||
}
|
||||
|
||||
item->set_icon_func([this, item, game](int)
|
||||
item->set_icon_func([this, item, game](const QVideoFrame& frame)
|
||||
{
|
||||
if (!item || !game)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (std::shared_ptr<QMovie> movie = item->movie(); movie && item->get_active())
|
||||
if (const QPixmap pixmap = item->get_movie_image(frame); item->get_active() && !pixmap.isNull())
|
||||
{
|
||||
item->set_icon(gui::utils::get_centered_pixmap(movie->currentPixmap(), m_icon_size, 0, 0, 1.0, Qt::FastTransformation));
|
||||
item->set_icon(gui::utils::get_centered_pixmap(pixmap, m_icon_size, 0, 0, 1.0, Qt::FastTransformation));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -92,21 +92,22 @@ void game_list_grid::populate(
|
||||
|
||||
item->set_icon(game->pxmap);
|
||||
|
||||
if (!game->has_hover_gif)
|
||||
if (!game->has_hover_gif && !game->has_hover_pam)
|
||||
{
|
||||
game->pxmap = {};
|
||||
}
|
||||
|
||||
if (movie)
|
||||
{
|
||||
movie->stop();
|
||||
}
|
||||
item->stop_movie();
|
||||
}
|
||||
});
|
||||
|
||||
if (play_hover_movies && game->has_hover_gif)
|
||||
{
|
||||
item->init_movie(game_icon_path % serial % "/hover.gif");
|
||||
item->set_movie_path(game_icon_path % serial % "/hover.gif");
|
||||
}
|
||||
else if (play_hover_movies && game->has_hover_pam)
|
||||
{
|
||||
item->set_movie_path(QString::fromStdString(game->info.get_pam_path()));
|
||||
}
|
||||
|
||||
if (selected_item_id == game->info.path + game->info.icon_path)
|
||||
|
@ -235,16 +235,16 @@ void game_list_table::populate(
|
||||
custom_table_widget_item* icon_item = new custom_table_widget_item;
|
||||
game->item = icon_item;
|
||||
|
||||
icon_item->set_icon_func([this, icon_item, game](int)
|
||||
icon_item->set_icon_func([this, icon_item, game](const QVideoFrame& frame)
|
||||
{
|
||||
if (!icon_item || !game)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (std::shared_ptr<QMovie> movie = icon_item->movie(); movie && icon_item->get_active())
|
||||
if (const QPixmap pixmap = icon_item->get_movie_image(frame); icon_item->get_active() && !pixmap.isNull())
|
||||
{
|
||||
icon_item->setData(Qt::DecorationRole, movie->currentPixmap().scaled(m_icon_size, Qt::KeepAspectRatio));
|
||||
icon_item->setData(Qt::DecorationRole, pixmap.scaled(m_icon_size, Qt::KeepAspectRatio));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,15 +252,12 @@ void game_list_table::populate(
|
||||
|
||||
icon_item->setData(Qt::DecorationRole, game->pxmap);
|
||||
|
||||
if (!game->has_hover_gif)
|
||||
if (!game->has_hover_gif && !game->has_hover_pam)
|
||||
{
|
||||
game->pxmap = {};
|
||||
}
|
||||
|
||||
if (movie)
|
||||
{
|
||||
movie->stop();
|
||||
}
|
||||
icon_item->stop_movie();
|
||||
}
|
||||
});
|
||||
|
||||
@ -288,7 +285,11 @@ void game_list_table::populate(
|
||||
|
||||
if (play_hover_movies && game->has_hover_gif)
|
||||
{
|
||||
icon_item->init_movie(game_icon_path % serial % "/hover.gif");
|
||||
icon_item->set_movie_path(game_icon_path % serial % "/hover.gif");
|
||||
}
|
||||
else if (play_hover_movies && game->has_hover_pam)
|
||||
{
|
||||
icon_item->set_movie_path(QString::fromStdString(game->info.get_pam_path()));
|
||||
}
|
||||
|
||||
icon_item->setData(Qt::UserRole, index, true);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "movie_item_base.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
movie_item_base::movie_item_base()
|
||||
{
|
||||
init_pointers();
|
||||
@ -13,6 +15,11 @@ movie_item_base::~movie_item_base()
|
||||
m_movie->stop();
|
||||
}
|
||||
|
||||
if (m_media_player)
|
||||
{
|
||||
m_media_player->stop();
|
||||
}
|
||||
|
||||
wait_for_icon_loading(true);
|
||||
wait_for_size_on_disk_loading(true);
|
||||
}
|
||||
@ -25,33 +32,136 @@ void movie_item_base::init_pointers()
|
||||
|
||||
void movie_item_base::set_active(bool active)
|
||||
{
|
||||
if (!std::exchange(m_active, active) && active && m_movie)
|
||||
if (!std::exchange(m_active, active) && active)
|
||||
{
|
||||
m_movie->jumpToFrame(1);
|
||||
m_movie->start();
|
||||
init_movie();
|
||||
|
||||
if (m_movie)
|
||||
{
|
||||
m_movie->jumpToFrame(1);
|
||||
m_movie->start();
|
||||
}
|
||||
|
||||
if (m_media_player)
|
||||
{
|
||||
m_media_player->play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void movie_item_base::init_movie(const QString& path)
|
||||
void movie_item_base::init_movie()
|
||||
{
|
||||
if (path.isEmpty() || !m_icon_callback) return;
|
||||
|
||||
m_movie.reset(new QMovie(path));
|
||||
|
||||
if (!m_movie->isValid())
|
||||
if (m_movie || m_media_player)
|
||||
{
|
||||
m_movie.reset();
|
||||
// Already initialized
|
||||
return;
|
||||
}
|
||||
|
||||
QObject::connect(m_movie.get(), &QMovie::frameChanged, m_movie.get(), m_icon_callback);
|
||||
if (!m_icon_callback || m_movie_path.isEmpty() || !QFile::exists(m_movie_path))
|
||||
{
|
||||
m_movie_path.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString lower = m_movie_path.toLower();
|
||||
|
||||
if (lower.endsWith(".gif"))
|
||||
{
|
||||
m_movie.reset(new QMovie(m_movie_path));
|
||||
m_movie_path.clear();
|
||||
|
||||
if (!m_movie->isValid())
|
||||
{
|
||||
m_movie.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
QObject::connect(m_movie.get(), &QMovie::frameChanged, m_movie.get(), [this](int)
|
||||
{
|
||||
m_icon_callback({});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (lower.endsWith(".pam"))
|
||||
{
|
||||
// We can't set PAM files as source of the video player, so we have to feed them as raw data.
|
||||
QFile file(m_movie_path);
|
||||
if (!file.open(QFile::OpenModeFlag::ReadOnly))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Decode the pam properly before pushing it to the player
|
||||
m_movie_data = file.readAll();
|
||||
if (m_movie_data.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_movie_buffer.reset(new QBuffer(&m_movie_data));
|
||||
m_movie_buffer->open(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
m_video_sink.reset(new QVideoSink());
|
||||
QObject::connect(m_video_sink.get(), &QVideoSink::videoFrameChanged, m_video_sink.get(), [this](const QVideoFrame& frame)
|
||||
{
|
||||
m_icon_callback(frame);
|
||||
});
|
||||
|
||||
m_media_player.reset(new QMediaPlayer());
|
||||
m_media_player->setVideoSink(m_video_sink.get());
|
||||
m_media_player->setLoops(QMediaPlayer::Infinite);
|
||||
|
||||
if (m_movie_buffer)
|
||||
{
|
||||
m_media_player->setSourceDevice(m_movie_buffer.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_media_player->setSource(m_movie_path);
|
||||
}
|
||||
}
|
||||
|
||||
void movie_item_base::stop_movie()
|
||||
{
|
||||
if (m_movie)
|
||||
{
|
||||
m_movie->stop();
|
||||
}
|
||||
|
||||
m_video_sink.reset();
|
||||
m_media_player.reset();
|
||||
m_movie_buffer.reset();
|
||||
m_movie_data.clear();
|
||||
}
|
||||
|
||||
QPixmap movie_item_base::get_movie_image(const QVideoFrame& frame) const
|
||||
{
|
||||
if (!m_active)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m_movie)
|
||||
{
|
||||
return m_movie->currentPixmap();
|
||||
}
|
||||
|
||||
if (!frame.isValid())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// Get image. This usually also converts the image to ARGB32.
|
||||
return QPixmap::fromImage(frame.toImage());
|
||||
}
|
||||
|
||||
void movie_item_base::call_icon_func() const
|
||||
{
|
||||
if (m_icon_callback)
|
||||
{
|
||||
m_icon_callback(0);
|
||||
m_icon_callback({});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,16 @@
|
||||
|
||||
#include <QMovie>
|
||||
#include <QThread>
|
||||
#include <QBuffer>
|
||||
#include <QMediaPlayer>
|
||||
#include <QVideoSink>
|
||||
#include <QVideoFrame>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
using icon_callback_t = std::function<void(int)>;
|
||||
using icon_callback_t = std::function<void(const QVideoFrame&)>;
|
||||
using icon_load_callback_t = std::function<void(int)>;
|
||||
using size_calc_callback_t = std::function<void()>;
|
||||
|
||||
@ -29,12 +34,14 @@ public:
|
||||
return m_active;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<QMovie> movie() const
|
||||
void set_movie_path(QString path)
|
||||
{
|
||||
return m_movie;
|
||||
m_movie_path = std::move(path);
|
||||
}
|
||||
|
||||
void init_movie(const QString& path);
|
||||
void init_movie();
|
||||
void stop_movie();
|
||||
QPixmap get_movie_image(const QVideoFrame& frame) const;
|
||||
|
||||
void call_icon_func() const;
|
||||
void set_icon_func(const icon_callback_t& func);
|
||||
@ -71,6 +78,11 @@ public:
|
||||
shared_mutex pixmap_mutex;
|
||||
|
||||
protected:
|
||||
QString m_movie_path;
|
||||
QByteArray m_movie_data{};
|
||||
std::unique_ptr<QBuffer> m_movie_buffer;
|
||||
std::unique_ptr<QMediaPlayer> m_media_player;
|
||||
std::shared_ptr<QVideoSink> m_video_sink;
|
||||
std::shared_ptr<QMovie> m_movie;
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user