From 08fcf41b0a3d4e6066cb72f47c3e1d94bb7fc408 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Thu, 17 Jan 2019 00:01:00 -0700 Subject: QT Frontend: Add a Loading screen with progressbar With shader caches on the horizon, one requirement is to provide visible feedback for the progress. The shader cache reportedly takes several minutes to load for large caches that were invalidated, and as such we should provide a loading screen with progress. Adds a loading screen widget that will be shown until the first frame of the game is swapped. This was chosen in case shader caches are not being used, several games still take more than a few seconds to launch and could benefit from a loading screen. --- src/yuzu/loading_screen.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/yuzu/loading_screen.cpp (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp new file mode 100644 index 000000000..f2d3214f6 --- /dev/null +++ b/src/yuzu/loading_screen.cpp @@ -0,0 +1,71 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/logging/log.h" +#include "core/loader/loader.h" +#include "ui_loading_screen.h" +#include "yuzu/loading_screen.h" + +LoadingScreen::LoadingScreen(QWidget* parent) + : QWidget(parent), ui(std::make_unique()) { + ui->setupUi(this); + // Progress bar is hidden until we have a use for it. + ui->progress_bar->hide(); +} + +LoadingScreen::~LoadingScreen() = default; + +void LoadingScreen::Prepare(Loader::AppLoader& loader) { + std::vector buffer; + if (loader.ReadBanner(buffer) == Loader::ResultStatus::Success) { + backing_mem = + std::make_unique(reinterpret_cast(buffer.data()), buffer.size()); + backing_buf = std::make_unique(backing_mem.get()); + backing_buf->open(QIODevice::ReadOnly); + animation = std::make_unique(backing_buf.get(), QByteArray("GIF")); + animation->start(); + ui->banner->setMovie(animation.get()); + buffer.clear(); + } + if (loader.ReadLogo(buffer) == Loader::ResultStatus::Success) { + QPixmap map; + map.loadFromData(buffer.data(), buffer.size()); + ui->logo->setPixmap(map); + } +} + +void LoadingScreen::OnLoadProgress(std::size_t value, std::size_t total) { + if (total != previous_total) { + ui->progress_bar->setMaximum(total); + previous_total = total; + } + ui->progress_bar->setValue(value); +} + +void LoadingScreen::paintEvent(QPaintEvent* event) { + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} + +void LoadingScreen::Clear() { + animation.reset(); + backing_buf.reset(); + backing_mem.reset(); +} -- cgit v1.2.3 From 69da26754003cb4695380738f5a837c9a93b5eaa Mon Sep 17 00:00:00 2001 From: James Rowe Date: Fri, 18 Jan 2019 10:02:27 -0700 Subject: Add a workaround if QMovie isn't available --- src/yuzu/loading_screen.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/yuzu/loading_screen.cpp') diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index f2d3214f6..0f3c4bb6c 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -20,6 +19,12 @@ #include "ui_loading_screen.h" #include "yuzu/loading_screen.h" +// Mingw seems to not have QMovie at all. If QMovie is missing then use a single frame instead of an +// showing the full animation +#if !YUZU_QT_MOVIE_MISSING +#include +#endif + LoadingScreen::LoadingScreen(QWidget* parent) : QWidget(parent), ui(std::make_unique()) { ui->setupUi(this); @@ -32,6 +37,11 @@ LoadingScreen::~LoadingScreen() = default; void LoadingScreen::Prepare(Loader::AppLoader& loader) { std::vector buffer; if (loader.ReadBanner(buffer) == Loader::ResultStatus::Success) { +#ifdef YUZU_QT_MOVIE_MISSING + QPixmap map; + map.loadFromData(buffer.data(), buffer.size()); + ui->banner->setPixmap(map); +#else backing_mem = std::make_unique(reinterpret_cast(buffer.data()), buffer.size()); backing_buf = std::make_unique(backing_mem.get()); @@ -39,6 +49,7 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { animation = std::make_unique(backing_buf.get(), QByteArray("GIF")); animation->start(); ui->banner->setMovie(animation.get()); +#endif buffer.clear(); } if (loader.ReadLogo(buffer) == Loader::ResultStatus::Success) { @@ -65,7 +76,9 @@ void LoadingScreen::paintEvent(QPaintEvent* event) { } void LoadingScreen::Clear() { +#ifndef YUZU_QT_MOVIE_MISSING animation.reset(); backing_buf.reset(); backing_mem.reset(); +#endif } -- cgit v1.2.3