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:
parent
52f88f8fb4
commit
5b7cc76ba3
6 changed files with 85 additions and 80 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -90,4 +90,4 @@ bool CheckAuthorizationForMicrophone() {
|
||||||
return authorized_microphone;
|
return authorized_microphone;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // AppleAuthorization
|
} // namespace AppleAuthorization
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"};
|
||||||
|
|
Loading…
Reference in a new issue