| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | // Copyright 2015 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2+
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 01:42:12 +02:00
										 |  |  | #include <QApplication>
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  | #include <QCloseEvent>
 | 
					
						
							| 
									
										
										
										
											2017-12-31 20:33:36 +01:00
										 |  |  | #include <QDateTime>
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | #include <QDir>
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:22:40 +02:00
										 |  |  | #include <QDragEnterEvent>
 | 
					
						
							|  |  |  | #include <QDropEvent>
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | #include <QFileDialog>
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:22:40 +02:00
										 |  |  | #include <QFileInfo>
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | #include <QIcon>
 | 
					
						
							|  |  |  | #include <QMessageBox>
 | 
					
						
							| 
									
										
										
										
											2017-06-26 23:22:40 +02:00
										 |  |  | #include <QMimeData>
 | 
					
						
							| 
									
										
										
										
											2017-08-24 17:38:31 +02:00
										 |  |  | #include <QProgressDialog>
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:20:59 -04:00
										 |  |  | #include <QStackedWidget>
 | 
					
						
							| 
									
										
										
										
											2018-03-21 11:13:53 +01:00
										 |  |  | #include <QVBoxLayout>
 | 
					
						
							| 
									
										
										
										
											2018-10-03 23:03:22 +10:00
										 |  |  | #include <QWindow>
 | 
					
						
							| 
									
										
										
										
											2017-08-24 17:38:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <future>
 | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  | #include <optional>
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 21:30:54 +02:00
										 |  |  | #if defined(__unix__) || defined(__unix) || defined(__APPLE__)
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "QtUtils/SignalDaemon.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 23:03:13 +10:00
										 |  |  | #ifndef WIN32
 | 
					
						
							|  |  |  | #include <qpa/qplatformnativeinterface.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-09 15:52:35 -04:00
										 |  |  | #include "Common/Version.h"
 | 
					
						
							| 
									
										
										
										
											2018-10-03 23:03:22 +10:00
										 |  |  | #include "Common/WindowSystemInfo.h"
 | 
					
						
							| 
									
										
										
										
											2017-06-05 12:36:30 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-27 15:43:40 +02:00
										 |  |  | #include "Core/Boot/Boot.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | #include "Core/BootManager.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-06 11:01:32 +02:00
										 |  |  | #include "Core/CommonTitles.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-06 18:29:46 -07:00
										 |  |  | #include "Core/Config/MainSettings.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | #include "Core/Config/NetplaySettings.h"
 | 
					
						
							| 
									
										
										
										
											2016-07-13 01:11:29 +00:00
										 |  |  | #include "Core/ConfigManager.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | #include "Core/Core.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-23 01:18:53 +01:00
										 |  |  | #include "Core/HW/DVD/DVDInterface.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-23 22:12:01 +02:00
										 |  |  | #include "Core/HW/GCKeyboard.h"
 | 
					
						
							|  |  |  | #include "Core/HW/GCPad.h"
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #include "Core/HW/ProcessorInterface.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-23 22:12:01 +02:00
										 |  |  | #include "Core/HW/Wiimote.h"
 | 
					
						
							|  |  |  | #include "Core/HW/WiimoteEmu/WiimoteEmu.h"
 | 
					
						
							|  |  |  | #include "Core/HotkeyManager.h"
 | 
					
						
							| 
									
										
										
										
											2018-01-24 15:25:35 +01:00
										 |  |  | #include "Core/IOS/USB/Bluetooth/BTEmu.h"
 | 
					
						
							|  |  |  | #include "Core/IOS/USB/Bluetooth/WiimoteDevice.h"
 | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | #include "Core/Movie.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | #include "Core/NetPlayClient.h"
 | 
					
						
							| 
									
										
										
										
											2017-05-09 18:49:10 +02:00
										 |  |  | #include "Core/NetPlayProto.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | #include "Core/NetPlayServer.h"
 | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | #include "Core/State.h"
 | 
					
						
							| 
									
										
										
										
											2016-05-09 06:34:07 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 17:38:31 +02:00
										 |  |  | #include "DiscIO/NANDImporter.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 00:40:15 +02:00
										 |  |  | #include "DolphinQt/AboutDialog.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/CheatsManager.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Config/ControllersWindow.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Config/Graphics/GraphicsWindow.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Config/LogConfigWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Config/LogWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Config/Mapping/MappingWindow.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Config/SettingsWindow.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Debugger/BreakpointWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Debugger/CodeViewWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Debugger/CodeWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Debugger/JITWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Debugger/MemoryWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Debugger/RegisterWidget.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Debugger/WatchWidget.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-03 17:50:08 -04:00
										 |  |  | #include "DolphinQt/DiscordHandler.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-07 00:40:15 +02:00
										 |  |  | #include "DolphinQt/FIFO/FIFOPlayerWindow.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/GCMemcardManager.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:20:59 -04:00
										 |  |  | #include "DolphinQt/GameList/GameList.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-07 00:40:15 +02:00
										 |  |  | #include "DolphinQt/Host.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/HotkeyScheduler.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/MainWindow.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:20:59 -04:00
										 |  |  | #include "DolphinQt/MenuBar.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-07 00:40:15 +02:00
										 |  |  | #include "DolphinQt/NetPlay/NetPlayDialog.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/NetPlay/NetPlaySetupDialog.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/QtUtils/QueueOnObject.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/QtUtils/RunOnObject.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/QtUtils/WindowActivationEventFilter.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:20:59 -04:00
										 |  |  | #include "DolphinQt/RenderWidget.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-07 00:40:15 +02:00
										 |  |  | #include "DolphinQt/Resources.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/SearchBar.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/Settings.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/TAS/GCTASInputWindow.h"
 | 
					
						
							|  |  |  | #include "DolphinQt/TAS/WiiTASInputWindow.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:20:59 -04:00
										 |  |  | #include "DolphinQt/ToolBar.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-07 00:40:15 +02:00
										 |  |  | #include "DolphinQt/WiiUpdate.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 22:12:01 +02:00
										 |  |  | #include "InputCommon/ControllerInterface/ControllerInterface.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-27 00:24:13 -04:00
										 |  |  | #include "UICommon/DiscordPresence.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-10 15:37:55 -04:00
										 |  |  | #include "UICommon/GameFile.h"
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  | #include "UICommon/UICommon.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 04:05:59 +02:00
										 |  |  | #include "VideoCommon/VideoConfig.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 01:42:12 +02:00
										 |  |  | #if defined(HAVE_XRANDR) && HAVE_XRANDR
 | 
					
						
							|  |  |  | #include "UICommon/X11Utils.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 21:30:54 +02:00
										 |  |  | #if defined(__unix__) || defined(__unix) || defined(__APPLE__)
 | 
					
						
							|  |  |  | void MainWindow::OnSignal() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   close(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void InstallSignalHandler() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct sigaction sa; | 
					
						
							|  |  |  |   sa.sa_handler = &SignalDaemon::HandleInterrupt; | 
					
						
							|  |  |  |   sigemptyset(&sa.sa_mask); | 
					
						
							|  |  |  |   sa.sa_flags = SA_RESETHAND; | 
					
						
							|  |  |  |   sigaction(SIGINT, &sa, nullptr); | 
					
						
							|  |  |  |   sigaction(SIGTERM, &sa, nullptr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 23:03:22 +10:00
										 |  |  | static WindowSystemType GetWindowSystemType() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // Determine WSI type based on Qt platform.
 | 
					
						
							|  |  |  |   QString platform_name = QGuiApplication::platformName(); | 
					
						
							|  |  |  |   if (platform_name == QStringLiteral("windows")) | 
					
						
							|  |  |  |     return WindowSystemType::Windows; | 
					
						
							|  |  |  |   else if (platform_name == QStringLiteral("cocoa")) | 
					
						
							|  |  |  |     return WindowSystemType::MacOS; | 
					
						
							|  |  |  |   else if (platform_name == QStringLiteral("xcb")) | 
					
						
							|  |  |  |     return WindowSystemType::X11; | 
					
						
							|  |  |  |   else if (platform_name == QStringLiteral("wayland")) | 
					
						
							|  |  |  |     return WindowSystemType::Wayland; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   QMessageBox::critical( | 
					
						
							|  |  |  |       nullptr, QStringLiteral("Error"), | 
					
						
							|  |  |  |       QString::asprintf("Unknown Qt platform: %s", platform_name.toStdString().c_str())); | 
					
						
							|  |  |  |   return WindowSystemType::Headless; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static WindowSystemInfo GetWindowSystemInfo(QWindow* window) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   WindowSystemInfo wsi; | 
					
						
							|  |  |  |   wsi.type = GetWindowSystemType(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Our Win32 Qt external doesn't have the private API.
 | 
					
						
							|  |  |  | #if defined(WIN32) || defined(__APPLE__)
 | 
					
						
							|  |  |  |   wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); | 
					
						
							|  |  |  |   wsi.display_connection = pni->nativeResourceForWindow("display", window); | 
					
						
							|  |  |  |   if (wsi.type == WindowSystemType::Wayland) | 
					
						
							|  |  |  |     wsi.render_surface = window ? pni->nativeResourceForWindow("surface", window) : nullptr; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     wsi.render_surface = window ? reinterpret_cast<void*>(window->winId()) : nullptr; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return wsi; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-02 00:09:07 +02:00
										 |  |  | MainWindow::MainWindow(std::unique_ptr<BootParameters> boot_parameters) : QMainWindow(nullptr) | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-09 15:52:35 -04:00
										 |  |  |   setWindowTitle(QString::fromStdString(Common::scm_rev_str)); | 
					
						
							| 
									
										
										
										
											2018-03-26 08:13:15 +02:00
										 |  |  |   setWindowIcon(Resources::GetAppIcon()); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   setUnifiedTitleAndToolBarOnMac(true); | 
					
						
							| 
									
										
										
										
											2017-06-26 23:22:40 +02:00
										 |  |  |   setAcceptDrops(true); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-03 14:31:17 -07:00
										 |  |  |   InitControllers(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   CreateComponents(); | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   ConnectGameList(); | 
					
						
							| 
									
										
										
										
											2018-03-24 02:13:56 +01:00
										 |  |  |   ConnectHost(); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   ConnectToolBar(); | 
					
						
							|  |  |  |   ConnectRenderWidget(); | 
					
						
							|  |  |  |   ConnectStack(); | 
					
						
							|  |  |  |   ConnectMenuBar(); | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  |   ConnectHotkeys(); | 
					
						
							| 
									
										
										
										
											2017-05-23 22:12:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 15:27:00 +02:00
										 |  |  |   InitCoreCallbacks(); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   NetPlayInit(); | 
					
						
							| 
									
										
										
										
											2017-10-02 00:09:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 21:30:54 +02:00
										 |  |  | #if defined(__unix__) || defined(__unix) || defined(__APPLE__)
 | 
					
						
							|  |  |  |   auto* daemon = new SignalDaemon(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   connect(daemon, &SignalDaemon::InterruptReceived, this, &MainWindow::OnSignal); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   InstallSignalHandler(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-02 00:09:07 +02:00
										 |  |  |   if (boot_parameters) | 
					
						
							| 
									
										
										
										
											2018-05-13 15:03:48 +02:00
										 |  |  |     m_pending_boot = std::move(boot_parameters); | 
					
						
							| 
									
										
										
										
											2018-04-19 11:32:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   QSettings& settings = Settings::GetQSettings(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   restoreState(settings.value(QStringLiteral("mainwindow/state")).toByteArray()); | 
					
						
							| 
									
										
										
										
											2018-05-10 17:24:50 +02:00
										 |  |  |   restoreGeometry(settings.value(QStringLiteral("mainwindow/geometry")).toByteArray()); | 
					
						
							| 
									
										
										
										
											2018-05-08 16:00:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-13 00:59:09 +02:00
										 |  |  |   m_render_widget_geometry = settings.value(QStringLiteral("renderwidget/geometry")).toByteArray(); | 
					
						
							| 
									
										
										
										
											2018-08-20 00:39:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Restoring of window states can sometimes go wrong, resulting in widgets being visible when they
 | 
					
						
							|  |  |  |   // shouldn't be so we have to reapply all our rules afterwards.
 | 
					
						
							|  |  |  |   Settings::Instance().RefreshWidgetVisibility(); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-14 17:04:16 -08:00
										 |  |  | MainWindow::~MainWindow() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_render_widget->deleteLater(); | 
					
						
							| 
									
										
										
										
											2018-07-04 16:41:56 -04:00
										 |  |  |   m_netplay_dialog->deleteLater(); | 
					
						
							| 
									
										
										
										
											2018-08-13 14:15:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (int i = 0; i < 4; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_gc_tas_input_windows[i]->deleteLater(); | 
					
						
							|  |  |  |     m_wii_tas_input_windows[i]->deleteLater(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-31 21:11:54 -07:00
										 |  |  |   ShutdownControllers(); | 
					
						
							| 
									
										
										
										
											2017-09-13 19:33:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-19 11:32:00 +02:00
										 |  |  |   QSettings& settings = Settings::GetQSettings(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   settings.setValue(QStringLiteral("mainwindow/state"), saveState()); | 
					
						
							| 
									
										
										
										
											2018-05-10 17:24:50 +02:00
										 |  |  |   settings.setValue(QStringLiteral("mainwindow/geometry"), saveGeometry()); | 
					
						
							| 
									
										
										
										
											2018-05-08 16:00:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-13 00:59:09 +02:00
										 |  |  |   settings.setValue(QStringLiteral("renderwidget/geometry"), m_render_widget_geometry); | 
					
						
							| 
									
										
										
										
											2018-05-10 12:05:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Config::Save(); | 
					
						
							| 
									
										
										
										
											2016-02-14 17:04:16 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-23 22:12:01 +02:00
										 |  |  | void MainWindow::InitControllers() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (g_controller_interface.IsInit()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_controller_interface.Initialize(reinterpret_cast<void*>(winId())); | 
					
						
							|  |  |  |   Pad::Initialize(); | 
					
						
							|  |  |  |   Keyboard::Initialize(); | 
					
						
							|  |  |  |   Wiimote::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   m_hotkey_scheduler = new HotkeyScheduler(); | 
					
						
							|  |  |  |   m_hotkey_scheduler->Start(); | 
					
						
							| 
									
										
										
										
											2018-05-12 01:31:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Defaults won't work reliabily without loading and saving the config first
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Wiimote::LoadConfig(); | 
					
						
							|  |  |  |   Wiimote::GetConfig()->SaveConfig(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Pad::LoadConfig(); | 
					
						
							|  |  |  |   Pad::GetConfig()->SaveConfig(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Keyboard::LoadConfig(); | 
					
						
							|  |  |  |   Keyboard::GetConfig()->SaveConfig(); | 
					
						
							| 
									
										
										
										
											2017-05-23 22:12:01 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-31 21:11:54 -07:00
										 |  |  | void MainWindow::ShutdownControllers() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   m_hotkey_scheduler->Stop(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-31 21:11:54 -07:00
										 |  |  |   g_controller_interface.Shutdown(); | 
					
						
							|  |  |  |   Pad::Shutdown(); | 
					
						
							|  |  |  |   Keyboard::Shutdown(); | 
					
						
							|  |  |  |   Wiimote::Shutdown(); | 
					
						
							|  |  |  |   HotkeyManagerEmu::Shutdown(); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   m_hotkey_scheduler->deleteLater(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 15:27:00 +02:00
										 |  |  | void MainWindow::InitCoreCallbacks() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-04 11:12:13 -07:00
										 |  |  |   connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [=](Core::State state) { | 
					
						
							| 
									
										
										
										
											2017-09-04 10:57:42 -07:00
										 |  |  |     if (state == Core::State::Uninitialized) | 
					
						
							| 
									
										
										
										
											2017-09-04 11:12:13 -07:00
										 |  |  |       OnStopComplete(); | 
					
						
							| 
									
										
										
										
											2018-06-08 19:59:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (state == Core::State::Running && m_fullscreen_requested) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       FullScreen(); | 
					
						
							|  |  |  |       m_fullscreen_requested = false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-04 10:57:42 -07:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |   installEventFilter(this); | 
					
						
							|  |  |  |   m_render_widget->installEventFilter(this); | 
					
						
							| 
									
										
										
										
											2017-06-16 15:27:00 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 18:49:56 -07:00
										 |  |  | static void InstallHotkeyFilter(QWidget* dialog) | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-14 18:49:56 -07:00
										 |  |  |   auto* filter = new WindowActivationEventFilter(); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   dialog->installEventFilter(filter); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 18:49:56 -07:00
										 |  |  |   filter->connect(filter, &WindowActivationEventFilter::windowDeactivated, | 
					
						
							|  |  |  |                   [] { HotkeyManagerEmu::Enable(true); }); | 
					
						
							|  |  |  |   filter->connect(filter, &WindowActivationEventFilter::windowActivated, | 
					
						
							|  |  |  |                   [] { HotkeyManagerEmu::Enable(false); }); | 
					
						
							| 
									
										
										
										
											2017-05-31 21:11:54 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | void MainWindow::CreateComponents() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_menu_bar = new MenuBar(this); | 
					
						
							|  |  |  |   m_tool_bar = new ToolBar(this); | 
					
						
							| 
									
										
										
										
											2018-03-21 11:13:53 +01:00
										 |  |  |   m_search_bar = new SearchBar(this); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_game_list = new GameList(this); | 
					
						
							|  |  |  |   m_render_widget = new RenderWidget; | 
					
						
							|  |  |  |   m_stack = new QStackedWidget(this); | 
					
						
							| 
									
										
										
										
											2017-08-30 16:44:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-31 22:35:09 +11:00
										 |  |  |   for (int i = 0; i < 4; i++) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-08-13 14:15:09 +02:00
										 |  |  |     m_gc_tas_input_windows[i] = new GCTASInputWindow(nullptr, i); | 
					
						
							|  |  |  |     m_wii_tas_input_windows[i] = new WiiTASInputWindow(nullptr, i); | 
					
						
							| 
									
										
										
										
											2018-01-31 22:35:09 +11:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-28 00:35:02 +11:00
										 |  |  |   Movie::SetGCInputManip([this](GCPadStatus* pad_status, int controller_id) { | 
					
						
							|  |  |  |     m_gc_tas_input_windows[controller_id]->GetValues(pad_status); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-31 22:35:09 +11:00
										 |  |  |   Movie::SetWiiInputManip([this](u8* input_data, WiimoteEmu::ReportFeatures rptf, int controller_id, | 
					
						
							|  |  |  |                                  int ext, wiimote_key key) { | 
					
						
							|  |  |  |     m_wii_tas_input_windows[controller_id]->GetValues(input_data, rptf, ext, key); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-01-28 00:35:02 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-09 15:31:20 +02:00
										 |  |  |   m_jit_widget = new JITWidget(this); | 
					
						
							| 
									
										
										
										
											2017-08-28 00:10:06 +02:00
										 |  |  |   m_log_widget = new LogWidget(this); | 
					
						
							|  |  |  |   m_log_config_widget = new LogConfigWidget(this); | 
					
						
							| 
									
										
										
										
											2018-03-16 12:39:53 +01:00
										 |  |  |   m_memory_widget = new MemoryWidget(this); | 
					
						
							| 
									
										
										
										
											2017-09-13 19:33:45 +02:00
										 |  |  |   m_register_widget = new RegisterWidget(this); | 
					
						
							| 
									
										
										
										
											2017-09-27 08:53:05 +02:00
										 |  |  |   m_watch_widget = new WatchWidget(this); | 
					
						
							| 
									
										
										
										
											2017-10-03 18:43:44 +02:00
										 |  |  |   m_breakpoint_widget = new BreakpointWidget(this); | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  |   m_code_widget = new CodeWidget(this); | 
					
						
							| 
									
										
										
										
											2018-03-26 04:17:47 +02:00
										 |  |  |   m_cheats_manager = new CheatsManager(this); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-19 18:50:38 +01:00
										 |  |  |   connect(m_watch_widget, &WatchWidget::RequestMemoryBreakpoint, | 
					
						
							|  |  |  |           [this](u32 addr) { m_breakpoint_widget->AddAddressMBP(addr); }); | 
					
						
							|  |  |  |   connect(m_register_widget, &RegisterWidget::RequestMemoryBreakpoint, | 
					
						
							|  |  |  |           [this](u32 addr) { m_breakpoint_widget->AddAddressMBP(addr); }); | 
					
						
							| 
									
										
										
										
											2018-03-16 12:39:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  |   connect(m_code_widget, &CodeWidget::BreakpointsChanged, m_breakpoint_widget, | 
					
						
							|  |  |  |           &BreakpointWidget::Update); | 
					
						
							| 
									
										
										
										
											2018-04-09 15:31:20 +02:00
										 |  |  |   connect(m_code_widget, &CodeWidget::RequestPPCComparison, m_jit_widget, &JITWidget::Compare); | 
					
						
							| 
									
										
										
										
											2018-03-16 12:39:53 +01:00
										 |  |  |   connect(m_memory_widget, &MemoryWidget::BreakpointsChanged, m_breakpoint_widget, | 
					
						
							|  |  |  |           &BreakpointWidget::Update); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   connect(m_breakpoint_widget, &BreakpointWidget::BreakpointsChanged, m_code_widget, | 
					
						
							|  |  |  |           &CodeWidget::Update); | 
					
						
							|  |  |  |   connect(m_breakpoint_widget, &BreakpointWidget::BreakpointsChanged, m_memory_widget, | 
					
						
							|  |  |  |           &MemoryWidget::Update); | 
					
						
							| 
									
										
										
										
											2018-05-05 22:55:10 -04:00
										 |  |  |   connect(m_breakpoint_widget, &BreakpointWidget::SelectedBreakpoint, [this](u32 address) { | 
					
						
							|  |  |  |     if (Core::GetState() == Core::State::Paused) | 
					
						
							|  |  |  |       m_code_widget->SetAddress(address, CodeViewWidget::SetAddressUpdate::WithUpdate); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | void MainWindow::ConnectMenuBar() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   setMenuBar(m_menu_bar); | 
					
						
							|  |  |  |   // File
 | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::Open, this, &MainWindow::Open); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::Exit, this, &MainWindow::close); | 
					
						
							| 
									
										
										
										
											2018-03-23 01:18:53 +01:00
										 |  |  |   connect(m_menu_bar, &MenuBar::EjectDisc, this, &MainWindow::EjectDisc); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::ChangeDisc, this, &MainWindow::ChangeDisc); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::BootDVDBackup, this, | 
					
						
							|  |  |  |           [this](const QString& drive) { StartGame(drive); }); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Emulation
 | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::Pause, this, &MainWindow::Pause); | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |   connect(m_menu_bar, &MenuBar::Play, this, [this]() { Play(); }); | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::Stop, this, &MainWindow::RequestStop); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::Reset, this, &MainWindow::Reset); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::Fullscreen, this, &MainWindow::FullScreen); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::FrameAdvance, this, &MainWindow::FrameAdvance); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::Screenshot, this, &MainWindow::ScreenShot); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateLoad, this, &MainWindow::StateLoad); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateSave, this, &MainWindow::StateSave); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateLoadSlot, this, &MainWindow::StateLoadSlot); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateSaveSlot, this, &MainWindow::StateSaveSlot); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateLoadSlotAt, this, &MainWindow::StateLoadSlotAt); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateSaveSlotAt, this, &MainWindow::StateSaveSlotAt); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateLoadUndo, this, &MainWindow::StateLoadUndo); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateSaveUndo, this, &MainWindow::StateSaveUndo); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StateSaveOldest, this, &MainWindow::StateSaveOldest); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::SetStateSlot, this, &MainWindow::SetStateSlot); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   // Options
 | 
					
						
							| 
									
										
										
										
											2017-07-16 14:11:11 -07:00
										 |  |  |   connect(m_menu_bar, &MenuBar::Configure, this, &MainWindow::ShowSettingsWindow); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::ConfigureGraphics, this, &MainWindow::ShowGraphicsWindow); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::ConfigureAudio, this, &MainWindow::ShowAudioWindow); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::ConfigureControllers, this, &MainWindow::ShowControllersWindow); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ConfigureHotkeys, this, &MainWindow::ShowHotkeyDialog); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 11:58:11 +02:00
										 |  |  |   // Tools
 | 
					
						
							| 
									
										
										
										
											2018-01-25 19:54:50 +01:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ShowMemcardManager, this, &MainWindow::ShowMemcardManager); | 
					
						
							| 
									
										
										
										
											2018-03-26 04:17:47 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ShowCheatsManager, this, &MainWindow::ShowCheatsManager); | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::BootGameCubeIPL, this, &MainWindow::OnBootGameCubeIPL); | 
					
						
							| 
									
										
										
										
											2017-08-24 17:38:31 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ImportNANDBackup, this, &MainWindow::OnImportNANDBackup); | 
					
						
							| 
									
										
										
										
											2017-06-14 11:58:11 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::PerformOnlineUpdate, this, &MainWindow::PerformOnlineUpdate); | 
					
						
							| 
									
										
										
										
											2017-07-06 11:01:32 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::BootWiiSystemMenu, this, &MainWindow::BootWiiSystemMenu); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::StartNetPlay, this, &MainWindow::ShowNetPlaySetupDialog); | 
					
						
							| 
									
										
										
										
											2017-08-30 16:44:28 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ShowFIFOPlayer, this, &MainWindow::ShowFIFOPlayer); | 
					
						
							| 
									
										
										
										
											2018-01-24 15:25:35 +01:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ConnectWiiRemote, this, &MainWindow::OnConnectWiiRemote); | 
					
						
							| 
									
										
										
										
											2017-06-14 11:58:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |   // Movie
 | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::PlayRecording, this, &MainWindow::OnPlayRecording); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StartRecording, this, &MainWindow::OnStartRecording); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::StopRecording, this, &MainWindow::OnStopRecording); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::ExportRecording, this, &MainWindow::OnExportRecording); | 
					
						
							| 
									
										
										
										
											2018-01-28 00:35:02 +11:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ShowTASInput, this, &MainWindow::ShowTASInput); | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // View
 | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::ShowList, m_game_list, &GameList::SetListView); | 
					
						
							| 
									
										
										
										
											2017-08-05 10:28:53 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ShowGrid, m_game_list, &GameList::SetGridView); | 
					
						
							| 
									
										
										
										
											2018-10-14 18:03:10 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::PurgeGameListCache, m_game_list, &GameList::PurgeCache); | 
					
						
							| 
									
										
										
										
											2018-03-21 11:13:53 +01:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ToggleSearch, m_search_bar, &SearchBar::Toggle); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 19:03:59 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ColumnVisibilityToggled, m_game_list, | 
					
						
							|  |  |  |           &GameList::OnColumnVisibilityToggled); | 
					
						
							| 
									
										
										
										
											2017-06-25 19:40:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-11 15:13:09 +01:00
										 |  |  |   connect(m_menu_bar, &MenuBar::GameListPlatformVisibilityToggled, m_game_list, | 
					
						
							|  |  |  |           &GameList::OnGameListVisibilityChanged); | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::GameListRegionVisibilityToggled, m_game_list, | 
					
						
							|  |  |  |           &GameList::OnGameListVisibilityChanged); | 
					
						
							| 
									
										
										
										
											2017-06-25 19:40:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   connect(m_menu_bar, &MenuBar::ShowAboutDialog, this, &MainWindow::ShowAboutDialog); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |   connect(m_game_list, &GameList::SelectionChanged, m_menu_bar, &MenuBar::SelectionChanged); | 
					
						
							|  |  |  |   connect(this, &MainWindow::ReadOnlyModeChanged, m_menu_bar, &MenuBar::ReadOnlyModeChanged); | 
					
						
							|  |  |  |   connect(this, &MainWindow::RecordingStatusChanged, m_menu_bar, &MenuBar::RecordingStatusChanged); | 
					
						
							| 
									
										
										
										
											2018-05-11 16:38:32 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Symbols
 | 
					
						
							|  |  |  |   connect(m_menu_bar, &MenuBar::NotifySymbolsUpdated, [this] { | 
					
						
							|  |  |  |     m_code_widget->UpdateSymbols(); | 
					
						
							|  |  |  |     m_code_widget->Update(); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  | void MainWindow::ConnectHotkeys() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-09 08:27:04 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::Open, this, &MainWindow::Open); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ChangeDisc, this, &MainWindow::ChangeDisc); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::EjectDisc, this, &MainWindow::EjectDisc); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ExitHotkey, this, &MainWindow::close); | 
					
						
							| 
									
										
										
										
											2018-02-09 22:54:35 +11:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::TogglePauseHotkey, this, &MainWindow::TogglePause); | 
					
						
							| 
									
										
										
										
											2018-06-06 18:28:51 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::RefreshGameListHotkey, this, | 
					
						
							|  |  |  |           &MainWindow::RefreshGameList); | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StopHotkey, this, &MainWindow::RequestStop); | 
					
						
							| 
									
										
										
										
											2018-05-12 03:56:10 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ResetHotkey, this, &MainWindow::Reset); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ScreenShotHotkey, this, &MainWindow::ScreenShot); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::FullScreenHotkey, this, &MainWindow::FullScreen); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 20:27:14 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadSlot, this, &MainWindow::StateLoadSlotAt); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveSlot, this, &MainWindow::StateSaveSlotAt); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadLastSaved, this, | 
					
						
							|  |  |  |           &MainWindow::StateLoadLastSavedAt); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadUndo, this, &MainWindow::StateLoadUndo); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveUndo, this, &MainWindow::StateSaveUndo); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveOldest, this, | 
					
						
							|  |  |  |           &MainWindow::StateSaveOldest); | 
					
						
							| 
									
										
										
										
											2018-07-01 16:14:29 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveFile, this, &MainWindow::StateSave); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadFile, this, &MainWindow::StateLoad); | 
					
						
							| 
									
										
										
										
											2018-05-17 20:27:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadSlotHotkey, this, | 
					
						
							|  |  |  |           &MainWindow::StateLoadSlot); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveSlotHotkey, this, | 
					
						
							|  |  |  |           &MainWindow::StateSaveSlot); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::SetStateSlotHotkey, this, | 
					
						
							|  |  |  |           &MainWindow::SetStateSlot); | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StartRecording, this, | 
					
						
							|  |  |  |           &MainWindow::OnStartRecording); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ExportRecording, this, | 
					
						
							|  |  |  |           &MainWindow::OnExportRecording); | 
					
						
							| 
									
										
										
										
											2018-01-24 15:25:35 +01:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ConnectWiiRemote, this, | 
					
						
							|  |  |  |           &MainWindow::OnConnectWiiRemote); | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleReadOnlyMode, [this] { | 
					
						
							|  |  |  |     bool read_only = !Movie::IsReadOnly(); | 
					
						
							|  |  |  |     Movie::SetReadOnly(read_only); | 
					
						
							|  |  |  |     emit ReadOnlyModeChanged(read_only); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::Step, m_code_widget, &CodeWidget::Step); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StepOver, m_code_widget, &CodeWidget::StepOver); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::StepOut, m_code_widget, &CodeWidget::StepOut); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::Skip, m_code_widget, &CodeWidget::Skip); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ShowPC, m_code_widget, &CodeWidget::ShowPC); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::SetPC, m_code_widget, &CodeWidget::SetPC); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::ToggleBreakpoint, m_code_widget, | 
					
						
							|  |  |  |           &CodeWidget::ToggleBreakpoint); | 
					
						
							|  |  |  |   connect(m_hotkey_scheduler, &HotkeyScheduler::AddBreakpoint, m_code_widget, | 
					
						
							|  |  |  |           &CodeWidget::AddBreakpoint); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | void MainWindow::ConnectToolBar() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   addToolBar(m_tool_bar); | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::OpenPressed, this, &MainWindow::Open); | 
					
						
							| 
									
										
										
										
											2018-06-04 21:44:46 +02:00
										 |  |  |   connect(m_tool_bar, &ToolBar::RefreshPressed, this, &MainWindow::RefreshGameList); | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |   connect(m_tool_bar, &ToolBar::PlayPressed, this, [this]() { Play(); }); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   connect(m_tool_bar, &ToolBar::PausePressed, this, &MainWindow::Pause); | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   connect(m_tool_bar, &ToolBar::StopPressed, this, &MainWindow::RequestStop); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   connect(m_tool_bar, &ToolBar::FullScreenPressed, this, &MainWindow::FullScreen); | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::ScreenShotPressed, this, &MainWindow::ScreenShot); | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::SettingsPressed, this, &MainWindow::ShowSettingsWindow); | 
					
						
							| 
									
										
										
										
											2017-05-09 18:49:10 +02:00
										 |  |  |   connect(m_tool_bar, &ToolBar::ControllersPressed, this, &MainWindow::ShowControllersWindow); | 
					
						
							| 
									
										
										
										
											2017-06-16 01:42:12 +02:00
										 |  |  |   connect(m_tool_bar, &ToolBar::GraphicsPressed, this, &MainWindow::ShowGraphicsWindow); | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::StepPressed, m_code_widget, &CodeWidget::Step); | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::StepOverPressed, m_code_widget, &CodeWidget::StepOver); | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::StepOutPressed, m_code_widget, &CodeWidget::StepOut); | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::SkipPressed, m_code_widget, &CodeWidget::Skip); | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::ShowPCPressed, m_code_widget, &CodeWidget::ShowPC); | 
					
						
							|  |  |  |   connect(m_tool_bar, &ToolBar::SetPCPressed, m_code_widget, &CodeWidget::SetPC); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | void MainWindow::ConnectGameList() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |   connect(m_game_list, &GameList::GameSelected, this, [this]() { Play(); }); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   connect(m_game_list, &GameList::NetPlayHost, this, &MainWindow::NetPlayHost); | 
					
						
							| 
									
										
										
										
											2017-09-10 19:10:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   connect(m_game_list, &GameList::OpenGeneralSettings, this, &MainWindow::ShowGeneralWindow); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | void MainWindow::ConnectRenderWidget() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_rendering_to_main = false; | 
					
						
							|  |  |  |   m_render_widget->hide(); | 
					
						
							|  |  |  |   connect(m_render_widget, &RenderWidget::Closed, this, &MainWindow::ForceStop); | 
					
						
							| 
									
										
										
										
											2018-06-08 20:47:15 +02:00
										 |  |  |   connect(m_render_widget, &RenderWidget::FocusChanged, this, [this](bool focus) { | 
					
						
							|  |  |  |     if (m_render_widget->isFullScreen()) | 
					
						
							|  |  |  |       SetFullScreenResolution(focus); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-24 02:13:56 +01:00
										 |  |  | void MainWindow::ConnectHost() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   connect(Host::GetInstance(), &Host::UpdateProgressDialog, this, | 
					
						
							|  |  |  |           &MainWindow::OnUpdateProgressDialog); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | void MainWindow::ConnectStack() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-21 11:13:53 +01:00
										 |  |  |   auto* widget = new QWidget; | 
					
						
							|  |  |  |   auto* layout = new QVBoxLayout; | 
					
						
							|  |  |  |   widget->setLayout(layout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   layout->addWidget(m_game_list); | 
					
						
							|  |  |  |   layout->addWidget(m_search_bar); | 
					
						
							| 
									
										
										
										
											2018-03-21 22:48:17 +01:00
										 |  |  |   layout->setMargin(0); | 
					
						
							| 
									
										
										
										
											2018-03-21 11:13:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   connect(m_search_bar, &SearchBar::Search, m_game_list, &GameList::SetSearchTerm); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_stack->addWidget(widget); | 
					
						
							| 
									
										
										
										
											2017-06-25 19:40:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   setCentralWidget(m_stack); | 
					
						
							| 
									
										
										
										
											2017-08-28 00:10:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   setTabPosition(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea, QTabWidget::North); | 
					
						
							| 
									
										
										
										
											2018-05-04 22:37:25 -04:00
										 |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_log_widget); | 
					
						
							|  |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_log_config_widget); | 
					
						
							|  |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_code_widget); | 
					
						
							|  |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_register_widget); | 
					
						
							|  |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_watch_widget); | 
					
						
							|  |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_breakpoint_widget); | 
					
						
							|  |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_memory_widget); | 
					
						
							|  |  |  |   addDockWidget(Qt::LeftDockWidgetArea, m_jit_widget); | 
					
						
							| 
									
										
										
										
											2017-08-28 00:10:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   tabifyDockWidget(m_log_widget, m_log_config_widget); | 
					
						
							| 
									
										
										
										
											2018-02-14 23:25:01 +01:00
										 |  |  |   tabifyDockWidget(m_log_widget, m_code_widget); | 
					
						
							| 
									
										
										
										
											2017-09-13 19:33:45 +02:00
										 |  |  |   tabifyDockWidget(m_log_widget, m_register_widget); | 
					
						
							| 
									
										
										
										
											2017-09-27 08:53:05 +02:00
										 |  |  |   tabifyDockWidget(m_log_widget, m_watch_widget); | 
					
						
							| 
									
										
										
										
											2017-10-03 18:43:44 +02:00
										 |  |  |   tabifyDockWidget(m_log_widget, m_breakpoint_widget); | 
					
						
							| 
									
										
										
										
											2018-03-16 12:39:53 +01:00
										 |  |  |   tabifyDockWidget(m_log_widget, m_memory_widget); | 
					
						
							| 
									
										
										
										
											2018-04-09 15:31:20 +02:00
										 |  |  |   tabifyDockWidget(m_log_widget, m_jit_widget); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-04 21:44:46 +02:00
										 |  |  | void MainWindow::RefreshGameList() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Settings::Instance().ReloadTitleDB(); | 
					
						
							| 
									
										
										
										
											2018-07-06 20:27:07 +02:00
										 |  |  |   Settings::Instance().RefreshGameList(); | 
					
						
							| 
									
										
										
										
											2018-06-04 21:44:46 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 01:18:53 +01:00
										 |  |  | QString MainWindow::PromptFileName() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-05 13:19:44 +02:00
										 |  |  |   auto& settings = Settings::Instance().GetQSettings(); | 
					
						
							|  |  |  |   QString path = QFileDialog::getOpenFileName( | 
					
						
							|  |  |  |       this, tr("Select a File"), | 
					
						
							|  |  |  |       settings.value(QStringLiteral("mainwindow/lastdir"), QStringLiteral("")).toString(), | 
					
						
							| 
									
										
										
										
											2018-08-03 17:39:17 +10:00
										 |  |  |       tr("All GC/Wii files (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wad *.dff);;" | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |          "All Files (*)")); | 
					
						
							| 
									
										
										
										
											2018-06-05 13:19:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!path.isEmpty()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     settings.setValue(QStringLiteral("mainwindow/lastdir"), | 
					
						
							|  |  |  |                       QFileInfo(path).absoluteDir().absolutePath()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return path; | 
					
						
							| 
									
										
										
										
											2018-03-23 01:18:53 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::ChangeDisc() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   QString file = PromptFileName(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!file.isEmpty()) | 
					
						
							|  |  |  |     Core::RunAsCPUThread([&file] { DVDInterface::ChangeDisc(file.toStdString()); }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::EjectDisc() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Core::RunAsCPUThread(DVDInterface::EjectDisc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::Open() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   QString file = PromptFileName(); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (!file.isEmpty()) | 
					
						
							|  |  |  |     StartGame(file); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  | void MainWindow::Play(const std::optional<std::string>& savestate_path) | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // If we're in a paused game, start it up again.
 | 
					
						
							|  |  |  |   // Otherwise, play the selected game, if there is one.
 | 
					
						
							|  |  |  |   // Otherwise, play the default game.
 | 
					
						
							|  |  |  |   // Otherwise, play the last played game, if there is one.
 | 
					
						
							|  |  |  |   // Otherwise, prompt for a new game.
 | 
					
						
							| 
									
										
										
										
											2017-02-05 07:39:58 -05:00
										 |  |  |   if (Core::GetState() == Core::State::Paused) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:39:58 -05:00
										 |  |  |     Core::SetState(Core::State::Running); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-12-31 20:33:36 +01:00
										 |  |  |     std::shared_ptr<const UICommon::GameFile> selection = m_game_list->GetSelectedGame(); | 
					
						
							| 
									
										
										
										
											2017-12-25 18:41:53 +01:00
										 |  |  |     if (selection) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |       StartGame(selection->GetFilePath(), savestate_path); | 
					
						
							| 
									
										
										
										
											2018-01-01 21:15:26 +00:00
										 |  |  |       EnableScreenSaver(false); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-07-06 18:29:46 -07:00
										 |  |  |       const QString default_path = QString::fromStdString(Config::Get(Config::MAIN_DEFAULT_ISO)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       if (!default_path.isEmpty() && QFile::exists(default_path)) | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |         StartGame(default_path, savestate_path); | 
					
						
							| 
									
										
										
										
											2018-01-01 21:15:26 +00:00
										 |  |  |         EnableScreenSaver(false); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2017-06-04 14:43:41 -06:00
										 |  |  |         Open(); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::Pause() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-02-05 07:39:58 -05:00
										 |  |  |   Core::SetState(Core::State::Paused); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-09 22:54:35 +11:00
										 |  |  | void MainWindow::TogglePause() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (Core::GetState() == Core::State::Paused) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Play(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Pause(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  | void MainWindow::OnStopComplete() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   m_stop_requested = false; | 
					
						
							| 
									
										
										
										
											2017-09-15 22:39:55 +02:00
										 |  |  |   HideRenderWidget(); | 
					
						
							| 
									
										
										
										
											2018-05-16 23:16:01 -04:00
										 |  |  |   EnableScreenSaver(true); | 
					
						
							| 
									
										
										
										
											2018-05-29 23:44:20 -04:00
										 |  |  | #ifdef USE_DISCORD_PRESENCE
 | 
					
						
							| 
									
										
										
										
											2018-08-06 17:56:40 -04:00
										 |  |  |   if (!m_netplay_dialog->isVisible()) | 
					
						
							|  |  |  |     Discord::UpdateDiscordPresence(); | 
					
						
							| 
									
										
										
										
											2018-05-29 23:44:20 -04:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 18:38:59 +02:00
										 |  |  |   SetFullScreenResolution(false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-29 19:13:40 +02:00
										 |  |  |   if (m_exit_requested || Settings::Instance().IsBatchModeEnabled()) | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |     QGuiApplication::instance()->quit(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // If the current emulation prevented the booting of another, do that now
 | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  |   if (m_pending_boot != nullptr) | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  |     StartGame(std::move(m_pending_boot)); | 
					
						
							|  |  |  |     m_pending_boot.reset(); | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MainWindow::RequestStop() | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |   if (!Core::IsRunning()) | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     Core::QueueHostJob([this] { OnStopComplete(); }, true); | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 16:00:20 +02:00
										 |  |  |   if (!m_render_widget->isFullScreen()) | 
					
						
							| 
									
										
										
										
											2018-05-13 00:59:09 +02:00
										 |  |  |     m_render_widget_geometry = m_render_widget->saveGeometry(); | 
					
						
							| 
									
										
										
										
											2018-06-04 19:15:57 +02:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2018-06-01 04:05:59 +02:00
										 |  |  |     FullScreen(); | 
					
						
							| 
									
										
										
										
											2018-05-08 16:00:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-22 15:11:53 -07:00
										 |  |  |   if (SConfig::GetInstance().bConfirmStop) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |     const Core::State state = Core::GetState(); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Only pause the game, if NetPlay is not running
 | 
					
						
							| 
									
										
										
										
											2018-07-12 20:37:12 -04:00
										 |  |  |     bool pause = !Settings::Instance().GetNetPlayClient(); | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (pause) | 
					
						
							|  |  |  |       Core::SetState(Core::State::Paused); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     QMessageBox::StandardButton confirm; | 
					
						
							| 
									
										
										
										
											2018-05-25 03:53:40 +02:00
										 |  |  |     confirm = QMessageBox::question(this, tr("Confirm"), | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |                                     m_stop_requested ? | 
					
						
							|  |  |  |                                         tr("A shutdown is already in progress. Unsaved data " | 
					
						
							|  |  |  |                                            "may be lost if you stop the current emulation " | 
					
						
							|  |  |  |                                            "before it completes. Force stop?") : | 
					
						
							|  |  |  |                                         tr("Do you want to stop the current emulation?")); | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |     if (pause) | 
					
						
							|  |  |  |       Core::SetState(state); | 
					
						
							| 
									
										
										
										
											2017-06-27 18:06:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (confirm != QMessageBox::Yes) | 
					
						
							|  |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |   // TODO: Add Movie shutdown
 | 
					
						
							|  |  |  |   // TODO: Add Debugger shutdown
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!m_stop_requested && UICommon::TriggerSTMPowerEvent()) | 
					
						
							| 
									
										
										
										
											2016-07-06 19:00:33 -05:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |     m_stop_requested = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Unpause because gracefully shutting down needs the game to actually request a shutdown.
 | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |     // TODO: Do not unpause in debug mode to allow debugging until the complete shutdown.
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |     if (Core::GetState() == Core::State::Paused) | 
					
						
							|  |  |  |       Core::SetState(Core::State::Running); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ForceStop(); | 
					
						
							| 
									
										
										
										
											2016-07-06 19:00:33 -05:00
										 |  |  | #ifdef Q_OS_WIN
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |   // Allow windows to idle or turn off display again
 | 
					
						
							|  |  |  |   SetThreadExecutionState(ES_CONTINUOUS); | 
					
						
							| 
									
										
										
										
											2016-07-06 19:00:33 -05:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::ForceStop() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-04-21 23:27:54 +02:00
										 |  |  |   Core::Stop(); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | void MainWindow::Reset() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (Movie::IsRecordingInput()) | 
					
						
							| 
									
										
										
										
											2016-08-04 12:54:45 -04:00
										 |  |  |     Movie::SetReset(true); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   ProcessorInterface::ResetButton_Tap(); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::FrameAdvance() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-01 13:17:18 -07:00
										 |  |  |   Core::DoFrameStep(); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | void MainWindow::FullScreen() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // If the render widget is fullscreen we want to reset it to whatever is in
 | 
					
						
							|  |  |  |   // settings. If it's set to be fullscreen then it just remakes the window,
 | 
					
						
							|  |  |  |   // which probably isn't ideal.
 | 
					
						
							|  |  |  |   bool was_fullscreen = m_render_widget->isFullScreen(); | 
					
						
							| 
									
										
										
										
											2018-05-16 19:54:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!was_fullscreen) | 
					
						
							|  |  |  |     m_render_widget_geometry = m_render_widget->saveGeometry(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  |   HideRenderWidget(false); | 
					
						
							| 
									
										
										
										
											2018-05-07 18:38:59 +02:00
										 |  |  |   SetFullScreenResolution(!was_fullscreen); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (was_fullscreen) | 
					
						
							| 
									
										
										
										
											2018-05-04 14:14:53 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     ShowRenderWidget(); | 
					
						
							| 
									
										
										
										
											2018-05-04 14:14:53 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2018-05-04 14:14:53 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     m_render_widget->showFullScreen(); | 
					
						
							| 
									
										
										
										
											2018-05-04 14:14:53 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::ScreenShot() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   Core::SaveScreenShot(); | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  | void MainWindow::StartGame(const QString& path, const std::optional<std::string>& savestate_path) | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-31 20:33:36 +01:00
										 |  |  |   StartGame(path.toStdString(), savestate_path); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StartGame(const std::string& path, | 
					
						
							|  |  |  |                            const std::optional<std::string>& savestate_path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   StartGame(BootParameters::GenerateFromFile(path, savestate_path)); | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters) | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // If we're running, only start a new game once we've stopped the last.
 | 
					
						
							| 
									
										
										
										
											2017-02-05 07:39:58 -05:00
										 |  |  |   if (Core::GetState() != Core::State::Uninitialized) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |     if (!RequestStop()) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |       return; | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // As long as the shutdown isn't complete, we can't boot, so let's boot later
 | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  |     m_pending_boot = std::move(parameters); | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-10-03 23:03:13 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // We need the render widget before booting.
 | 
					
						
							|  |  |  |   ShowRenderWidget(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // Boot up, show an error if it fails to load the game.
 | 
					
						
							| 
									
										
										
										
											2018-10-03 23:03:22 +10:00
										 |  |  |   if (!BootManager::BootCore(std::move(parameters), | 
					
						
							|  |  |  |                              GetWindowSystemInfo(m_render_widget->windowHandle()))) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     QMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok); | 
					
						
							| 
									
										
										
										
											2018-10-03 23:03:13 +10:00
										 |  |  |     HideRenderWidget(); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-08 19:59:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-29 23:44:20 -04:00
										 |  |  | #ifdef USE_DISCORD_PRESENCE
 | 
					
						
							| 
									
										
										
										
											2018-08-06 17:56:40 -04:00
										 |  |  |   if (!NetPlay::IsNetPlayRunning()) | 
					
						
							|  |  |  |     Discord::UpdateDiscordPresence(); | 
					
						
							| 
									
										
										
										
											2018-05-29 23:44:20 -04:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-07-06 19:00:33 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 19:59:24 +02:00
										 |  |  |   if (SConfig::GetInstance().bFullscreen) | 
					
						
							|  |  |  |     m_fullscreen_requested = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-06 19:00:33 -05:00
										 |  |  | #ifdef Q_OS_WIN
 | 
					
						
							|  |  |  |   // Prevents Windows from sleeping, turning off the display, or idling
 | 
					
						
							|  |  |  |   EXECUTION_STATE shouldScreenSave = | 
					
						
							|  |  |  |       SConfig::GetInstance().bDisableScreenSaver ? ES_DISPLAY_REQUIRED : 0; | 
					
						
							|  |  |  |   SetThreadExecutionState(ES_CONTINUOUS | shouldScreenSave | ES_SYSTEM_REQUIRED); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 18:38:59 +02:00
										 |  |  | void MainWindow::SetFullScreenResolution(bool fullscreen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (SConfig::GetInstance().strFullscreenResolution == "Auto") | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!fullscreen) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ChangeDisplaySettings(nullptr, CDS_FULLSCREEN); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DEVMODE screen_settings; | 
					
						
							|  |  |  |   memset(&screen_settings, 0, sizeof(screen_settings)); | 
					
						
							|  |  |  |   screen_settings.dmSize = sizeof(screen_settings); | 
					
						
							|  |  |  |   sscanf(SConfig::GetInstance().strFullscreenResolution.c_str(), "%dx%d", | 
					
						
							|  |  |  |          &screen_settings.dmPelsWidth, &screen_settings.dmPelsHeight); | 
					
						
							|  |  |  |   screen_settings.dmBitsPerPel = 32; | 
					
						
							|  |  |  |   screen_settings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
 | 
					
						
							|  |  |  |   ChangeDisplaySettings(&screen_settings, CDS_FULLSCREEN); | 
					
						
							|  |  |  | #elif defined(HAVE_XRANDR) && HAVE_XRANDR
 | 
					
						
							|  |  |  |   m_xrr_config->ToggleDisplayMode(fullscreen); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | void MainWindow::ShowRenderWidget() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-16 19:54:35 +02:00
										 |  |  |   SetFullScreenResolution(false); | 
					
						
							|  |  |  |   Host::GetInstance()->SetRenderFullscreen(false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-22 15:11:53 -07:00
										 |  |  |   if (SConfig::GetInstance().bRenderToMain) | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     // If we're rendering to main, add it to the stack and update our title when necessary.
 | 
					
						
							|  |  |  |     m_rendering_to_main = true; | 
					
						
							| 
									
										
										
										
											2018-04-27 15:04:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     m_stack->setCurrentIndex(m_stack->addWidget(m_render_widget)); | 
					
						
							|  |  |  |     connect(Host::GetInstance(), &Host::RequestTitle, this, &MainWindow::setWindowTitle); | 
					
						
							| 
									
										
										
										
											2018-05-14 00:43:31 -04:00
										 |  |  |     m_stack->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); | 
					
						
							| 
									
										
										
										
											2018-03-24 23:50:03 +01:00
										 |  |  |     m_stack->repaint(); | 
					
						
							| 
									
										
										
										
											2018-05-13 21:08:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Host::GetInstance()->SetRenderFocus(isActiveWindow()); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // Otherwise, just show it.
 | 
					
						
							|  |  |  |     m_rendering_to_main = false; | 
					
						
							| 
									
										
										
										
											2018-04-27 15:04:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_render_widget->showNormal(); | 
					
						
							| 
									
										
										
										
											2018-05-13 00:59:09 +02:00
										 |  |  |     m_render_widget->restoreGeometry(m_render_widget_geometry); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  | void MainWindow::HideRenderWidget(bool reinit) | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (m_rendering_to_main) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // Remove the widget from the stack and reparent it to nullptr, so that it can draw
 | 
					
						
							|  |  |  |     // itself in a new window if it wants. Disconnect the title updates.
 | 
					
						
							|  |  |  |     m_stack->removeWidget(m_render_widget); | 
					
						
							|  |  |  |     m_render_widget->setParent(nullptr); | 
					
						
							|  |  |  |     m_rendering_to_main = false; | 
					
						
							| 
									
										
										
										
											2018-05-14 00:43:31 -04:00
										 |  |  |     m_stack->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     disconnect(Host::GetInstance(), &Host::RequestTitle, this, &MainWindow::setWindowTitle); | 
					
						
							| 
									
										
										
										
											2017-09-09 15:52:35 -04:00
										 |  |  |     setWindowTitle(QString::fromStdString(Common::scm_rev_str)); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-02-02 15:35:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // The following code works around a driver bug that would lead to Dolphin crashing when changing
 | 
					
						
							| 
									
										
										
										
											2018-02-09 22:54:35 +11:00
										 |  |  |   // graphics backends (e.g. OpenGL to Vulkan). To avoid this the render widget is (safely)
 | 
					
						
							|  |  |  |   // recreated
 | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  |   if (reinit) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-03-22 15:29:08 +01:00
										 |  |  |     m_render_widget->hide(); | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  |     disconnect(m_render_widget, &RenderWidget::Closed, this, &MainWindow::ForceStop); | 
					
						
							| 
									
										
										
										
											2018-02-02 15:35:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  |     m_render_widget->removeEventFilter(this); | 
					
						
							|  |  |  |     m_render_widget->deleteLater(); | 
					
						
							| 
									
										
										
										
											2018-02-02 15:35:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  |     m_render_widget = new RenderWidget; | 
					
						
							| 
									
										
										
										
											2018-02-02 15:35:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  |     m_render_widget->installEventFilter(this); | 
					
						
							|  |  |  |     connect(m_render_widget, &RenderWidget::Closed, this, &MainWindow::ForceStop); | 
					
						
							| 
									
										
										
										
											2018-06-08 20:47:15 +02:00
										 |  |  |     connect(m_render_widget, &RenderWidget::FocusChanged, this, [this](bool focus) { | 
					
						
							|  |  |  |       if (m_render_widget->isFullScreen()) | 
					
						
							|  |  |  |         SetFullScreenResolution(focus); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-03-21 20:53:37 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-27 00:33:07 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-02-09 20:42:06 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 18:49:10 +02:00
										 |  |  | void MainWindow::ShowControllersWindow() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-14 21:46:54 +10:00
										 |  |  |   if (!m_controllers_window) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_controllers_window = new ControllersWindow(this); | 
					
						
							|  |  |  |     InstallHotkeyFilter(m_controllers_window); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 18:49:10 +02:00
										 |  |  |   m_controllers_window->show(); | 
					
						
							|  |  |  |   m_controllers_window->raise(); | 
					
						
							|  |  |  |   m_controllers_window->activateWindow(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-09 06:34:07 -07:00
										 |  |  | void MainWindow::ShowSettingsWindow() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-14 21:46:54 +10:00
										 |  |  |   if (!m_settings_window) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_settings_window = new SettingsWindow(this); | 
					
						
							|  |  |  |     InstallHotkeyFilter(m_settings_window); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_settings_window->show(); | 
					
						
							|  |  |  |   m_settings_window->raise(); | 
					
						
							|  |  |  |   m_settings_window->activateWindow(); | 
					
						
							| 
									
										
										
										
											2016-05-09 06:34:07 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-16 14:11:11 -07:00
										 |  |  | void MainWindow::ShowAudioWindow() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   ShowSettingsWindow(); | 
					
						
							| 
									
										
										
										
											2018-10-14 21:46:54 +10:00
										 |  |  |   m_settings_window->SelectAudioPane(); | 
					
						
							| 
									
										
										
										
											2017-07-16 14:11:11 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 19:10:45 +02:00
										 |  |  | void MainWindow::ShowGeneralWindow() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   ShowSettingsWindow(); | 
					
						
							| 
									
										
										
										
											2018-10-14 21:46:54 +10:00
										 |  |  |   m_settings_window->SelectGeneralPane(); | 
					
						
							| 
									
										
										
										
											2017-09-10 19:10:45 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-11 22:59:44 +11:00
										 |  |  | void MainWindow::ShowAboutDialog() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-14 17:01:43 +02:00
										 |  |  |   AboutDialog about{this}; | 
					
						
							|  |  |  |   about.exec(); | 
					
						
							| 
									
										
										
										
											2016-02-11 22:59:44 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  | void MainWindow::ShowHotkeyDialog() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-14 22:15:26 +10:00
										 |  |  |   if (!m_hotkey_window) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_hotkey_window = new MappingWindow(this, MappingWindow::Type::MAPPING_HOTKEYS, 0); | 
					
						
							|  |  |  |     InstallHotkeyFilter(m_hotkey_window); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-07-03 08:24:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-14 22:15:26 +10:00
										 |  |  |   m_hotkey_window->show(); | 
					
						
							|  |  |  |   m_hotkey_window->raise(); | 
					
						
							|  |  |  |   m_hotkey_window->activateWindow(); | 
					
						
							| 
									
										
										
										
											2017-06-06 13:49:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 01:42:12 +02:00
										 |  |  | void MainWindow::ShowGraphicsWindow() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-14 21:46:54 +10:00
										 |  |  |   if (!m_graphics_window) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  | #if defined(HAVE_XRANDR) && HAVE_XRANDR
 | 
					
						
							|  |  |  |     m_xrr_config = std::make_unique<X11Utils::XRRConfiguration>( | 
					
						
							|  |  |  |         static_cast<Display*>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow( | 
					
						
							|  |  |  |             "display", windowHandle())), | 
					
						
							|  |  |  |         winId()); | 
					
						
							|  |  |  |     m_graphics_window = new GraphicsWindow(m_xrr_config.get(), this); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     m_graphics_window = new GraphicsWindow(nullptr, this); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 01:42:12 +02:00
										 |  |  |   m_graphics_window->show(); | 
					
						
							|  |  |  |   m_graphics_window->raise(); | 
					
						
							|  |  |  |   m_graphics_window->activateWindow(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | void MainWindow::ShowNetPlaySetupDialog() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   m_netplay_setup_dialog->show(); | 
					
						
							|  |  |  |   m_netplay_setup_dialog->raise(); | 
					
						
							|  |  |  |   m_netplay_setup_dialog->activateWindow(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 16:44:28 +02:00
										 |  |  | void MainWindow::ShowFIFOPlayer() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-14 21:46:54 +10:00
										 |  |  |   if (!m_fifo_window) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_fifo_window = new FIFOPlayerWindow(this); | 
					
						
							|  |  |  |     connect(m_fifo_window, &FIFOPlayerWindow::LoadFIFORequested, this, | 
					
						
							|  |  |  |             [this](const QString& path) { StartGame(path); }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 16:44:28 +02:00
										 |  |  |   m_fifo_window->show(); | 
					
						
							|  |  |  |   m_fifo_window->raise(); | 
					
						
							|  |  |  |   m_fifo_window->activateWindow(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | void MainWindow::StateLoad() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   QString path = QFileDialog::getOpenFileName(this, tr("Select a File"), QDir::currentPath(), | 
					
						
							|  |  |  |                                               tr("All Save States (*.sav *.s##);; All Files (*)")); | 
					
						
							|  |  |  |   State::LoadAs(path.toStdString()); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StateSave() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   QString path = QFileDialog::getSaveFileName(this, tr("Select a File"), QDir::currentPath(), | 
					
						
							|  |  |  |                                               tr("All Save States (*.sav *.s##);; All Files (*)")); | 
					
						
							|  |  |  |   State::SaveAs(path.toStdString()); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StateLoadSlot() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   State::Load(m_state_slot); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StateSaveSlot() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   State::Save(m_state_slot, true); | 
					
						
							|  |  |  |   m_menu_bar->UpdateStateSlotMenu(); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StateLoadSlotAt(int slot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   State::Load(slot); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 20:27:14 +02:00
										 |  |  | void MainWindow::StateLoadLastSavedAt(int slot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   State::LoadLastSaved(slot); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | void MainWindow::StateSaveSlotAt(int slot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   State::Save(slot, true); | 
					
						
							|  |  |  |   m_menu_bar->UpdateStateSlotMenu(); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StateLoadUndo() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   State::UndoLoadState(); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StateSaveUndo() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   State::UndoSaveState(); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::StateSaveOldest() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   State::SaveFirstSaved(); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::SetStateSlot(int slot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-05-31 00:17:39 -07:00
										 |  |  |   Settings::Instance().SetStateSlot(slot); | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_state_slot = slot; | 
					
						
							| 
									
										
										
										
											2018-07-01 16:30:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Core::DisplayMessage(StringFromFormat("Selected slot %d - %s", m_state_slot, | 
					
						
							|  |  |  |                                         State::GetInfoStringOfSlot(m_state_slot, false).c_str()), | 
					
						
							|  |  |  |                        2500); | 
					
						
							| 
									
										
										
										
											2016-02-15 12:56:40 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-14 11:58:11 +02:00
										 |  |  | void MainWindow::PerformOnlineUpdate(const std::string& region) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   WiiUpdate::PerformOnlineUpdate(region, this); | 
					
						
							|  |  |  |   // Since the update may have installed a newer system menu, refresh the tools menu.
 | 
					
						
							|  |  |  |   m_menu_bar->UpdateToolsMenu(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-06 11:01:32 +02:00
										 |  |  | void MainWindow::BootWiiSystemMenu() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-10-01 15:41:54 +02:00
										 |  |  |   StartGame(std::make_unique<BootParameters>(BootParameters::NANDTitle{Titles::SYSTEM_MENU})); | 
					
						
							| 
									
										
										
										
											2017-07-06 11:01:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | void MainWindow::NetPlayInit() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   m_netplay_setup_dialog = new NetPlaySetupDialog(this); | 
					
						
							| 
									
										
										
										
											2018-07-04 16:41:56 -04:00
										 |  |  |   m_netplay_dialog = new NetPlayDialog; | 
					
						
							| 
									
										
										
										
											2018-07-20 18:27:43 -04:00
										 |  |  | #ifdef USE_DISCORD_PRESENCE
 | 
					
						
							|  |  |  |   m_netplay_discord = new DiscordHandler(this); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  |   connect(m_netplay_dialog, &NetPlayDialog::Boot, this, | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |           [this](const QString& path) { StartGame(path); }); | 
					
						
							| 
									
										
										
										
											2018-07-04 00:54:50 +02:00
										 |  |  |   connect(m_netplay_dialog, &NetPlayDialog::Stop, this, &MainWindow::ForceStop); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   connect(m_netplay_dialog, &NetPlayDialog::rejected, this, &MainWindow::NetPlayQuit); | 
					
						
							|  |  |  |   connect(m_netplay_setup_dialog, &NetPlaySetupDialog::Join, this, &MainWindow::NetPlayJoin); | 
					
						
							|  |  |  |   connect(m_netplay_setup_dialog, &NetPlaySetupDialog::Host, this, &MainWindow::NetPlayHost); | 
					
						
							| 
									
										
										
										
											2018-07-20 18:27:43 -04:00
										 |  |  | #ifdef USE_DISCORD_PRESENCE
 | 
					
						
							| 
									
										
										
										
											2018-07-03 17:50:08 -04:00
										 |  |  |   connect(m_netplay_discord, &DiscordHandler::Join, this, &MainWindow::NetPlayJoin); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 18:27:43 -04:00
										 |  |  |   Discord::InitNetPlayFunctionality(*m_netplay_discord); | 
					
						
							| 
									
										
										
										
											2018-07-03 17:50:08 -04:00
										 |  |  |   m_netplay_discord->Start(); | 
					
						
							| 
									
										
										
										
											2018-07-20 18:27:43 -04:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MainWindow::NetPlayJoin() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (Core::IsRunning()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     QMessageBox::critical( | 
					
						
							|  |  |  |         nullptr, QObject::tr("Error"), | 
					
						
							|  |  |  |         QObject::tr("Can't start a NetPlay Session while a game is still running!")); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (m_netplay_dialog->isVisible()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     QMessageBox::critical(nullptr, QObject::tr("Error"), | 
					
						
							|  |  |  |                           QObject::tr("A NetPlay Session is already in progress!")); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 00:52:19 +02:00
										 |  |  |   auto server = Settings::Instance().GetNetPlayServer(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   // Settings
 | 
					
						
							| 
									
										
										
										
											2018-07-05 17:52:53 -04:00
										 |  |  |   const std::string traversal_choice = Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE); | 
					
						
							|  |  |  |   const bool is_traversal = traversal_choice == "traversal"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 12:47:27 -07:00
										 |  |  |   std::string host_ip; | 
					
						
							|  |  |  |   u16 host_port; | 
					
						
							| 
									
										
										
										
											2018-10-10 00:52:19 +02:00
										 |  |  |   if (server) | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     host_ip = "127.0.0.1"; | 
					
						
							| 
									
										
										
										
											2018-10-10 00:52:19 +02:00
										 |  |  |     host_port = server->GetPort(); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-07-05 17:52:53 -04:00
										 |  |  |     host_ip = is_traversal ? Config::Get(Config::NETPLAY_HOST_CODE) : | 
					
						
							|  |  |  |                              Config::Get(Config::NETPLAY_ADDRESS); | 
					
						
							|  |  |  |     host_port = Config::Get(Config::NETPLAY_CONNECT_PORT); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 12:47:27 -07:00
										 |  |  |   const std::string traversal_host = Config::Get(Config::NETPLAY_TRAVERSAL_SERVER); | 
					
						
							|  |  |  |   const u16 traversal_port = Config::Get(Config::NETPLAY_TRAVERSAL_PORT); | 
					
						
							|  |  |  |   const std::string nickname = Config::Get(Config::NETPLAY_NICKNAME); | 
					
						
							| 
									
										
										
										
											2018-10-10 00:52:19 +02:00
										 |  |  |   const bool host_input_authority = Config::Get(Config::NETPLAY_HOST_INPUT_AUTHORITY); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (server) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     server->SetHostInputAuthority(host_input_authority); | 
					
						
							|  |  |  |     if (!host_input_authority) | 
					
						
							|  |  |  |       server->AdjustPadBufferSize(Config::Get(Config::NETPLAY_BUFFER_SIZE)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create Client
 | 
					
						
							| 
									
										
										
										
											2018-10-10 00:52:19 +02:00
										 |  |  |   const bool is_hosting_netplay = server != nullptr; | 
					
						
							| 
									
										
										
										
											2018-07-06 19:39:42 -04:00
										 |  |  |   Settings::Instance().ResetNetPlayClient(new NetPlay::NetPlayClient( | 
					
						
							| 
									
										
										
										
											2017-08-07 00:22:33 -07:00
										 |  |  |       host_ip, host_port, m_netplay_dialog, nickname, | 
					
						
							| 
									
										
										
										
											2018-07-06 19:39:42 -04:00
										 |  |  |       NetPlay::NetTraversalConfig{is_hosting_netplay ? false : is_traversal, traversal_host, | 
					
						
							|  |  |  |                                   traversal_port})); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!Settings::Instance().GetNetPlayClient()->IsConnected()) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-06 19:00:17 +02:00
										 |  |  |     NetPlayQuit(); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 00:52:19 +02:00
										 |  |  |   if (server != nullptr) | 
					
						
							|  |  |  |     server->SetNetPlayUI(m_netplay_dialog); | 
					
						
							| 
									
										
										
										
											2018-07-04 17:01:50 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |   m_netplay_setup_dialog->close(); | 
					
						
							|  |  |  |   m_netplay_dialog->show(nickname, is_traversal); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MainWindow::NetPlayHost(const QString& game_id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (Core::IsRunning()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     QMessageBox::critical( | 
					
						
							|  |  |  |         nullptr, QObject::tr("Error"), | 
					
						
							|  |  |  |         QObject::tr("Can't start a NetPlay Session while a game is still running!")); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (m_netplay_dialog->isVisible()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     QMessageBox::critical(nullptr, QObject::tr("Error"), | 
					
						
							|  |  |  |                           QObject::tr("A NetPlay Session is already in progress!")); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Settings
 | 
					
						
							| 
									
										
										
										
											2017-08-10 12:47:27 -07:00
										 |  |  |   u16 host_port = Config::Get(Config::NETPLAY_HOST_PORT); | 
					
						
							|  |  |  |   const std::string traversal_choice = Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE); | 
					
						
							|  |  |  |   const bool is_traversal = traversal_choice == "traversal"; | 
					
						
							|  |  |  |   const bool use_upnp = Config::Get(Config::NETPLAY_USE_UPNP); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const std::string traversal_host = Config::Get(Config::NETPLAY_TRAVERSAL_SERVER); | 
					
						
							|  |  |  |   const u16 traversal_port = Config::Get(Config::NETPLAY_TRAVERSAL_PORT); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (is_traversal) | 
					
						
							|  |  |  |     host_port = Config::Get(Config::NETPLAY_LISTEN_PORT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Create Server
 | 
					
						
							| 
									
										
										
										
											2018-07-06 19:39:42 -04:00
										 |  |  |   Settings::Instance().ResetNetPlayServer(new NetPlay::NetPlayServer( | 
					
						
							|  |  |  |       host_port, use_upnp, | 
					
						
							|  |  |  |       NetPlay::NetTraversalConfig{is_traversal, traversal_host, traversal_port})); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!Settings::Instance().GetNetPlayServer()->is_connected) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     QMessageBox::critical( | 
					
						
							|  |  |  |         nullptr, QObject::tr("Failed to open server"), | 
					
						
							|  |  |  |         QObject::tr( | 
					
						
							|  |  |  |             "Failed to listen on port %1. Is another instance of the NetPlay server running?") | 
					
						
							|  |  |  |             .arg(host_port)); | 
					
						
							| 
									
										
										
										
											2018-05-06 19:00:17 +02:00
										 |  |  |     NetPlayQuit(); | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Settings::Instance().GetNetPlayServer()->ChangeGame(game_id.toStdString()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Join our local server
 | 
					
						
							|  |  |  |   return NetPlayJoin(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::NetPlayQuit() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Settings::Instance().ResetNetPlayClient(); | 
					
						
							|  |  |  |   Settings::Instance().ResetNetPlayServer(); | 
					
						
							| 
									
										
										
										
											2018-08-06 17:56:40 -04:00
										 |  |  | #ifdef USE_DISCORD_PRESENCE
 | 
					
						
							| 
									
										
										
										
											2018-07-03 17:50:08 -04:00
										 |  |  |   Discord::UpdateDiscordPresence(); | 
					
						
							| 
									
										
										
										
											2018-08-06 17:56:40 -04:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:48:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-01 21:15:26 +00:00
										 |  |  | void MainWindow::EnableScreenSaver(bool enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined(HAVE_XRANDR) && HAVE_XRANDR
 | 
					
						
							| 
									
										
										
										
											2018-04-14 16:48:49 +02:00
										 |  |  |   UICommon::EnableScreenSaver(winId(), enable); | 
					
						
							| 
									
										
										
										
											2018-01-01 21:15:26 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |   UICommon::EnableScreenSaver(enable); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  | bool MainWindow::eventFilter(QObject* object, QEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |   if (event->type() == QEvent::Close) | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2017-07-03 16:04:24 +02:00
										 |  |  |     if (RequestStop() && object == this) | 
					
						
							|  |  |  |       m_exit_requested = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-24 17:00:37 +02:00
										 |  |  |     static_cast<QCloseEvent*>(event)->ignore(); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-06-26 23:22:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::dragEnterEvent(QDragEnterEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) | 
					
						
							|  |  |  |     event->acceptProposedAction(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::dropEvent(QDropEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const auto& urls = event->mimeData()->urls(); | 
					
						
							|  |  |  |   if (urls.empty()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const auto& url = urls[0]; | 
					
						
							|  |  |  |   QFileInfo file_info(url.toLocalFile()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   auto path = file_info.filePath(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!file_info.exists() || !file_info.isReadable()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     QMessageBox::critical(this, tr("Error"), tr("Failed to open '%1'").arg(path)); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (file_info.isFile()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     StartGame(path); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     auto& settings = Settings::Instance(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (settings.GetPaths().size() != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (QMessageBox::question( | 
					
						
							|  |  |  |               this, tr("Confirm"), | 
					
						
							|  |  |  |               tr("Do you want to add \"%1\" to the list of Game Paths?").arg(path)) != | 
					
						
							|  |  |  |           QMessageBox::Yes) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     settings.AddPath(path); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-26 19:24:07 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | QSize MainWindow::sizeHint() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return QSize(800, 600); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-08-24 16:35:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::OnBootGameCubeIPL(DiscIO::Region region) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   StartGame(std::make_unique<BootParameters>(BootParameters::IPL{region})); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-08-24 17:38:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::OnImportNANDBackup() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   auto response = QMessageBox::question( | 
					
						
							|  |  |  |       this, tr("Question"), | 
					
						
							|  |  |  |       tr("Merging a new NAND over your currently selected NAND will overwrite any channels " | 
					
						
							|  |  |  |          "and savegames that already exist. This process is not reversible, so it is " | 
					
						
							|  |  |  |          "recommended that you keep backups of both NANDs. Are you sure you want to " | 
					
						
							|  |  |  |          "continue?")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (response == QMessageBox::No) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   QString file = QFileDialog::getOpenFileName(this, tr("Select the save file"), QDir::currentPath(), | 
					
						
							|  |  |  |                                               tr("BootMii NAND backup file (*.bin);;" | 
					
						
							|  |  |  |                                                  "All Files (*)")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (file.isEmpty()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   QProgressDialog* dialog = new QProgressDialog(this); | 
					
						
							|  |  |  |   dialog->setMinimum(0); | 
					
						
							|  |  |  |   dialog->setMaximum(0); | 
					
						
							|  |  |  |   dialog->setLabelText(tr("Importing NAND backup")); | 
					
						
							|  |  |  |   dialog->setCancelButton(nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-02 03:20:20 +02:00
										 |  |  |   auto beginning = QDateTime::currentDateTime().toMSecsSinceEpoch(); | 
					
						
							| 
									
										
										
										
											2017-08-24 17:38:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   auto result = std::async(std::launch::async, [&] { | 
					
						
							| 
									
										
										
										
											2017-10-26 21:22:16 +02:00
										 |  |  |     DiscIO::NANDImporter().ImportNANDBin( | 
					
						
							|  |  |  |         file.toStdString(), | 
					
						
							|  |  |  |         [&dialog, beginning] { | 
					
						
							|  |  |  |           QueueOnObject(dialog, [&dialog, beginning] { | 
					
						
							|  |  |  |             dialog->setLabelText( | 
					
						
							|  |  |  |                 tr("Importing NAND backup\n Time elapsed: %1s") | 
					
						
							|  |  |  |                     .arg((QDateTime::currentDateTime().toMSecsSinceEpoch() - beginning) / 1000)); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         [this] { | 
					
						
							| 
									
										
										
										
											2018-05-21 15:27:12 -07:00
										 |  |  |           std::optional<std::string> keys_file = RunOnObject(this, [this] { | 
					
						
							| 
									
										
										
										
											2017-12-02 18:20:42 +01:00
										 |  |  |             return QFileDialog::getOpenFileName(this, tr("Select the keys file (OTP/SEEPROM dump)"), | 
					
						
							| 
									
										
										
										
											2017-10-26 21:22:16 +02:00
										 |  |  |                                                 QDir::currentPath(), | 
					
						
							| 
									
										
										
										
											2017-12-02 18:20:42 +01:00
										 |  |  |                                                 tr("BootMii keys file (*.bin);;" | 
					
						
							| 
									
										
										
										
											2017-10-26 21:22:16 +02:00
										 |  |  |                                                    "All Files (*)")) | 
					
						
							|  |  |  |                 .toStdString(); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2018-05-21 15:27:12 -07:00
										 |  |  |           if (keys_file) | 
					
						
							|  |  |  |             return *keys_file; | 
					
						
							|  |  |  |           return std::string(""); | 
					
						
							| 
									
										
										
										
											2017-10-26 21:22:16 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-09-15 08:51:08 -07:00
										 |  |  |     QueueOnObject(dialog, &QProgressDialog::close); | 
					
						
							| 
									
										
										
										
											2017-08-24 17:38:31 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   dialog->exec(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   result.wait(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_menu_bar->UpdateToolsMenu(Core::IsRunning()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::OnPlayRecording() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-02 14:32:16 +01:00
										 |  |  |   QString dtm_file = QFileDialog::getOpenFileName(this, tr("Select the Recording File"), QString(), | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |                                                   tr("Dolphin TAS Movies (*.dtm)")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (dtm_file.isEmpty()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!Movie::IsReadOnly()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // let's make the read-only flag consistent at the start of a movie.
 | 
					
						
							|  |  |  |     Movie::SetReadOnly(true); | 
					
						
							|  |  |  |     emit ReadOnlyModeChanged(true); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |   std::optional<std::string> savestate_path; | 
					
						
							|  |  |  |   if (Movie::PlayInput(dtm_file.toStdString(), &savestate_path)) | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     emit RecordingStatusChanged(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 18:07:29 +01:00
										 |  |  |     Play(savestate_path); | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::OnStartRecording() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if ((!Core::IsRunningAndStarted() && Core::IsRunning()) || Movie::IsRecordingInput() || | 
					
						
							|  |  |  |       Movie::IsPlayingInput()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (Movie::IsReadOnly()) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // The user just chose to record a movie, so that should take precedence
 | 
					
						
							|  |  |  |     Movie::SetReadOnly(false); | 
					
						
							|  |  |  |     emit ReadOnlyModeChanged(true); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int controllers = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int i = 0; i < 4; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (SerialInterface::SIDevice_IsGCController(SConfig::GetInstance().m_SIDevice[i])) | 
					
						
							|  |  |  |       controllers |= (1 << i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (g_wiimote_sources[i] != WIIMOTE_SRC_NONE) | 
					
						
							|  |  |  |       controllers |= (1 << (i + 4)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (Movie::BeginRecordingInput(controllers)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     emit RecordingStatusChanged(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!Core::IsRunning()) | 
					
						
							|  |  |  |       Play(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::OnStopRecording() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (Movie::IsRecordingInput()) | 
					
						
							|  |  |  |     OnExportRecording(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Movie::EndPlayInput(false); | 
					
						
							|  |  |  |   emit RecordingStatusChanged(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::OnExportRecording() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   bool was_paused = Core::GetState() == Core::State::Paused; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (was_paused) | 
					
						
							|  |  |  |     Core::SetState(Core::State::Paused); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-02 14:32:16 +01:00
										 |  |  |   QString dtm_file = QFileDialog::getSaveFileName(this, tr("Select the Recording File"), QString(), | 
					
						
							| 
									
										
										
										
											2017-08-27 13:55:05 +02:00
										 |  |  |                                                   tr("Dolphin TAS Movies (*.dtm)")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (was_paused) | 
					
						
							|  |  |  |     Core::SetState(Core::State::Running); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (dtm_file.isEmpty()) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Core::SetState(Core::State::Running); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Movie::SaveRecording(dtm_file.toStdString()); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-01-24 15:25:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-28 00:35:02 +11:00
										 |  |  | void MainWindow::ShowTASInput() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-06 22:10:28 +11:00
										 |  |  |   for (int i = 0; i < num_gc_controllers; i++) | 
					
						
							| 
									
										
										
										
											2018-01-28 00:35:02 +11:00
										 |  |  |   { | 
					
						
							|  |  |  |     if (SConfig::GetInstance().m_SIDevice[i] != SerialInterface::SIDEVICE_NONE && | 
					
						
							|  |  |  |         SConfig::GetInstance().m_SIDevice[i] != SerialInterface::SIDEVICE_GC_GBA) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       m_gc_tas_input_windows[i]->show(); | 
					
						
							|  |  |  |       m_gc_tas_input_windows[i]->raise(); | 
					
						
							|  |  |  |       m_gc_tas_input_windows[i]->activateWindow(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-06 22:10:28 +11:00
										 |  |  |   for (int i = 0; i < num_wii_controllers; i++) | 
					
						
							| 
									
										
										
										
											2018-01-31 22:35:09 +11:00
										 |  |  |   { | 
					
						
							|  |  |  |     if (g_wiimote_sources[i] == WIIMOTE_SRC_EMU && | 
					
						
							|  |  |  |         (!Core::IsRunning() || SConfig::GetInstance().bWii)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       m_wii_tas_input_windows[i]->show(); | 
					
						
							|  |  |  |       m_wii_tas_input_windows[i]->raise(); | 
					
						
							|  |  |  |       m_wii_tas_input_windows[i]->activateWindow(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-01-28 00:35:02 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-24 15:25:35 +01:00
										 |  |  | void MainWindow::OnConnectWiiRemote(int id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const auto ios = IOS::HLE::GetIOS(); | 
					
						
							|  |  |  |   if (!ios || SConfig::GetInstance().m_bt_passthrough_enabled) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   Core::RunAsCPUThread([&] { | 
					
						
							|  |  |  |     const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>( | 
					
						
							|  |  |  |         ios->GetDeviceByName("/dev/usb/oh1/57e/305")); | 
					
						
							| 
									
										
										
										
											2018-06-21 11:31:26 -04:00
										 |  |  |     const bool is_connected = bt && bt->AccessWiimoteByIndex(id)->IsConnected(); | 
					
						
							| 
									
										
										
										
											2018-01-24 15:25:35 +01:00
										 |  |  |     Wiimote::Connect(id, !is_connected); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-01-25 19:54:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::ShowMemcardManager() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GCMemcardManager manager(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   manager.exec(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-24 02:13:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-26 04:17:47 +02:00
										 |  |  | void MainWindow::ShowCheatsManager() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   m_cheats_manager->show(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-24 02:13:56 +01:00
										 |  |  | void MainWindow::OnUpdateProgressDialog(QString title, int progress, int total) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (!m_progress_dialog) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-10-03 21:35:10 -04:00
										 |  |  |     m_progress_dialog = new QProgressDialog(m_render_widget, Qt::WindowTitleHint); | 
					
						
							| 
									
										
										
										
											2018-03-24 02:13:56 +01:00
										 |  |  |     m_progress_dialog->show(); | 
					
						
							| 
									
										
										
										
											2018-10-03 21:35:10 -04:00
										 |  |  |     m_progress_dialog->setCancelButton(nullptr); | 
					
						
							|  |  |  |     m_progress_dialog->setWindowTitle(tr("Dolphin")); | 
					
						
							| 
									
										
										
										
											2018-03-24 02:13:56 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_progress_dialog->setValue(progress); | 
					
						
							|  |  |  |   m_progress_dialog->setLabelText(title); | 
					
						
							|  |  |  |   m_progress_dialog->setMaximum(total); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (total < 0 || progress >= total) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_progress_dialog->hide(); | 
					
						
							|  |  |  |     m_progress_dialog->deleteLater(); | 
					
						
							|  |  |  |     m_progress_dialog = nullptr; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-05-13 15:03:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MainWindow::Show() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   QWidget::show(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // If the booting of a game was requested on start up, do that now
 | 
					
						
							|  |  |  |   if (m_pending_boot != nullptr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     StartGame(std::move(m_pending_boot)); | 
					
						
							|  |  |  |     m_pending_boot.reset(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |