diff options
Diffstat (limited to 'src/yuzu')
| -rw-r--r-- | src/yuzu/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | src/yuzu/applets/web_browser.cpp | 6 | ||||
| -rw-r--r-- | src/yuzu/applets/web_browser.h | 9 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 11 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.h | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_web.cpp | 11 | ||||
| -rw-r--r-- | src/yuzu/loading_screen.cpp | 213 | ||||
| -rw-r--r-- | src/yuzu/loading_screen.h | 92 | ||||
| -rw-r--r-- | src/yuzu/loading_screen.ui | 161 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 29 | ||||
| -rw-r--r-- | src/yuzu/main.h | 4 | 
11 files changed, 520 insertions, 24 deletions
| diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 1f852df4b..4cab599b4 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -68,6 +68,8 @@ add_executable(yuzu      game_list_p.h      game_list_worker.cpp      game_list_worker.h +    loading_screen.cpp +    loading_screen.h      hotkeys.cpp      hotkeys.h      main.cpp @@ -102,9 +104,10 @@ set(UIS      configuration/configure_system.ui      configuration/configure_touchscreen_advanced.ui      configuration/configure_web.ui +    compatdb.ui      hotkeys.ui +    loading_screen.ui      main.ui -    compatdb.ui  )  file(GLOB COMPAT_LIST diff --git a/src/yuzu/applets/web_browser.cpp b/src/yuzu/applets/web_browser.cpp index c59b7ade1..6a9138d53 100644 --- a/src/yuzu/applets/web_browser.cpp +++ b/src/yuzu/applets/web_browser.cpp @@ -86,9 +86,9 @@ QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {  QtWebBrowser::~QtWebBrowser() = default;  void QtWebBrowser::OpenPage(std::string_view url, std::function<void()> unpack_romfs_callback, -                            std::function<void()> finished_callback) const { -    this->unpack_romfs_callback = unpack_romfs_callback; -    this->finished_callback = finished_callback; +                            std::function<void()> finished_callback) { +    this->unpack_romfs_callback = std::move(unpack_romfs_callback); +    this->finished_callback = std::move(finished_callback);      const auto index = url.find('?');      if (index == std::string::npos) { diff --git a/src/yuzu/applets/web_browser.h b/src/yuzu/applets/web_browser.h index bba273767..1a3d67353 100644 --- a/src/yuzu/applets/web_browser.h +++ b/src/yuzu/applets/web_browser.h @@ -38,16 +38,15 @@ public:      ~QtWebBrowser() override;      void OpenPage(std::string_view url, std::function<void()> unpack_romfs_callback, -                  std::function<void()> finished_callback) const override; +                  std::function<void()> finished_callback) override;  signals:      void MainWindowOpenPage(std::string_view filename, std::string_view additional_args) const; -public slots: +private:      void MainWindowUnpackRomFS();      void MainWindowFinishedBrowsing(); -private: -    mutable std::function<void()> unpack_romfs_callback; -    mutable std::function<void()> finished_callback; +    std::function<void()> unpack_romfs_callback; +    std::function<void()> finished_callback;  }; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 40db7a5e9..f74cb693a 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -3,9 +3,7 @@  #include <QKeyEvent>  #include <QScreen>  #include <QWindow> -  #include <fmt/format.h> -  #include "common/microprofile.h"  #include "common/scm_rev.h"  #include "core/core.h" @@ -17,6 +15,7 @@  #include "video_core/renderer_base.h"  #include "video_core/video_core.h"  #include "yuzu/bootmanager.h" +#include "yuzu/main.h"  EmuThread::EmuThread(GRenderWindow* render_window) : render_window(render_window) {} @@ -114,6 +113,8 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)      InputCommon::Init();      InputCommon::StartJoystickEventHandler(); +    connect(this, &GRenderWindow::FirstFrameDisplayed, static_cast<GMainWindow*>(parent), +            &GMainWindow::OnLoadComplete);  }  GRenderWindow::~GRenderWindow() { @@ -141,6 +142,10 @@ void GRenderWindow::SwapBuffers() {      child->makeCurrent();      child->swapBuffers(); +    if (!first_frame) { +        emit FirstFrameDisplayed(); +        first_frame = true; +    }  }  void GRenderWindow::MakeCurrent() { @@ -309,6 +314,8 @@ void GRenderWindow::InitRenderTarget() {          delete layout();      } +    first_frame = false; +      // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground,      // WA_DontShowOnScreen, WA_DeleteOnClose      QGLFormat fmt; diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 4e3028215..d1f37e503 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -152,6 +152,7 @@ public slots:  signals:      /// Emitted when the window is closed      void Closed(); +    void FirstFrameDisplayed();  private:      std::pair<unsigned, unsigned> ScaleTouch(const QPointF pos) const; @@ -171,6 +172,8 @@ private:      /// Temporary storage of the screenshot taken      QImage screenshot_image; +    bool first_frame = false; +  protected:      void showEvent(QShowEvent* event) override;  }; diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp index 3c2ccb76f..18566d028 100644 --- a/src/yuzu/configuration/configure_web.cpp +++ b/src/yuzu/configuration/configure_web.cpp @@ -89,12 +89,11 @@ void ConfigureWeb::OnLoginChanged() {  void ConfigureWeb::VerifyLogin() {      ui->button_verify_login->setDisabled(true); -    ui->button_verify_login->setText(tr("Verifying")); -    verify_watcher.setFuture( -        QtConcurrent::run([this, username = ui->edit_username->text().toStdString(), -                           token = ui->edit_token->text().toStdString()]() { -            return Core::VerifyLogin(username, token); -        })); +    ui->button_verify_login->setText(tr("Verifying...")); +    verify_watcher.setFuture(QtConcurrent::run([username = ui->edit_username->text().toStdString(), +                                                token = ui->edit_token->text().toStdString()] { +        return Core::VerifyLogin(username, token); +    }));  }  void ConfigureWeb::OnLoginVerified() { diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp new file mode 100644 index 000000000..907aac4f1 --- /dev/null +++ b/src/yuzu/loading_screen.cpp @@ -0,0 +1,213 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <unordered_map> +#include <QBuffer> +#include <QByteArray> +#include <QGraphicsOpacityEffect> +#include <QHBoxLayout> +#include <QIODevice> +#include <QImage> +#include <QLabel> +#include <QPainter> +#include <QPalette> +#include <QPixmap> +#include <QProgressBar> +#include <QPropertyAnimation> +#include <QStyleOption> +#include <QTime> +#include <QtConcurrent/QtConcurrentRun> +#include "common/logging/log.h" +#include "core/loader/loader.h" +#include "ui_loading_screen.h" +#include "video_core/rasterizer_interface.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 <QMovie> +#endif + +constexpr const char PROGRESSBAR_STYLE_PREPARE[] = R"( +QProgressBar {} +QProgressBar::chunk {})"; + +constexpr const char PROGRESSBAR_STYLE_DECOMPILE[] = R"( +QProgressBar { +  background-color: black; +  border: 2px solid white; +  border-radius: 4px; +  padding: 2px; +} +QProgressBar::chunk { +  background-color: #0ab9e6; +})"; + +constexpr const char PROGRESSBAR_STYLE_BUILD[] = R"( +QProgressBar { +  background-color: black; +  border: 2px solid white; +  border-radius: 4px; +  padding: 2px; +} +QProgressBar::chunk { + background-color: #ff3c28; +})"; + +constexpr const char PROGRESSBAR_STYLE_COMPLETE[] = R"( +QProgressBar { +  background-color: #0ab9e6; +  border: 2px solid white; +  border-radius: 4px; +  padding: 2px; +} +QProgressBar::chunk { +  background-color: #ff3c28; +})"; + +LoadingScreen::LoadingScreen(QWidget* parent) +    : QWidget(parent), ui(std::make_unique<Ui::LoadingScreen>()), +      previous_stage(VideoCore::LoadCallbackStage::Complete) { +    ui->setupUi(this); +    setMinimumSize(1280, 720); + +    // Create a fade out effect to hide this loading screen widget. +    // When fading opacity, it will fade to the parent widgets background color, which is why we +    // create an internal widget named fade_widget that we use the effect on, while keeping the +    // loading screen widget's background color black. This way we can create a fade to black effect +    opacity_effect = new QGraphicsOpacityEffect(this); +    opacity_effect->setOpacity(1); +    ui->fade_parent->setGraphicsEffect(opacity_effect); +    fadeout_animation = std::make_unique<QPropertyAnimation>(opacity_effect, "opacity"); +    fadeout_animation->setDuration(500); +    fadeout_animation->setStartValue(1); +    fadeout_animation->setEndValue(0); +    fadeout_animation->setEasingCurve(QEasingCurve::OutBack); + +    // After the fade completes, hide the widget and reset the opacity +    connect(fadeout_animation.get(), &QPropertyAnimation::finished, [this] { +        hide(); +        opacity_effect->setOpacity(1); +        emit Hidden(); +    }); +    connect(this, &LoadingScreen::LoadProgress, this, &LoadingScreen::OnLoadProgress, +            Qt::QueuedConnection); +    qRegisterMetaType<VideoCore::LoadCallbackStage>(); + +    stage_translations = { +        {VideoCore::LoadCallbackStage::Prepare, tr("Loading...")}, +        {VideoCore::LoadCallbackStage::Decompile, tr("Preparing Shaders %1 / %2")}, +        {VideoCore::LoadCallbackStage::Build, tr("Loading Shaders %1 / %2")}, +        {VideoCore::LoadCallbackStage::Complete, tr("Launching...")}, +    }; +    progressbar_style = { +        {VideoCore::LoadCallbackStage::Prepare, PROGRESSBAR_STYLE_PREPARE}, +        {VideoCore::LoadCallbackStage::Decompile, PROGRESSBAR_STYLE_DECOMPILE}, +        {VideoCore::LoadCallbackStage::Build, PROGRESSBAR_STYLE_BUILD}, +        {VideoCore::LoadCallbackStage::Complete, PROGRESSBAR_STYLE_COMPLETE}, +    }; +} + +LoadingScreen::~LoadingScreen() = default; + +void LoadingScreen::Prepare(Loader::AppLoader& loader) { +    std::vector<u8> 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<QByteArray>(reinterpret_cast<char*>(buffer.data()), +                                                   static_cast<int>(buffer.size())); +        backing_buf = std::make_unique<QBuffer>(backing_mem.get()); +        backing_buf->open(QIODevice::ReadOnly); +        animation = std::make_unique<QMovie>(backing_buf.get(), QByteArray()); +        animation->start(); +        ui->banner->setMovie(animation.get()); +#endif +        buffer.clear(); +    } +    if (loader.ReadLogo(buffer) == Loader::ResultStatus::Success) { +        QPixmap map; +        map.loadFromData(buffer.data(), static_cast<uint>(buffer.size())); +        ui->logo->setPixmap(map); +    } + +    slow_shader_compile_start = false; +    OnLoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); +} + +void LoadingScreen::OnLoadComplete() { +    fadeout_animation->start(QPropertyAnimation::KeepWhenStopped); +} + +void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, +                                   std::size_t total) { +    using namespace std::chrono; +    auto now = high_resolution_clock::now(); +    // reset the timer if the stage changes +    if (stage != previous_stage) { +        ui->progress_bar->setStyleSheet(progressbar_style[stage]); +        // Hide the progress bar during the prepare stage +        if (stage == VideoCore::LoadCallbackStage::Prepare) { +            ui->progress_bar->hide(); +        } else { +            ui->progress_bar->show(); +        } +        previous_stage = stage; +        // reset back to fast shader compiling since the stage changed +        slow_shader_compile_start = false; +    } +    // update the max of the progress bar if the number of shaders change +    if (total != previous_total) { +        ui->progress_bar->setMaximum(static_cast<int>(total)); +        previous_total = total; +    } + +    QString estimate; +    // If theres a drastic slowdown in the rate, then display an estimate +    if (now - previous_time > milliseconds{50} || slow_shader_compile_start) { +        if (!slow_shader_compile_start) { +            slow_shader_start = high_resolution_clock::now(); +            slow_shader_compile_start = true; +            slow_shader_first_value = value; +        } +        // only calculate an estimate time after a second has passed since stage change +        auto diff = duration_cast<milliseconds>(now - slow_shader_start); +        if (diff > seconds{1}) { +            auto eta_mseconds = +                static_cast<long>(static_cast<double>(total - slow_shader_first_value) / +                                  (value - slow_shader_first_value) * diff.count()); +            estimate = +                tr("Estimated Time %1") +                    .arg(QTime(0, 0, 0, 0) +                             .addMSecs(std::max<long>(eta_mseconds - diff.count() + 1000, 1000)) +                             .toString("mm:ss")); +        } +    } + +    // update labels and progress bar +    ui->stage->setText(stage_translations[stage].arg(value).arg(total)); +    ui->value->setText(estimate); +    ui->progress_bar->setValue(static_cast<int>(value)); +    previous_time = now; +} + +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() { +#ifndef YUZU_QT_MOVIE_MISSING +    animation.reset(); +    backing_buf.reset(); +    backing_mem.reset(); +#endif +} diff --git a/src/yuzu/loading_screen.h b/src/yuzu/loading_screen.h new file mode 100644 index 000000000..801d08e1a --- /dev/null +++ b/src/yuzu/loading_screen.h @@ -0,0 +1,92 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <chrono> +#include <memory> +#include <QString> +#include <QWidget> + +#if !QT_CONFIG(movie) +#define YUZU_QT_MOVIE_MISSING 1 +#endif + +namespace Loader { +class AppLoader; +} + +namespace Ui { +class LoadingScreen; +} + +namespace VideoCore { +enum class LoadCallbackStage; +} + +class QBuffer; +class QByteArray; +class QGraphicsOpacityEffect; +class QMovie; +class QPropertyAnimation; + +class LoadingScreen : public QWidget { +    Q_OBJECT + +public: +    explicit LoadingScreen(QWidget* parent = nullptr); + +    ~LoadingScreen(); + +    /// Call before showing the loading screen to load the widgets with the logo and banner for the +    /// currently loaded application. +    void Prepare(Loader::AppLoader& loader); + +    /// After the loading screen is hidden, the owner of this class can call this to clean up any +    /// used resources such as the logo and banner. +    void Clear(); + +    /// Slot used to update the status of the progress bar +    void OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); + +    /// Hides the LoadingScreen with a fade out effect +    void OnLoadComplete(); + +    // In order to use a custom widget with a stylesheet, you need to override the paintEvent +    // See https://wiki.qt.io/How_to_Change_the_Background_Color_of_QWidget +    void paintEvent(QPaintEvent* event) override; + +signals: +    void LoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total); +    /// Signals that this widget is completely hidden now and should be replaced with the other +    /// widget +    void Hidden(); + +private: +#ifndef YUZU_QT_MOVIE_MISSING +    std::unique_ptr<QMovie> animation; +    std::unique_ptr<QBuffer> backing_buf; +    std::unique_ptr<QByteArray> backing_mem; +#endif +    std::unique_ptr<Ui::LoadingScreen> ui; +    std::size_t previous_total = 0; +    VideoCore::LoadCallbackStage previous_stage; + +    QGraphicsOpacityEffect* opacity_effect = nullptr; +    std::unique_ptr<QPropertyAnimation> fadeout_animation; + +    // Definitions for the differences in text and styling for each stage +    std::unordered_map<VideoCore::LoadCallbackStage, const char*> progressbar_style; +    std::unordered_map<VideoCore::LoadCallbackStage, QString> stage_translations; + +    // newly generated shaders are added to the end of the file, so when loading and compiling +    // shaders, it will start quickly but end slow if new shaders were added since previous launch. +    // These variables are used to detect the change in speed so we can generate an ETA +    bool slow_shader_compile_start = false; +    std::chrono::high_resolution_clock::time_point slow_shader_start; +    std::chrono::high_resolution_clock::time_point previous_time; +    std::size_t slow_shader_first_value = 0; +}; + +Q_DECLARE_METATYPE(VideoCore::LoadCallbackStage); diff --git a/src/yuzu/loading_screen.ui b/src/yuzu/loading_screen.ui new file mode 100644 index 000000000..a67d273fd --- /dev/null +++ b/src/yuzu/loading_screen.ui @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LoadingScreen</class> + <widget class="QWidget" name="LoadingScreen"> +  <property name="geometry"> +   <rect> +    <x>0</x> +    <y>0</y> +    <width>746</width> +    <height>495</height> +   </rect> +  </property> +  <property name="styleSheet"> +   <string notr="true">background-color: rgb(0, 0, 0);</string> +  </property> +  <layout class="QVBoxLayout"> +   <property name="spacing"> +    <number>0</number> +   </property> +   <property name="leftMargin"> +    <number>0</number> +   </property> +   <property name="topMargin"> +    <number>0</number> +   </property> +   <property name="rightMargin"> +    <number>0</number> +   </property> +   <property name="bottomMargin"> +    <number>0</number> +   </property> +   <item> +    <widget class="QWidget" name="fade_parent" native="true"> +     <layout class="QVBoxLayout" name="verticalLayout_2"> +      <property name="spacing"> +       <number>0</number> +      </property> +      <property name="leftMargin"> +       <number>0</number> +      </property> +      <property name="topMargin"> +       <number>0</number> +      </property> +      <property name="rightMargin"> +       <number>0</number> +      </property> +      <property name="bottomMargin"> +       <number>0</number> +      </property> +      <item alignment="Qt::AlignLeft|Qt::AlignTop"> +       <widget class="QLabel" name="logo"> +        <property name="text"> +         <string/> +        </property> +        <property name="alignment"> +         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> +        </property> +        <property name="margin"> +         <number>30</number> +        </property> +       </widget> +      </item> +      <item> +       <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,1"> +        <property name="spacing"> +         <number>15</number> +        </property> +        <property name="sizeConstraint"> +         <enum>QLayout::SetNoConstraint</enum> +        </property> +        <item alignment="Qt::AlignHCenter|Qt::AlignBottom"> +         <widget class="QLabel" name="stage"> +          <property name="sizePolicy"> +           <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> +            <horstretch>0</horstretch> +            <verstretch>0</verstretch> +           </sizepolicy> +          </property> +          <property name="styleSheet"> +           <string notr="true">background-color: black; color: white; +font: 75 20pt "Arial";</string> +          </property> +          <property name="text"> +           <string>Loading Shaders 387 / 1628</string> +          </property> +         </widget> +        </item> +        <item alignment="Qt::AlignHCenter|Qt::AlignTop"> +         <widget class="QProgressBar" name="progress_bar"> +          <property name="sizePolicy"> +           <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> +            <horstretch>0</horstretch> +            <verstretch>0</verstretch> +           </sizepolicy> +          </property> +          <property name="minimumSize"> +           <size> +            <width>500</width> +            <height>40</height> +           </size> +          </property> +          <property name="styleSheet"> +           <string notr="true">QProgressBar { +color: white; +border: 2px solid white; +outline-color: black; +border-radius: 20px; +} +QProgressBar::chunk { +background-color: white; +border-radius: 15px; +}</string> +          </property> +          <property name="value"> +           <number>50</number> +          </property> +          <property name="textVisible"> +           <bool>false</bool> +          </property> +          <property name="format"> +           <string>Loading Shaders %v out of %m</string> +          </property> +         </widget> +        </item> +        <item alignment="Qt::AlignHCenter|Qt::AlignTop"> +         <widget class="QLabel" name="value"> +          <property name="toolTip"> +           <string notr="true"/> +          </property> +          <property name="styleSheet"> +           <string notr="true">background-color: black; color: white; +font: 75 15pt "Arial";</string> +          </property> +          <property name="text"> +           <string>Stage 1 of 2. Estimate Time 5m 4s</string> +          </property> +         </widget> +        </item> +       </layout> +      </item> +      <item alignment="Qt::AlignRight|Qt::AlignBottom"> +       <widget class="QLabel" name="banner"> +        <property name="styleSheet"> +         <string notr="true">background-color: black;</string> +        </property> +        <property name="text"> +         <string/> +        </property> +        <property name="margin"> +         <number>30</number> +        </property> +       </widget> +      </item> +     </layout> +    </widget> +   </item> +  </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f564de994..2c3e27c2e 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -92,6 +92,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual  #include "yuzu/game_list.h"  #include "yuzu/game_list_p.h"  #include "yuzu/hotkeys.h" +#include "yuzu/loading_screen.h"  #include "yuzu/main.h"  #include "yuzu/ui_settings.h" @@ -411,6 +412,17 @@ void GMainWindow::InitializeWidgets() {      game_list = new GameList(vfs, this);      ui.horizontalLayout->addWidget(game_list); +    loading_screen = new LoadingScreen(this); +    loading_screen->hide(); +    ui.horizontalLayout->addWidget(loading_screen); +    connect(loading_screen, &LoadingScreen::Hidden, [&] { +        loading_screen->Clear(); +        if (emulation_running) { +            render_window->show(); +            render_window->setFocus(); +        } +    }); +      // Create status bar      message_label = new QLabel();      // Configured separately for left alignment @@ -897,8 +909,8 @@ void GMainWindow::BootGame(const QString& filename) {                         .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc,                              QString::fromStdString(title_name))); -    render_window->show(); -    render_window->setFocus(); +    loading_screen->Prepare(Core::System::GetInstance().GetAppLoader()); +    loading_screen->show();      emulation_running = true;      if (ui.action_Fullscreen->isChecked()) { @@ -932,6 +944,8 @@ void GMainWindow::ShutdownGame() {      ui.action_Load_Amiibo->setEnabled(false);      ui.action_Capture_Screenshot->setEnabled(false);      render_window->hide(); +    loading_screen->hide(); +    loading_screen->Clear();      game_list->show();      game_list->setFilterFocus();      setWindowTitle(QString("yuzu %1| %2-%3") @@ -1505,6 +1519,10 @@ void GMainWindow::OnStopGame() {      ShutdownGame();  } +void GMainWindow::OnLoadComplete() { +    loading_screen->OnLoadComplete(); +} +  void GMainWindow::OnMenuReportCompatibility() {      if (!Settings::values.yuzu_token.empty() && !Settings::values.yuzu_username.empty()) {          CompatDB compatdb{this}; @@ -1771,9 +1789,8 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {              this, tr("Confirm Key Rederivation"),              tr("You are about to force rederive all of your keys. \nIf you do not know what this "                 "means or what you are doing, \nthis is a potentially destructive action. \nPlease " -               "make " -               "sure this is what you want \nand optionally make backups.\n\nThis will delete your " -               "autogenerated key files and re-run the key derivation module."), +               "make sure this is what you want \nand optionally make backups.\n\nThis will delete " +               "your autogenerated key files and re-run the key derivation module."),              QMessageBox::StandardButtons{QMessageBox::Ok, QMessageBox::Cancel});          if (res == QMessageBox::Cancel) @@ -1818,7 +1835,7 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {                      errors +                      tr("<br><br>You can get all of these and dump all of your games easily by "                         "following <a href='https://yuzu-emu.org/help/quickstart/'>the " -                       "quickstart guide</a>. Alternatively, you can use another method of dumping " +                       "quickstart guide</a>. Alternatively, you can use another method of dumping"                         "to obtain all of your keys."));          } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 2d705ad54..e07c892cf 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -25,6 +25,7 @@ class GImageInfo;  class GraphicsBreakPointsWidget;  class GraphicsSurfaceWidget;  class GRenderWindow; +class LoadingScreen;  class MicroProfileDialog;  class ProfilerWidget;  class QLabel; @@ -109,10 +110,10 @@ signals:      void WebBrowserFinishedBrowsing();  public slots: +    void OnLoadComplete();      void ProfileSelectorSelectProfile();      void SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters);      void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message); -      void WebBrowserOpenPage(std::string_view filename, std::string_view arguments);  private: @@ -212,6 +213,7 @@ private:      GRenderWindow* render_window;      GameList* game_list; +    LoadingScreen* loading_screen;      // Status bar elements      QLabel* message_label = nullptr; | 
