Add warning popup when loading save states for the first time (#6565)

* citra_qt: Remove global state usage in GMainWindow

* citra_qt: Add warning when loadings saves for the first time

* citra_qt: Focus window when launching game from cmdline

* citra_qt: Cleanup nullptr checks

* citra_qt: Move setting to UISettings

* renderer_opengl: Remove header
This commit is contained in:
GPUCode 2023-06-05 10:06:00 +03:00 committed by GitHub
parent 52f88f8fb4
commit 5b7cc76ba3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 80 deletions

View file

@ -78,7 +78,6 @@ void EmuThread::run() {
}); });
emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
emit HideLoadingScreen();
core_context.MakeCurrent(); core_context.MakeCurrent();

View file

@ -752,6 +752,7 @@ void Config::ReadUIValues() {
ReadBasicSetting(UISettings::values.show_filter_bar); ReadBasicSetting(UISettings::values.show_filter_bar);
ReadBasicSetting(UISettings::values.show_status_bar); ReadBasicSetting(UISettings::values.show_status_bar);
ReadBasicSetting(UISettings::values.confirm_before_closing); ReadBasicSetting(UISettings::values.confirm_before_closing);
ReadBasicSetting(UISettings::values.save_state_warning);
ReadBasicSetting(UISettings::values.first_start); ReadBasicSetting(UISettings::values.first_start);
ReadBasicSetting(UISettings::values.callout_flags); ReadBasicSetting(UISettings::values.callout_flags);
ReadBasicSetting(UISettings::values.show_console); ReadBasicSetting(UISettings::values.show_console);
@ -1209,6 +1210,7 @@ void Config::SaveUIValues() {
WriteBasicSetting(UISettings::values.show_filter_bar); WriteBasicSetting(UISettings::values.show_filter_bar);
WriteBasicSetting(UISettings::values.show_status_bar); WriteBasicSetting(UISettings::values.show_status_bar);
WriteBasicSetting(UISettings::values.confirm_before_closing); WriteBasicSetting(UISettings::values.confirm_before_closing);
WriteBasicSetting(UISettings::values.save_state_warning);
WriteBasicSetting(UISettings::values.first_start); WriteBasicSetting(UISettings::values.first_start);
WriteBasicSetting(UISettings::values.callout_flags); WriteBasicSetting(UISettings::values.callout_flags);
WriteBasicSetting(UISettings::values.show_console); WriteBasicSetting(UISettings::values.show_console);

View file

@ -90,4 +90,4 @@ bool CheckAuthorizationForMicrophone() {
return authorized_microphone; return authorized_microphone;
} }
} // AppleAuthorization } // namespace AppleAuthorization

View file

@ -66,9 +66,7 @@
#include "common/file_util.h" #include "common/file_util.h"
#include "common/literals.h" #include "common/literals.h"
#include "common/logging/backend.h" #include "common/logging/backend.h"
#include "common/logging/filter.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/logging/text_formatter.h"
#include "common/memory_detect.h" #include "common/memory_detect.h"
#include "common/microprofile.h" #include "common/microprofile.h"
#include "common/scm_rev.h" #include "common/scm_rev.h"
@ -83,16 +81,13 @@
#include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_extsavedata.h"
#include "core/file_sys/archive_source_sd_savedata.h" #include "core/file_sys/archive_source_sd_savedata.h"
#include "core/frontend/applets/default_applets.h" #include "core/frontend/applets/default_applets.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/cfg/cfg.h"
#include "core/hle/service/fs/archive.h" #include "core/hle/service/fs/archive.h"
#include "core/hle/service/nfc/nfc.h" #include "core/hle/service/nfc/nfc.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
#include "core/movie.h" #include "core/movie.h"
#include "core/savestate.h" #include "core/savestate.h"
#include "core/system_titles.h" #include "core/system_titles.h"
#include "game_list_p.h"
#include "input_common/main.h" #include "input_common/main.h"
#include "network/network_settings.h" #include "network/network_settings.h"
#include "ui_main.h" #include "ui_main.h"
@ -188,9 +183,9 @@ static QString PrettyProductName() {
return QSysInfo::prettyProductName(); return QSysInfo::prettyProductName();
} }
GMainWindow::GMainWindow() GMainWindow::GMainWindow(Core::System& system_)
: ui{std::make_unique<Ui::MainWindow>()}, config{std::make_unique<Config>()}, emu_thread{ : ui{std::make_unique<Ui::MainWindow>()}, system{system_}, movie{Core::Movie::GetInstance()},
nullptr} { config{std::make_unique<Config>()}, emu_thread{nullptr} {
InitializeLogging(); InitializeLogging();
Debugger::ToggleConsole(); Debugger::ToggleConsole();
Settings::LogSettings(); Settings::LogSettings();
@ -219,7 +214,7 @@ GMainWindow::GMainWindow()
Network::Init(); Network::Init();
Core::Movie::GetInstance().SetPlaybackCompletionCallback([this] { movie.SetPlaybackCompletionCallback([this] {
QMetaObject::invokeMethod(this, "OnMoviePlaybackCompleted", Qt::BlockingQueuedConnection); QMetaObject::invokeMethod(this, "OnMoviePlaybackCompleted", Qt::BlockingQueuedConnection);
}); });
@ -284,9 +279,10 @@ GMainWindow::GMainWindow()
} }
GMainWindow::~GMainWindow() { GMainWindow::~GMainWindow() {
// will get automatically deleted otherwise // Will get automatically deleted otherwise
if (render_window->parent() == nullptr) if (!render_window->parent()) {
delete render_window; delete render_window;
}
Pica::g_debug_context.reset(); Pica::g_debug_context.reset();
Network::Shutdown(); Network::Shutdown();
@ -317,6 +313,7 @@ void GMainWindow::InitializeWidgets() {
if (emulation_running) { if (emulation_running) {
render_window->show(); render_window->show();
render_window->setFocus(); render_window->setFocus();
render_window->activateWindow();
} }
}); });
@ -804,16 +801,14 @@ void GMainWindow::ConnectMenuEvents() {
connect_menu(ui->action_Close_Movie, &GMainWindow::OnCloseMovie); connect_menu(ui->action_Close_Movie, &GMainWindow::OnCloseMovie);
connect_menu(ui->action_Save_Movie, &GMainWindow::OnSaveMovie); connect_menu(ui->action_Save_Movie, &GMainWindow::OnSaveMovie);
connect_menu(ui->action_Movie_Read_Only_Mode, connect_menu(ui->action_Movie_Read_Only_Mode,
[](bool checked) { Core::Movie::GetInstance().SetReadOnly(checked); }); [this](bool checked) { movie.SetReadOnly(checked); });
connect_menu(ui->action_Enable_Frame_Advancing, [this] { connect_menu(ui->action_Enable_Frame_Advancing, [this] {
if (emulation_running) { if (emulation_running) {
Core::System::GetInstance().frame_limiter.SetFrameAdvancing( system.frame_limiter.SetFrameAdvancing(ui->action_Enable_Frame_Advancing->isChecked());
ui->action_Enable_Frame_Advancing->isChecked());
ui->action_Advance_Frame->setEnabled(ui->action_Enable_Frame_Advancing->isChecked()); ui->action_Advance_Frame->setEnabled(ui->action_Enable_Frame_Advancing->isChecked());
} }
}); });
connect_menu(ui->action_Advance_Frame, [this] { connect_menu(ui->action_Advance_Frame, [this] {
auto& system = Core::System::GetInstance();
if (emulation_running && system.frame_limiter.IsFrameAdvancing()) { if (emulation_running && system.frame_limiter.IsFrameAdvancing()) {
ui->action_Enable_Frame_Advancing->setChecked(true); ui->action_Enable_Frame_Advancing->setChecked(true);
ui->action_Advance_Frame->setEnabled(true); ui->action_Advance_Frame->setEnabled(true);
@ -845,7 +840,7 @@ void GMainWindow::ConnectMenuEvents() {
} }
void GMainWindow::UpdateMenuState() { void GMainWindow::UpdateMenuState() {
const bool is_paused = emu_thread == nullptr || !emu_thread->IsRunning(); const bool is_paused = !emu_thread || !emu_thread->IsRunning();
const std::array running_actions{ const std::array running_actions{
ui->action_Stop, ui->action_Stop,
@ -878,18 +873,20 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
for (QDockWidget* widget : widgets) { for (QDockWidget* widget : widgets) {
QWidget* old = widget->titleBarWidget(); QWidget* old = widget->titleBarWidget();
widget->setTitleBarWidget(nullptr); widget->setTitleBarWidget(nullptr);
if (old != nullptr) if (old) {
delete old; delete old;
} }
}
} else { } else {
for (QDockWidget* widget : widgets) { for (QDockWidget* widget : widgets) {
QWidget* old = widget->titleBarWidget(); QWidget* old = widget->titleBarWidget();
widget->setTitleBarWidget(new QWidget()); widget->setTitleBarWidget(new QWidget());
if (old != nullptr) if (old) {
delete old; delete old;
} }
} }
} }
}
void GMainWindow::OnCheckForUpdates() { void GMainWindow::OnCheckForUpdates() {
explicit_update_check = true; explicit_update_check = true;
@ -1027,16 +1024,15 @@ void GMainWindow::AllowOSSleep() {
bool GMainWindow::LoadROM(const QString& filename) { bool GMainWindow::LoadROM(const QString& filename) {
// Shutdown previous session if the emu thread is still active... // Shutdown previous session if the emu thread is still active...
if (emu_thread != nullptr) if (emu_thread) {
ShutdownGame(); ShutdownGame();
}
render_window->InitRenderTarget(); render_window->InitRenderTarget();
secondary_window->InitRenderTarget(); secondary_window->InitRenderTarget();
const auto scope = render_window->Acquire(); const auto scope = render_window->Acquire();
Core::System& system{Core::System::GetInstance()};
const Core::System::ResultStatus result{ const Core::System::ResultStatus result{
system.Load(*render_window, filename.toStdString(), secondary_window)}; system.Load(*render_window, filename.toStdString(), secondary_window)};
@ -1126,17 +1122,17 @@ void GMainWindow::BootGame(const QString& filename) {
StoreRecentFile(filename); // Put the filename on top of the list StoreRecentFile(filename); // Put the filename on top of the list
if (movie_record_on_start) { if (movie_record_on_start) {
Core::Movie::GetInstance().PrepareForRecording(); movie.PrepareForRecording();
} }
if (movie_playback_on_start) { if (movie_playback_on_start) {
Core::Movie::GetInstance().PrepareForPlayback(movie_playback_path.toStdString()); movie.PrepareForPlayback(movie_playback_path.toStdString());
} }
u64 title_id{0}; u64 title_id{0};
const std::string path = filename.toStdString(); const std::string path = filename.toStdString();
const auto loader = Loader::GetLoader(path); const auto loader = Loader::GetLoader(path);
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success) { if (loader && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success) {
// Load per game settings // Load per game settings
const std::string name{FileUtil::GetFilename(filename.toStdString())}; const std::string name{FileUtil::GetFilename(filename.toStdString())};
const std::string config_file_name = const std::string config_file_name =
@ -1158,21 +1154,20 @@ void GMainWindow::BootGame(const QString& filename) {
// Set everything up // Set everything up
if (movie_record_on_start) { if (movie_record_on_start) {
Core::Movie::GetInstance().StartRecording(movie_record_path.toStdString(), movie.StartRecording(movie_record_path.toStdString(), movie_record_author.toStdString());
movie_record_author.toStdString());
movie_record_on_start = false; movie_record_on_start = false;
movie_record_path.clear(); movie_record_path.clear();
movie_record_author.clear(); movie_record_author.clear();
} }
if (movie_playback_on_start) { if (movie_playback_on_start) {
Core::Movie::GetInstance().StartPlayback(movie_playback_path.toStdString()); movie.StartPlayback(movie_playback_path.toStdString());
movie_playback_on_start = false; movie_playback_on_start = false;
movie_playback_path.clear(); movie_playback_path.clear();
} }
if (ui->action_Enable_Frame_Advancing->isChecked()) { if (ui->action_Enable_Frame_Advancing->isChecked()) {
ui->action_Advance_Frame->setEnabled(true); ui->action_Advance_Frame->setEnabled(true);
Core::System::GetInstance().frame_limiter.SetFrameAdvancing(true); system.frame_limiter.SetFrameAdvancing(true);
} else { } else {
ui->action_Advance_Frame->setEnabled(false); ui->action_Advance_Frame->setEnabled(false);
} }
@ -1180,8 +1175,7 @@ void GMainWindow::BootGame(const QString& filename) {
if (video_dumping_on_start) { if (video_dumping_on_start) {
Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale( Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale(
VideoCore::g_renderer->GetResolutionScaleFactor())}; VideoCore::g_renderer->GetResolutionScaleFactor())};
if (!Core::System::GetInstance().VideoDumper().StartDumping( if (!system.VideoDumper().StartDumping(video_dumping_path.toStdString(), layout)) {
video_dumping_path.toStdString(), layout)) {
QMessageBox::critical( QMessageBox::critical(
this, tr("Citra"), this, tr("Citra"),
@ -1235,7 +1229,7 @@ void GMainWindow::BootGame(const QString& filename) {
render_window->show(); render_window->show();
render_window->hide(); render_window->hide();
loading_screen->Prepare(Core::System::GetInstance().GetAppLoader()); loading_screen->Prepare(system.GetAppLoader());
loading_screen->show(); loading_screen->show();
emulation_running = true; emulation_running = true;
@ -1256,7 +1250,7 @@ void GMainWindow::ShutdownGame() {
} }
#ifdef ENABLE_FFMPEG_VIDEO_DUMPER #ifdef ENABLE_FFMPEG_VIDEO_DUMPER
if (Core::System::GetInstance().VideoDumper().IsDumping()) { if (system.VideoDumper().IsDumping()) {
game_shutdown_delayed = true; game_shutdown_delayed = true;
OnStopVideoDumping(); OnStopVideoDumping();
return; return;
@ -1276,7 +1270,7 @@ void GMainWindow::ShutdownGame() {
Pica::g_debug_context->ClearBreakpoints(); Pica::g_debug_context->ClearBreakpoints();
// Frame advancing must be cancelled in order to release the emu thread from waiting // Frame advancing must be cancelled in order to release the emu thread from waiting
Core::System::GetInstance().frame_limiter.SetFrameAdvancing(false); system.frame_limiter.SetFrameAdvancing(false);
emit EmulationStopping(); emit EmulationStopping();
@ -1366,7 +1360,7 @@ void GMainWindow::UpdateRecentFiles() {
} }
void GMainWindow::UpdateSaveStates() { void GMainWindow::UpdateSaveStates() {
if (!Core::System::GetInstance().IsPoweredOn()) { if (!system.IsPoweredOn()) {
ui->menu_Load_State->setEnabled(false); ui->menu_Load_State->setEnabled(false);
ui->menu_Save_State->setEnabled(false); ui->menu_Save_State->setEnabled(false);
return; return;
@ -1381,8 +1375,7 @@ void GMainWindow::UpdateSaveStates() {
newest_slot_time = 0; newest_slot_time = 0;
u64 title_id; u64 title_id;
if (Core::System::GetInstance().GetAppLoader().ReadProgramId(title_id) != if (system.GetAppLoader().ReadProgramId(title_id) != Loader::ResultStatus::Success) {
Loader::ResultStatus::Success) {
return; return;
} }
auto savestates = Core::ListSaveStates(title_id); auto savestates = Core::ListSaveStates(title_id);
@ -1743,7 +1736,6 @@ void GMainWindow::OnStartGame() {
} }
void GMainWindow::OnRestartGame() { void GMainWindow::OnRestartGame() {
Core::System& system = Core::System::GetInstance();
if (!system.IsPoweredOn()) { if (!system.IsPoweredOn()) {
return; return;
} }
@ -1940,19 +1932,27 @@ void GMainWindow::TriggerRotateScreens() {
void GMainWindow::OnSaveState() { void GMainWindow::OnSaveState() {
QAction* action = qobject_cast<QAction*>(sender()); QAction* action = qobject_cast<QAction*>(sender());
assert(action); ASSERT(action);
Core::System::GetInstance().SendSignal(Core::System::Signal::Save, action->data().toUInt()); system.SendSignal(Core::System::Signal::Save, action->data().toUInt());
Core::System::GetInstance().frame_limiter.AdvanceFrame(); system.frame_limiter.AdvanceFrame();
newest_slot = action->data().toUInt(); newest_slot = action->data().toUInt();
} }
void GMainWindow::OnLoadState() { void GMainWindow::OnLoadState() {
QAction* action = qobject_cast<QAction*>(sender()); QAction* action = qobject_cast<QAction*>(sender());
assert(action); ASSERT(action);
Core::System::GetInstance().SendSignal(Core::System::Signal::Load, action->data().toUInt()); if (UISettings::values.save_state_warning) {
Core::System::GetInstance().frame_limiter.AdvanceFrame(); QMessageBox::warning(this, tr("Savestates"),
tr("Warning: Savestates are NOT a replacement for in-game saves, "
"and are not meant to be reliable.\n\nUse at your own risk!"));
UISettings::values.save_state_warning = false;
config->Save();
}
system.SendSignal(Core::System::Signal::Load, action->data().toUInt());
system.frame_limiter.AdvanceFrame();
} }
void GMainWindow::OnConfigure() { void GMainWindow::OnConfigure() {
@ -1998,7 +1998,7 @@ void GMainWindow::OnConfigure() {
} }
void GMainWindow::OnLoadAmiibo() { void GMainWindow::OnLoadAmiibo() {
if (emu_thread == nullptr || !emu_thread->IsRunning()) { if (!emu_thread || !emu_thread->IsRunning()) [[unlikely]] {
return; return;
} }
@ -2014,10 +2014,9 @@ void GMainWindow::OnLoadAmiibo() {
} }
void GMainWindow::LoadAmiibo(const QString& filename) { void GMainWindow::LoadAmiibo(const QString& filename) {
Core::System& system{Core::System::GetInstance()};
Service::SM::ServiceManager& sm = system.ServiceManager(); Service::SM::ServiceManager& sm = system.ServiceManager();
auto nfc = sm.GetService<Service::NFC::Module::Interface>("nfc:u"); auto nfc = sm.GetService<Service::NFC::Module::Interface>("nfc:u");
if (nfc == nullptr) { if (!nfc) [[unlikely]] {
return; return;
} }
@ -2045,10 +2044,9 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
} }
void GMainWindow::OnRemoveAmiibo() { void GMainWindow::OnRemoveAmiibo() {
Core::System& system{Core::System::GetInstance()};
Service::SM::ServiceManager& sm = system.ServiceManager(); Service::SM::ServiceManager& sm = system.ServiceManager();
auto nfc = sm.GetService<Service::NFC::Module::Interface>("nfc:u"); auto nfc = sm.GetService<Service::NFC::Module::Interface>("nfc:u");
if (nfc == nullptr) { if (!nfc) [[unlikely]] {
return; return;
} }
@ -2120,9 +2118,8 @@ void GMainWindow::OnCloseMovie() {
OnPauseGame(); OnPauseGame();
} }
const bool was_recording = const bool was_recording = movie.GetPlayMode() == Core::Movie::PlayMode::Recording;
Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording; movie.Shutdown();
Core::Movie::GetInstance().Shutdown();
if (was_recording) { if (was_recording) {
QMessageBox::information(this, tr("Movie Saved"), QMessageBox::information(this, tr("Movie Saved"),
tr("The movie is successfully saved.")); tr("The movie is successfully saved."));
@ -2143,8 +2140,8 @@ void GMainWindow::OnSaveMovie() {
OnPauseGame(); OnPauseGame();
} }
if (Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording) { if (movie.GetPlayMode() == Core::Movie::PlayMode::Recording) {
Core::Movie::GetInstance().SaveMovie(); movie.SaveMovie();
QMessageBox::information(this, tr("Movie Saved"), tr("The movie is successfully saved.")); QMessageBox::information(this, tr("Movie Saved"), tr("The movie is successfully saved."));
} else { } else {
LOG_ERROR(Frontend, "Tried to save movie while movie is not being recorded"); LOG_ERROR(Frontend, "Tried to save movie while movie is not being recorded");
@ -2156,7 +2153,7 @@ void GMainWindow::OnSaveMovie() {
} }
void GMainWindow::OnCaptureScreenshot() { void GMainWindow::OnCaptureScreenshot() {
if (emu_thread == nullptr || !emu_thread->IsRunning()) { if (!emu_thread || !emu_thread->IsRunning()) [[unlikely]] {
return; return;
} }
@ -2172,8 +2169,9 @@ void GMainWindow::OnCaptureScreenshot() {
UISettings::values.screenshot_path = path; UISettings::values.screenshot_path = path;
}; };
} }
const std::string filename =
game_title.remove(QRegularExpression(QStringLiteral("[\\/:?\"<>|]"))).toStdString(); static QRegularExpression expr(QStringLiteral("[\\/:?\"<>|]"));
const std::string filename = game_title.remove(expr).toStdString();
const std::string timestamp = const std::string timestamp =
QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yy_hh.mm.ss.z")).toStdString(); QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yy_hh.mm.ss.z")).toStdString();
path.append(fmt::format("/{}_{}.png", filename, timestamp)); path.append(fmt::format("/{}_{}.png", filename, timestamp));
@ -2195,7 +2193,7 @@ void GMainWindow::OnStartVideoDumping() {
if (emulation_running) { if (emulation_running) {
Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale( Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale(
VideoCore::g_renderer->GetResolutionScaleFactor())}; VideoCore::g_renderer->GetResolutionScaleFactor())};
if (!Core::System::GetInstance().VideoDumper().StartDumping(path.toStdString(), layout)) { if (!system.VideoDumper().StartDumping(path.toStdString(), layout)) {
QMessageBox::critical( QMessageBox::critical(
this, tr("Citra"), this, tr("Citra"),
tr("Could not start video dumping.<br>Refer to the log for details.")); tr("Could not start video dumping.<br>Refer to the log for details."));
@ -2214,15 +2212,14 @@ void GMainWindow::OnStopVideoDumping() {
video_dumping_on_start = false; video_dumping_on_start = false;
video_dumping_path.clear(); video_dumping_path.clear();
} else { } else {
const bool was_dumping = Core::System::GetInstance().VideoDumper().IsDumping(); const bool was_dumping = system.VideoDumper().IsDumping();
if (!was_dumping) if (!was_dumping)
return; return;
game_paused_for_dumping = emu_thread->IsRunning(); game_paused_for_dumping = emu_thread->IsRunning();
OnPauseGame(); OnPauseGame();
auto future = auto future = QtConcurrent::run([this] { system.VideoDumper().StopDumping(); });
QtConcurrent::run([] { Core::System::GetInstance().VideoDumper().StopDumping(); });
auto* future_watcher = new QFutureWatcher<void>(this); auto* future_watcher = new QFutureWatcher<void>(this);
connect(future_watcher, &QFutureWatcher<void>::finished, this, [this] { connect(future_watcher, &QFutureWatcher<void>::finished, this, [this] {
if (game_shutdown_delayed) { if (game_shutdown_delayed) {
@ -2239,15 +2236,15 @@ void GMainWindow::OnStopVideoDumping() {
#endif #endif
void GMainWindow::UpdateStatusBar() { void GMainWindow::UpdateStatusBar() {
if (emu_thread == nullptr) { if (!emu_thread) [[unlikely]] {
status_bar_update_timer.stop(); status_bar_update_timer.stop();
return; return;
} }
// Update movie status // Update movie status
const u64 current = Core::Movie::GetInstance().GetCurrentInputIndex(); const u64 current = movie.GetCurrentInputIndex();
const u64 total = Core::Movie::GetInstance().GetTotalInputCount(); const u64 total = movie.GetTotalInputCount();
const auto play_mode = Core::Movie::GetInstance().GetPlayMode(); const auto play_mode = movie.GetPlayMode();
if (play_mode == Core::Movie::PlayMode::Recording) { if (play_mode == Core::Movie::PlayMode::Recording) {
message_label->setText(tr("Recording %1").arg(current)); message_label->setText(tr("Recording %1").arg(current));
message_label_used_for_movie = true; message_label_used_for_movie = true;
@ -2266,7 +2263,7 @@ void GMainWindow::UpdateStatusBar() {
ui->action_Save_Movie->setEnabled(false); ui->action_Save_Movie->setEnabled(false);
} }
auto results = Core::System::GetInstance().GetAndResetPerfStats(); auto results = system.GetAndResetPerfStats();
if (Settings::values.frame_limit.GetValue() == 0) { if (Settings::values.frame_limit.GetValue() == 0) {
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
@ -2295,7 +2292,7 @@ void GMainWindow::UpdateBootHomeMenuState() {
} }
void GMainWindow::HideMouseCursor() { void GMainWindow::HideMouseCursor() {
if (emu_thread == nullptr || !UISettings::values.hide_mouse.GetValue()) { if (!emu_thread || !UISettings::values.hide_mouse.GetValue()) {
mouse_hide_timer.stop(); mouse_hide_timer.stop();
ShowMouseCursor(); ShowMouseCursor();
return; return;
@ -2311,7 +2308,7 @@ void GMainWindow::ShowMouseCursor() {
unsetCursor(); unsetCursor();
render_window->unsetCursor(); render_window->unsetCursor();
secondary_window->unsetCursor(); secondary_window->unsetCursor();
if (emu_thread != nullptr && UISettings::values.hide_mouse) { if (emu_thread && UISettings::values.hide_mouse) {
mouse_hide_timer.start(); mouse_hide_timer.start();
} }
} }
@ -2406,8 +2403,9 @@ void GMainWindow::OnMenuAboutCitra() {
} }
bool GMainWindow::ConfirmClose() { bool GMainWindow::ConfirmClose() {
if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) if (!emu_thread || !UISettings::values.confirm_before_closing) {
return true; return true;
}
QMessageBox::StandardButton answer = QMessageBox::StandardButton answer =
QMessageBox::question(this, tr("Citra"), tr("Would you like to exit now?"), QMessageBox::question(this, tr("Citra"), tr("Would you like to exit now?"),
@ -2426,8 +2424,9 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
hotkey_registry.SaveHotkeys(); hotkey_registry.SaveHotkeys();
// Shutdown session if the emu thread is active... // Shutdown session if the emu thread is active...
if (emu_thread != nullptr) if (emu_thread) {
ShutdownGame(); ShutdownGame();
}
render_window->close(); render_window->close();
secondary_window->close(); secondary_window->close();
@ -2493,8 +2492,9 @@ void GMainWindow::dragMoveEvent(QDragMoveEvent* event) {
} }
bool GMainWindow::ConfirmChangeGame() { bool GMainWindow::ConfirmChangeGame() {
if (emu_thread == nullptr) if (!emu_thread) [[unlikely]] {
return true; return true;
}
auto answer = QMessageBox::question( auto answer = QMessageBox::question(
this, tr("Citra"), tr("The game is still running. Would you like to stop emulation?"), this, tr("Citra"), tr("The game is still running. Would you like to stop emulation?"),
@ -2584,13 +2584,11 @@ void GMainWindow::OnLanguageChanged(const QString& locale) {
void GMainWindow::OnConfigurePerGame() { void GMainWindow::OnConfigurePerGame() {
u64 title_id{}; u64 title_id{};
Core::System::GetInstance().GetAppLoader().ReadProgramId(title_id); system.GetAppLoader().ReadProgramId(title_id);
OpenPerGameConfiguration(title_id, game_path); OpenPerGameConfiguration(title_id, game_path);
} }
void GMainWindow::OpenPerGameConfiguration(u64 title_id, const QString& file_name) { void GMainWindow::OpenPerGameConfiguration(u64 title_id, const QString& file_name) {
Core::System& system = Core::System::GetInstance();
Settings::SetConfiguringGlobal(false); Settings::SetConfiguringGlobal(false);
ConfigurePerGame dialog(this, title_id, file_name, system); ConfigurePerGame dialog(this, title_id, file_name, system);
const auto result = dialog.exec(); const auto result = dialog.exec();
@ -2704,7 +2702,7 @@ static Qt::HighDpiScaleFactorRoundingPolicy GetHighDpiRoundingPolicy() {
// Get the current screen geometry. // Get the current screen geometry.
const QScreen* primary_screen = QGuiApplication::primaryScreen(); const QScreen* primary_screen = QGuiApplication::primaryScreen();
if (primary_screen == nullptr) { if (!primary_screen) {
return Qt::HighDpiScaleFactorRoundingPolicy::PassThrough; return Qt::HighDpiScaleFactorRoundingPolicy::PassThrough;
} }
@ -2760,12 +2758,12 @@ int main(int argc, char* argv[]) {
// generating shaders // generating shaders
setlocale(LC_ALL, "C"); setlocale(LC_ALL, "C");
GMainWindow main_window; Core::System& system = Core::System::GetInstance();
GMainWindow main_window(system);
// Register frontend applets // Register frontend applets
Frontend::RegisterDefaultApplets(); Frontend::RegisterDefaultApplets();
Core::System& system = Core::System::GetInstance();
system.RegisterMiiSelector(std::make_shared<QtMiiSelector>(main_window)); system.RegisterMiiSelector(std::make_shared<QtMiiSelector>(main_window));
system.RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window)); system.RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window));

View file

@ -11,7 +11,6 @@
#include <QTranslator> #include <QTranslator>
#include "citra_qt/compatibility_list.h" #include "citra_qt/compatibility_list.h"
#include "citra_qt/hotkeys.h" #include "citra_qt/hotkeys.h"
#include "common/announce_multiplayer_room.h"
#include "core/core.h" #include "core/core.h"
#include "core/savestate.h" #include "core/savestate.h"
@ -57,6 +56,10 @@ namespace DiscordRPC {
class DiscordInterface; class DiscordInterface;
} }
namespace Core {
class Movie;
}
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
} }
@ -83,7 +86,7 @@ public:
void filterBarSetChecked(bool state); void filterBarSetChecked(bool state);
void UpdateUITheme(); void UpdateUITheme();
GMainWindow(); explicit GMainWindow(Core::System& system);
~GMainWindow(); ~GMainWindow();
GameList* game_list; GameList* game_list;
@ -260,6 +263,8 @@ private:
void OpenPerGameConfiguration(u64 title_id, const QString& file_name); void OpenPerGameConfiguration(u64 title_id, const QString& file_name);
std::unique_ptr<Ui::MainWindow> ui; std::unique_ptr<Ui::MainWindow> ui;
Core::System& system;
Core::Movie& movie;
GRenderWindow* render_window; GRenderWindow* render_window;
GRenderWindow* secondary_window; GRenderWindow* secondary_window;

View file

@ -77,6 +77,7 @@ struct Values {
Settings::Setting<bool> show_status_bar{true, "showStatusBar"}; Settings::Setting<bool> show_status_bar{true, "showStatusBar"};
Settings::Setting<bool> confirm_before_closing{true, "confirmClose"}; Settings::Setting<bool> confirm_before_closing{true, "confirmClose"};
Settings::Setting<bool> save_state_warning{true, "saveStateWarning"};
Settings::Setting<bool> first_start{true, "firstStart"}; Settings::Setting<bool> first_start{true, "firstStart"};
Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"}; Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
Settings::Setting<bool> hide_mouse{false, "hideInactiveMouse"}; Settings::Setting<bool> hide_mouse{false, "hideInactiveMouse"};