diff options
| author | 2019-01-21 14:12:47 -0500 | |
|---|---|---|
| committer | 2019-01-21 14:12:47 -0500 | |
| commit | 125599c2d51fba0bb9466d92382631ed7f34bed9 (patch) | |
| tree | a0fc21fcf2d49ff81938f0463cf3a5da4dcd3184 /src | |
| parent | Merge pull request #2034 from jroweboy/loading-widget (diff) | |
| parent | Change const char* to const char[] (diff) | |
| download | yuzu-125599c2d51fba0bb9466d92382631ed7f34bed9.tar.gz yuzu-125599c2d51fba0bb9466d92382631ed7f34bed9.tar.xz yuzu-125599c2d51fba0bb9466d92382631ed7f34bed9.zip | |
Merge pull request #2038 from jroweboy/loading-progress-bar
Loading progress bar upgrades
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 9 | ||||
| -rw-r--r-- | src/yuzu/loading_screen.cpp | 151 | ||||
| -rw-r--r-- | src/yuzu/loading_screen.h | 38 | ||||
| -rw-r--r-- | src/yuzu/loading_screen.ui | 162 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 13 |
5 files changed, 316 insertions, 57 deletions
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 06fc59dbe..ff5310848 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <functional> | ||
| 7 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 8 | #include "video_core/engines/fermi_2d.h" | 9 | #include "video_core/engines/fermi_2d.h" |
| 9 | #include "video_core/gpu.h" | 10 | #include "video_core/gpu.h" |
| @@ -11,6 +12,14 @@ | |||
| 11 | 12 | ||
| 12 | namespace VideoCore { | 13 | namespace VideoCore { |
| 13 | 14 | ||
| 15 | enum class LoadCallbackStage { | ||
| 16 | Prepare, | ||
| 17 | Decompile, | ||
| 18 | Build, | ||
| 19 | Complete, | ||
| 20 | }; | ||
| 21 | using DiskResourceLoadCallback = std::function<void(LoadCallbackStage, std::size_t, std::size_t)>; | ||
| 22 | |||
| 14 | class RasterizerInterface { | 23 | class RasterizerInterface { |
| 15 | public: | 24 | public: |
| 16 | virtual ~RasterizerInterface() {} | 25 | virtual ~RasterizerInterface() {} |
diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp index 0f3c4bb6c..907aac4f1 100644 --- a/src/yuzu/loading_screen.cpp +++ b/src/yuzu/loading_screen.cpp | |||
| @@ -2,8 +2,10 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <unordered_map> | ||
| 5 | #include <QBuffer> | 6 | #include <QBuffer> |
| 6 | #include <QByteArray> | 7 | #include <QByteArray> |
| 8 | #include <QGraphicsOpacityEffect> | ||
| 7 | #include <QHBoxLayout> | 9 | #include <QHBoxLayout> |
| 8 | #include <QIODevice> | 10 | #include <QIODevice> |
| 9 | #include <QImage> | 11 | #include <QImage> |
| @@ -12,11 +14,14 @@ | |||
| 12 | #include <QPalette> | 14 | #include <QPalette> |
| 13 | #include <QPixmap> | 15 | #include <QPixmap> |
| 14 | #include <QProgressBar> | 16 | #include <QProgressBar> |
| 17 | #include <QPropertyAnimation> | ||
| 15 | #include <QStyleOption> | 18 | #include <QStyleOption> |
| 16 | #include <QWindow> | 19 | #include <QTime> |
| 20 | #include <QtConcurrent/QtConcurrentRun> | ||
| 17 | #include "common/logging/log.h" | 21 | #include "common/logging/log.h" |
| 18 | #include "core/loader/loader.h" | 22 | #include "core/loader/loader.h" |
| 19 | #include "ui_loading_screen.h" | 23 | #include "ui_loading_screen.h" |
| 24 | #include "video_core/rasterizer_interface.h" | ||
| 20 | #include "yuzu/loading_screen.h" | 25 | #include "yuzu/loading_screen.h" |
| 21 | 26 | ||
| 22 | // Mingw seems to not have QMovie at all. If QMovie is missing then use a single frame instead of an | 27 | // Mingw seems to not have QMovie at all. If QMovie is missing then use a single frame instead of an |
| @@ -25,11 +30,84 @@ | |||
| 25 | #include <QMovie> | 30 | #include <QMovie> |
| 26 | #endif | 31 | #endif |
| 27 | 32 | ||
| 33 | constexpr const char PROGRESSBAR_STYLE_PREPARE[] = R"( | ||
| 34 | QProgressBar {} | ||
| 35 | QProgressBar::chunk {})"; | ||
| 36 | |||
| 37 | constexpr const char PROGRESSBAR_STYLE_DECOMPILE[] = R"( | ||
| 38 | QProgressBar { | ||
| 39 | background-color: black; | ||
| 40 | border: 2px solid white; | ||
| 41 | border-radius: 4px; | ||
| 42 | padding: 2px; | ||
| 43 | } | ||
| 44 | QProgressBar::chunk { | ||
| 45 | background-color: #0ab9e6; | ||
| 46 | })"; | ||
| 47 | |||
| 48 | constexpr const char PROGRESSBAR_STYLE_BUILD[] = R"( | ||
| 49 | QProgressBar { | ||
| 50 | background-color: black; | ||
| 51 | border: 2px solid white; | ||
| 52 | border-radius: 4px; | ||
| 53 | padding: 2px; | ||
| 54 | } | ||
| 55 | QProgressBar::chunk { | ||
| 56 | background-color: #ff3c28; | ||
| 57 | })"; | ||
| 58 | |||
| 59 | constexpr const char PROGRESSBAR_STYLE_COMPLETE[] = R"( | ||
| 60 | QProgressBar { | ||
| 61 | background-color: #0ab9e6; | ||
| 62 | border: 2px solid white; | ||
| 63 | border-radius: 4px; | ||
| 64 | padding: 2px; | ||
| 65 | } | ||
| 66 | QProgressBar::chunk { | ||
| 67 | background-color: #ff3c28; | ||
| 68 | })"; | ||
| 69 | |||
| 28 | LoadingScreen::LoadingScreen(QWidget* parent) | 70 | LoadingScreen::LoadingScreen(QWidget* parent) |
| 29 | : QWidget(parent), ui(std::make_unique<Ui::LoadingScreen>()) { | 71 | : QWidget(parent), ui(std::make_unique<Ui::LoadingScreen>()), |
| 72 | previous_stage(VideoCore::LoadCallbackStage::Complete) { | ||
| 30 | ui->setupUi(this); | 73 | ui->setupUi(this); |
| 31 | // Progress bar is hidden until we have a use for it. | 74 | setMinimumSize(1280, 720); |
| 32 | ui->progress_bar->hide(); | 75 | |
| 76 | // Create a fade out effect to hide this loading screen widget. | ||
| 77 | // When fading opacity, it will fade to the parent widgets background color, which is why we | ||
| 78 | // create an internal widget named fade_widget that we use the effect on, while keeping the | ||
| 79 | // loading screen widget's background color black. This way we can create a fade to black effect | ||
| 80 | opacity_effect = new QGraphicsOpacityEffect(this); | ||
| 81 | opacity_effect->setOpacity(1); | ||
| 82 | ui->fade_parent->setGraphicsEffect(opacity_effect); | ||
| 83 | fadeout_animation = std::make_unique<QPropertyAnimation>(opacity_effect, "opacity"); | ||
| 84 | fadeout_animation->setDuration(500); | ||
| 85 | fadeout_animation->setStartValue(1); | ||
| 86 | fadeout_animation->setEndValue(0); | ||
| 87 | fadeout_animation->setEasingCurve(QEasingCurve::OutBack); | ||
| 88 | |||
| 89 | // After the fade completes, hide the widget and reset the opacity | ||
| 90 | connect(fadeout_animation.get(), &QPropertyAnimation::finished, [this] { | ||
| 91 | hide(); | ||
| 92 | opacity_effect->setOpacity(1); | ||
| 93 | emit Hidden(); | ||
| 94 | }); | ||
| 95 | connect(this, &LoadingScreen::LoadProgress, this, &LoadingScreen::OnLoadProgress, | ||
| 96 | Qt::QueuedConnection); | ||
| 97 | qRegisterMetaType<VideoCore::LoadCallbackStage>(); | ||
| 98 | |||
| 99 | stage_translations = { | ||
| 100 | {VideoCore::LoadCallbackStage::Prepare, tr("Loading...")}, | ||
| 101 | {VideoCore::LoadCallbackStage::Decompile, tr("Preparing Shaders %1 / %2")}, | ||
| 102 | {VideoCore::LoadCallbackStage::Build, tr("Loading Shaders %1 / %2")}, | ||
| 103 | {VideoCore::LoadCallbackStage::Complete, tr("Launching...")}, | ||
| 104 | }; | ||
| 105 | progressbar_style = { | ||
| 106 | {VideoCore::LoadCallbackStage::Prepare, PROGRESSBAR_STYLE_PREPARE}, | ||
| 107 | {VideoCore::LoadCallbackStage::Decompile, PROGRESSBAR_STYLE_DECOMPILE}, | ||
| 108 | {VideoCore::LoadCallbackStage::Build, PROGRESSBAR_STYLE_BUILD}, | ||
| 109 | {VideoCore::LoadCallbackStage::Complete, PROGRESSBAR_STYLE_COMPLETE}, | ||
| 110 | }; | ||
| 33 | } | 111 | } |
| 34 | 112 | ||
| 35 | LoadingScreen::~LoadingScreen() = default; | 113 | LoadingScreen::~LoadingScreen() = default; |
| @@ -42,11 +120,11 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { | |||
| 42 | map.loadFromData(buffer.data(), buffer.size()); | 120 | map.loadFromData(buffer.data(), buffer.size()); |
| 43 | ui->banner->setPixmap(map); | 121 | ui->banner->setPixmap(map); |
| 44 | #else | 122 | #else |
| 45 | backing_mem = | 123 | backing_mem = std::make_unique<QByteArray>(reinterpret_cast<char*>(buffer.data()), |
| 46 | std::make_unique<QByteArray>(reinterpret_cast<char*>(buffer.data()), buffer.size()); | 124 | static_cast<int>(buffer.size())); |
| 47 | backing_buf = std::make_unique<QBuffer>(backing_mem.get()); | 125 | backing_buf = std::make_unique<QBuffer>(backing_mem.get()); |
| 48 | backing_buf->open(QIODevice::ReadOnly); | 126 | backing_buf->open(QIODevice::ReadOnly); |
| 49 | animation = std::make_unique<QMovie>(backing_buf.get(), QByteArray("GIF")); | 127 | animation = std::make_unique<QMovie>(backing_buf.get(), QByteArray()); |
| 50 | animation->start(); | 128 | animation->start(); |
| 51 | ui->banner->setMovie(animation.get()); | 129 | ui->banner->setMovie(animation.get()); |
| 52 | #endif | 130 | #endif |
| @@ -54,17 +132,68 @@ void LoadingScreen::Prepare(Loader::AppLoader& loader) { | |||
| 54 | } | 132 | } |
| 55 | if (loader.ReadLogo(buffer) == Loader::ResultStatus::Success) { | 133 | if (loader.ReadLogo(buffer) == Loader::ResultStatus::Success) { |
| 56 | QPixmap map; | 134 | QPixmap map; |
| 57 | map.loadFromData(buffer.data(), buffer.size()); | 135 | map.loadFromData(buffer.data(), static_cast<uint>(buffer.size())); |
| 58 | ui->logo->setPixmap(map); | 136 | ui->logo->setPixmap(map); |
| 59 | } | 137 | } |
| 138 | |||
| 139 | slow_shader_compile_start = false; | ||
| 140 | OnLoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); | ||
| 141 | } | ||
| 142 | |||
| 143 | void LoadingScreen::OnLoadComplete() { | ||
| 144 | fadeout_animation->start(QPropertyAnimation::KeepWhenStopped); | ||
| 60 | } | 145 | } |
| 61 | 146 | ||
| 62 | void LoadingScreen::OnLoadProgress(std::size_t value, std::size_t total) { | 147 | void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, |
| 148 | std::size_t total) { | ||
| 149 | using namespace std::chrono; | ||
| 150 | auto now = high_resolution_clock::now(); | ||
| 151 | // reset the timer if the stage changes | ||
| 152 | if (stage != previous_stage) { | ||
| 153 | ui->progress_bar->setStyleSheet(progressbar_style[stage]); | ||
| 154 | // Hide the progress bar during the prepare stage | ||
| 155 | if (stage == VideoCore::LoadCallbackStage::Prepare) { | ||
| 156 | ui->progress_bar->hide(); | ||
| 157 | } else { | ||
| 158 | ui->progress_bar->show(); | ||
| 159 | } | ||
| 160 | previous_stage = stage; | ||
| 161 | // reset back to fast shader compiling since the stage changed | ||
| 162 | slow_shader_compile_start = false; | ||
| 163 | } | ||
| 164 | // update the max of the progress bar if the number of shaders change | ||
| 63 | if (total != previous_total) { | 165 | if (total != previous_total) { |
| 64 | ui->progress_bar->setMaximum(total); | 166 | ui->progress_bar->setMaximum(static_cast<int>(total)); |
| 65 | previous_total = total; | 167 | previous_total = total; |
| 66 | } | 168 | } |
| 67 | ui->progress_bar->setValue(value); | 169 | |
| 170 | QString estimate; | ||
| 171 | // If theres a drastic slowdown in the rate, then display an estimate | ||
| 172 | if (now - previous_time > milliseconds{50} || slow_shader_compile_start) { | ||
| 173 | if (!slow_shader_compile_start) { | ||
| 174 | slow_shader_start = high_resolution_clock::now(); | ||
| 175 | slow_shader_compile_start = true; | ||
| 176 | slow_shader_first_value = value; | ||
| 177 | } | ||
| 178 | // only calculate an estimate time after a second has passed since stage change | ||
| 179 | auto diff = duration_cast<milliseconds>(now - slow_shader_start); | ||
| 180 | if (diff > seconds{1}) { | ||
| 181 | auto eta_mseconds = | ||
| 182 | static_cast<long>(static_cast<double>(total - slow_shader_first_value) / | ||
| 183 | (value - slow_shader_first_value) * diff.count()); | ||
| 184 | estimate = | ||
| 185 | tr("Estimated Time %1") | ||
| 186 | .arg(QTime(0, 0, 0, 0) | ||
| 187 | .addMSecs(std::max<long>(eta_mseconds - diff.count() + 1000, 1000)) | ||
| 188 | .toString("mm:ss")); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | // update labels and progress bar | ||
| 193 | ui->stage->setText(stage_translations[stage].arg(value).arg(total)); | ||
| 194 | ui->value->setText(estimate); | ||
| 195 | ui->progress_bar->setValue(static_cast<int>(value)); | ||
| 196 | previous_time = now; | ||
| 68 | } | 197 | } |
| 69 | 198 | ||
| 70 | void LoadingScreen::paintEvent(QPaintEvent* event) { | 199 | void LoadingScreen::paintEvent(QPaintEvent* event) { |
diff --git a/src/yuzu/loading_screen.h b/src/yuzu/loading_screen.h index 2a6cf1142..801d08e1a 100644 --- a/src/yuzu/loading_screen.h +++ b/src/yuzu/loading_screen.h | |||
| @@ -4,7 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <chrono> | ||
| 7 | #include <memory> | 8 | #include <memory> |
| 9 | #include <QString> | ||
| 8 | #include <QWidget> | 10 | #include <QWidget> |
| 9 | 11 | ||
| 10 | #if !QT_CONFIG(movie) | 12 | #if !QT_CONFIG(movie) |
| @@ -19,9 +21,15 @@ namespace Ui { | |||
| 19 | class LoadingScreen; | 21 | class LoadingScreen; |
| 20 | } | 22 | } |
| 21 | 23 | ||
| 24 | namespace VideoCore { | ||
| 25 | enum class LoadCallbackStage; | ||
| 26 | } | ||
| 27 | |||
| 22 | class QBuffer; | 28 | class QBuffer; |
| 23 | class QByteArray; | 29 | class QByteArray; |
| 30 | class QGraphicsOpacityEffect; | ||
| 24 | class QMovie; | 31 | class QMovie; |
| 32 | class QPropertyAnimation; | ||
| 25 | 33 | ||
| 26 | class LoadingScreen : public QWidget { | 34 | class LoadingScreen : public QWidget { |
| 27 | Q_OBJECT | 35 | Q_OBJECT |
| @@ -39,11 +47,21 @@ public: | |||
| 39 | /// used resources such as the logo and banner. | 47 | /// used resources such as the logo and banner. |
| 40 | void Clear(); | 48 | void Clear(); |
| 41 | 49 | ||
| 50 | /// Slot used to update the status of the progress bar | ||
| 51 | void OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); | ||
| 52 | |||
| 53 | /// Hides the LoadingScreen with a fade out effect | ||
| 54 | void OnLoadComplete(); | ||
| 55 | |||
| 42 | // In order to use a custom widget with a stylesheet, you need to override the paintEvent | 56 | // In order to use a custom widget with a stylesheet, you need to override the paintEvent |
| 43 | // See https://wiki.qt.io/How_to_Change_the_Background_Color_of_QWidget | 57 | // See https://wiki.qt.io/How_to_Change_the_Background_Color_of_QWidget |
| 44 | void paintEvent(QPaintEvent* event) override; | 58 | void paintEvent(QPaintEvent* event) override; |
| 45 | 59 | ||
| 46 | void OnLoadProgress(std::size_t value, std::size_t total); | 60 | signals: |
| 61 | void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); | ||
| 62 | /// Signals that this widget is completely hidden now and should be replaced with the other | ||
| 63 | /// widget | ||
| 64 | void Hidden(); | ||
| 47 | 65 | ||
| 48 | private: | 66 | private: |
| 49 | #ifndef YUZU_QT_MOVIE_MISSING | 67 | #ifndef YUZU_QT_MOVIE_MISSING |
| @@ -53,4 +71,22 @@ private: | |||
| 53 | #endif | 71 | #endif |
| 54 | std::unique_ptr<Ui::LoadingScreen> ui; | 72 | std::unique_ptr<Ui::LoadingScreen> ui; |
| 55 | std::size_t previous_total = 0; | 73 | std::size_t previous_total = 0; |
| 74 | VideoCore::LoadCallbackStage previous_stage; | ||
| 75 | |||
| 76 | QGraphicsOpacityEffect* opacity_effect = nullptr; | ||
| 77 | std::unique_ptr<QPropertyAnimation> fadeout_animation; | ||
| 78 | |||
| 79 | // Definitions for the differences in text and styling for each stage | ||
| 80 | std::unordered_map<VideoCore::LoadCallbackStage, const char*> progressbar_style; | ||
| 81 | std::unordered_map<VideoCore::LoadCallbackStage, QString> stage_translations; | ||
| 82 | |||
| 83 | // newly generated shaders are added to the end of the file, so when loading and compiling | ||
| 84 | // shaders, it will start quickly but end slow if new shaders were added since previous launch. | ||
| 85 | // These variables are used to detect the change in speed so we can generate an ETA | ||
| 86 | bool slow_shader_compile_start = false; | ||
| 87 | std::chrono::high_resolution_clock::time_point slow_shader_start; | ||
| 88 | std::chrono::high_resolution_clock::time_point previous_time; | ||
| 89 | std::size_t slow_shader_first_value = 0; | ||
| 56 | }; | 90 | }; |
| 91 | |||
| 92 | Q_DECLARE_METATYPE(VideoCore::LoadCallbackStage); | ||
diff --git a/src/yuzu/loading_screen.ui b/src/yuzu/loading_screen.ui index 00579b670..a67d273fd 100644 --- a/src/yuzu/loading_screen.ui +++ b/src/yuzu/loading_screen.ui | |||
| @@ -30,46 +30,128 @@ | |||
| 30 | <number>0</number> | 30 | <number>0</number> |
| 31 | </property> | 31 | </property> |
| 32 | <item> | 32 | <item> |
| 33 | <widget class="QLabel" name="logo"> | 33 | <widget class="QWidget" name="fade_parent" native="true"> |
| 34 | <property name="text"> | 34 | <layout class="QVBoxLayout" name="verticalLayout_2"> |
| 35 | <string/> | 35 | <property name="spacing"> |
| 36 | </property> | 36 | <number>0</number> |
| 37 | <property name="alignment"> | 37 | </property> |
| 38 | <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> | 38 | <property name="leftMargin"> |
| 39 | </property> | 39 | <number>0</number> |
| 40 | <property name="margin"> | 40 | </property> |
| 41 | <number>30</number> | 41 | <property name="topMargin"> |
| 42 | </property> | 42 | <number>0</number> |
| 43 | </widget> | 43 | </property> |
| 44 | </item> | 44 | <property name="rightMargin"> |
| 45 | <item> | 45 | <number>0</number> |
| 46 | <layout class="QHBoxLayout" name="horizontalLayout"> | 46 | </property> |
| 47 | <item> | 47 | <property name="bottomMargin"> |
| 48 | <widget class="QProgressBar" name="progress_bar"> | 48 | <number>0</number> |
| 49 | <property name="styleSheet"> | 49 | </property> |
| 50 | <string notr="true">font-size: 26px;</string> | 50 | <item alignment="Qt::AlignLeft|Qt::AlignTop"> |
| 51 | </property> | 51 | <widget class="QLabel" name="logo"> |
| 52 | <property name="value"> | 52 | <property name="text"> |
| 53 | <number>0</number> | 53 | <string/> |
| 54 | </property> | 54 | </property> |
| 55 | <property name="format"> | 55 | <property name="alignment"> |
| 56 | <string>Loading Shaders %v out of %m</string> | 56 | <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
| 57 | </property> | 57 | </property> |
| 58 | </widget> | 58 | <property name="margin"> |
| 59 | </item> | 59 | <number>30</number> |
| 60 | </layout> | 60 | </property> |
| 61 | </item> | 61 | </widget> |
| 62 | <item alignment="Qt::AlignRight|Qt::AlignBottom"> | 62 | </item> |
| 63 | <widget class="QLabel" name="banner"> | 63 | <item> |
| 64 | <property name="styleSheet"> | 64 | <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,1"> |
| 65 | <string notr="true">background-color: black;</string> | 65 | <property name="spacing"> |
| 66 | </property> | 66 | <number>15</number> |
| 67 | <property name="text"> | 67 | </property> |
| 68 | <string/> | 68 | <property name="sizeConstraint"> |
| 69 | </property> | 69 | <enum>QLayout::SetNoConstraint</enum> |
| 70 | <property name="margin"> | 70 | </property> |
| 71 | <number>30</number> | 71 | <item alignment="Qt::AlignHCenter|Qt::AlignBottom"> |
| 72 | </property> | 72 | <widget class="QLabel" name="stage"> |
| 73 | <property name="sizePolicy"> | ||
| 74 | <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> | ||
| 75 | <horstretch>0</horstretch> | ||
| 76 | <verstretch>0</verstretch> | ||
| 77 | </sizepolicy> | ||
| 78 | </property> | ||
| 79 | <property name="styleSheet"> | ||
| 80 | <string notr="true">background-color: black; color: white; | ||
| 81 | font: 75 20pt "Arial";</string> | ||
| 82 | </property> | ||
| 83 | <property name="text"> | ||
| 84 | <string>Loading Shaders 387 / 1628</string> | ||
| 85 | </property> | ||
| 86 | </widget> | ||
| 87 | </item> | ||
| 88 | <item alignment="Qt::AlignHCenter|Qt::AlignTop"> | ||
| 89 | <widget class="QProgressBar" name="progress_bar"> | ||
| 90 | <property name="sizePolicy"> | ||
| 91 | <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> | ||
| 92 | <horstretch>0</horstretch> | ||
| 93 | <verstretch>0</verstretch> | ||
| 94 | </sizepolicy> | ||
| 95 | </property> | ||
| 96 | <property name="minimumSize"> | ||
| 97 | <size> | ||
| 98 | <width>500</width> | ||
| 99 | <height>40</height> | ||
| 100 | </size> | ||
| 101 | </property> | ||
| 102 | <property name="styleSheet"> | ||
| 103 | <string notr="true">QProgressBar { | ||
| 104 | color: white; | ||
| 105 | border: 2px solid white; | ||
| 106 | outline-color: black; | ||
| 107 | border-radius: 20px; | ||
| 108 | } | ||
| 109 | QProgressBar::chunk { | ||
| 110 | background-color: white; | ||
| 111 | border-radius: 15px; | ||
| 112 | }</string> | ||
| 113 | </property> | ||
| 114 | <property name="value"> | ||
| 115 | <number>50</number> | ||
| 116 | </property> | ||
| 117 | <property name="textVisible"> | ||
| 118 | <bool>false</bool> | ||
| 119 | </property> | ||
| 120 | <property name="format"> | ||
| 121 | <string>Loading Shaders %v out of %m</string> | ||
| 122 | </property> | ||
| 123 | </widget> | ||
| 124 | </item> | ||
| 125 | <item alignment="Qt::AlignHCenter|Qt::AlignTop"> | ||
| 126 | <widget class="QLabel" name="value"> | ||
| 127 | <property name="toolTip"> | ||
| 128 | <string notr="true"/> | ||
| 129 | </property> | ||
| 130 | <property name="styleSheet"> | ||
| 131 | <string notr="true">background-color: black; color: white; | ||
| 132 | font: 75 15pt "Arial";</string> | ||
| 133 | </property> | ||
| 134 | <property name="text"> | ||
| 135 | <string>Stage 1 of 2. Estimate Time 5m 4s</string> | ||
| 136 | </property> | ||
| 137 | </widget> | ||
| 138 | </item> | ||
| 139 | </layout> | ||
| 140 | </item> | ||
| 141 | <item alignment="Qt::AlignRight|Qt::AlignBottom"> | ||
| 142 | <widget class="QLabel" name="banner"> | ||
| 143 | <property name="styleSheet"> | ||
| 144 | <string notr="true">background-color: black;</string> | ||
| 145 | </property> | ||
| 146 | <property name="text"> | ||
| 147 | <string/> | ||
| 148 | </property> | ||
| 149 | <property name="margin"> | ||
| 150 | <number>30</number> | ||
| 151 | </property> | ||
| 152 | </widget> | ||
| 153 | </item> | ||
| 154 | </layout> | ||
| 73 | </widget> | 155 | </widget> |
| 74 | </item> | 156 | </item> |
| 75 | </layout> | 157 | </layout> |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 68bfa23ab..2c3e27c2e 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -415,6 +415,13 @@ void GMainWindow::InitializeWidgets() { | |||
| 415 | loading_screen = new LoadingScreen(this); | 415 | loading_screen = new LoadingScreen(this); |
| 416 | loading_screen->hide(); | 416 | loading_screen->hide(); |
| 417 | ui.horizontalLayout->addWidget(loading_screen); | 417 | ui.horizontalLayout->addWidget(loading_screen); |
| 418 | connect(loading_screen, &LoadingScreen::Hidden, [&] { | ||
| 419 | loading_screen->Clear(); | ||
| 420 | if (emulation_running) { | ||
| 421 | render_window->show(); | ||
| 422 | render_window->setFocus(); | ||
| 423 | } | ||
| 424 | }); | ||
| 418 | 425 | ||
| 419 | // Create status bar | 426 | // Create status bar |
| 420 | message_label = new QLabel(); | 427 | message_label = new QLabel(); |
| @@ -904,7 +911,6 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 904 | 911 | ||
| 905 | loading_screen->Prepare(Core::System::GetInstance().GetAppLoader()); | 912 | loading_screen->Prepare(Core::System::GetInstance().GetAppLoader()); |
| 906 | loading_screen->show(); | 913 | loading_screen->show(); |
| 907 | loading_screen->setFocus(); | ||
| 908 | 914 | ||
| 909 | emulation_running = true; | 915 | emulation_running = true; |
| 910 | if (ui.action_Fullscreen->isChecked()) { | 916 | if (ui.action_Fullscreen->isChecked()) { |
| @@ -1514,10 +1520,7 @@ void GMainWindow::OnStopGame() { | |||
| 1514 | } | 1520 | } |
| 1515 | 1521 | ||
| 1516 | void GMainWindow::OnLoadComplete() { | 1522 | void GMainWindow::OnLoadComplete() { |
| 1517 | loading_screen->hide(); | 1523 | loading_screen->OnLoadComplete(); |
| 1518 | loading_screen->Clear(); | ||
| 1519 | render_window->show(); | ||
| 1520 | render_window->setFocus(); | ||
| 1521 | } | 1524 | } |
| 1522 | 1525 | ||
| 1523 | void GMainWindow::OnMenuReportCompatibility() { | 1526 | void GMainWindow::OnMenuReportCompatibility() { |