mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	add CIA installation to QT frontend
This commit is contained in:
		
							parent
							
								
									b7cf793814
								
							
						
					
					
						commit
						80852f918a
					
				
					 3 changed files with 87 additions and 2 deletions
				
			
		|  | @ -10,7 +10,9 @@ | ||||||
| #define QT_NO_OPENGL | #define QT_NO_OPENGL | ||||||
| #include <QDesktopWidget> | #include <QDesktopWidget> | ||||||
| #include <QFileDialog> | #include <QFileDialog> | ||||||
|  | #include <QFutureWatcher> | ||||||
| #include <QMessageBox> | #include <QMessageBox> | ||||||
|  | #include <QtConcurrent/QtConcurrentRun> | ||||||
| #include <QtGui> | #include <QtGui> | ||||||
| #include <QtWidgets> | #include <QtWidgets> | ||||||
| #include "citra_qt/aboutdialog.h" | #include "citra_qt/aboutdialog.h" | ||||||
|  | @ -92,6 +94,9 @@ void GMainWindow::ShowCallouts() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { | GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { | ||||||
|  |     // register size_t to use in slots and signals
 | ||||||
|  |     qRegisterMetaType<size_t>("size_t"); | ||||||
|  | 
 | ||||||
|     Pica::g_debug_context = Pica::DebugContext::Construct(); |     Pica::g_debug_context = Pica::DebugContext::Construct(); | ||||||
|     setAcceptDrops(true); |     setAcceptDrops(true); | ||||||
|     ui.setupUi(this); |     ui.setupUi(this); | ||||||
|  | @ -158,6 +163,10 @@ void GMainWindow::InitializeWidgets() { | ||||||
|     message_label->setAlignment(Qt::AlignLeft); |     message_label->setAlignment(Qt::AlignLeft); | ||||||
|     statusBar()->addPermanentWidget(message_label, 1); |     statusBar()->addPermanentWidget(message_label, 1); | ||||||
| 
 | 
 | ||||||
|  |     progress_bar = new QProgressBar(); | ||||||
|  |     progress_bar->hide(); | ||||||
|  |     statusBar()->addPermanentWidget(progress_bar); | ||||||
|  | 
 | ||||||
|     emu_speed_label = new QLabel(); |     emu_speed_label = new QLabel(); | ||||||
|     emu_speed_label->setToolTip(tr("Current emulation speed. Values higher or lower than 100% " |     emu_speed_label->setToolTip(tr("Current emulation speed. Values higher or lower than 100% " | ||||||
|                                    "indicate emulation is running faster or slower than a 3DS.")); |                                    "indicate emulation is running faster or slower than a 3DS.")); | ||||||
|  | @ -333,11 +342,14 @@ void GMainWindow::ConnectWidgetEvents() { | ||||||
|     connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping())); |     connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping())); | ||||||
| 
 | 
 | ||||||
|     connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar); |     connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar); | ||||||
|  | 
 | ||||||
|  |     connect(this, &GMainWindow::UpdateProgress, this, &GMainWindow::OnUpdateProgress); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GMainWindow::ConnectMenuEvents() { | void GMainWindow::ConnectMenuEvents() { | ||||||
|     // File
 |     // File
 | ||||||
|     connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); |     connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); | ||||||
|  |     connect(ui.action_Install_CIA, &QAction::triggered, this, &GMainWindow::OnMenuInstallCIA); | ||||||
|     connect(ui.action_Select_Game_List_Root, &QAction::triggered, this, |     connect(ui.action_Select_Game_List_Root, &QAction::triggered, this, | ||||||
|             &GMainWindow::OnMenuSelectGameListRoot); |             &GMainWindow::OnMenuSelectGameListRoot); | ||||||
|     connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); |     connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); | ||||||
|  | @ -696,6 +708,61 @@ void GMainWindow::OnMenuSelectGameListRoot() { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void GMainWindow::OnMenuInstallCIA() { | ||||||
|  |     QString filepath = QFileDialog::getOpenFileName( | ||||||
|  |         this, tr("Load File"), UISettings::values.roms_path, | ||||||
|  |         tr("3DS Installation File (*.CIA*)") + ";;" + tr("All Files (*.*)")); | ||||||
|  |     if (filepath.isEmpty()) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     ui.action_Install_CIA->setEnabled(false); | ||||||
|  |     progress_bar->show(); | ||||||
|  |     watcher = new QFutureWatcher<Service::AM::InstallStatus>; | ||||||
|  |     QFuture<Service::AM::InstallStatus> f = QtConcurrent::run([&, filepath] { | ||||||
|  |         const auto cia_progress = [&](size_t written, size_t total) { | ||||||
|  |             emit UpdateProgress(written, total); | ||||||
|  |         }; | ||||||
|  |         return Service::AM::InstallCIA(filepath.toStdString(), cia_progress); | ||||||
|  |     }); | ||||||
|  |     connect(watcher, &QFutureWatcher<Service::AM::InstallStatus>::finished, this, | ||||||
|  |             &GMainWindow::OnCIAInstallFinished); | ||||||
|  |     watcher->setFuture(f); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void GMainWindow::OnUpdateProgress(size_t written, size_t total) { | ||||||
|  |     progress_bar->setMaximum(total); | ||||||
|  |     progress_bar->setValue(written); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void GMainWindow::OnCIAInstallFinished() { | ||||||
|  |     progress_bar->hide(); | ||||||
|  |     progress_bar->setValue(0); | ||||||
|  |     switch (watcher->future()) { | ||||||
|  |     case Service::AM::InstallStatus::Success: | ||||||
|  |         this->statusBar()->showMessage(tr("The file has been installed successfully.")); | ||||||
|  |         break; | ||||||
|  |     case Service::AM::InstallStatus::ErrorFailedToOpenFile: | ||||||
|  |         QMessageBox::critical(this, tr("Unable to open File"), | ||||||
|  |                               tr("Could not open the selected file")); | ||||||
|  |         break; | ||||||
|  |     case Service::AM::InstallStatus::ErrorAborted: | ||||||
|  |         QMessageBox::critical( | ||||||
|  |             this, tr("Installation aborted"), | ||||||
|  |             tr("The installation was aborted. Please see the log for more details")); | ||||||
|  |         break; | ||||||
|  |     case Service::AM::InstallStatus::ErrorInvalid: | ||||||
|  |         QMessageBox::critical(this, tr("Invalid File"), tr("The selected file is not a valid CIA")); | ||||||
|  |         break; | ||||||
|  |     case Service::AM::InstallStatus::ErrorEncrypted: | ||||||
|  |         QMessageBox::critical(this, tr("Encrypted File"), | ||||||
|  |                               tr("The file that you are trying to install must be decrypted " | ||||||
|  |                                  "before being used with Citra. A real 3DS is required.")); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |     delete watcher; | ||||||
|  |     ui.action_Install_CIA->setEnabled(true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void GMainWindow::OnMenuRecentFile() { | void GMainWindow::OnMenuRecentFile() { | ||||||
|     QAction* action = qobject_cast<QAction*>(sender()); |     QAction* action = qobject_cast<QAction*>(sender()); | ||||||
|     assert(action); |     assert(action); | ||||||
|  |  | ||||||
|  | @ -8,24 +8,28 @@ | ||||||
| #include <QMainWindow> | #include <QMainWindow> | ||||||
| #include <QTimer> | #include <QTimer> | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/hle/service/am/am.h" | ||||||
| #include "ui_main.h" | #include "ui_main.h" | ||||||
| 
 | 
 | ||||||
|  | class AboutDialog; | ||||||
| class Config; | class Config; | ||||||
| class EmuThread; | class EmuThread; | ||||||
| class GameList; | class GameList; | ||||||
| class GImageInfo; | class GImageInfo; | ||||||
| class GPUCommandStreamWidget; |  | ||||||
| class GPUCommandListWidget; | class GPUCommandListWidget; | ||||||
|  | class GPUCommandStreamWidget; | ||||||
| class GraphicsBreakPointsWidget; | class GraphicsBreakPointsWidget; | ||||||
| class GraphicsTracingWidget; | class GraphicsTracingWidget; | ||||||
| class GraphicsVertexShaderWidget; | class GraphicsVertexShaderWidget; | ||||||
| class GRenderWindow; | class GRenderWindow; | ||||||
| class MicroProfileDialog; | class MicroProfileDialog; | ||||||
| class ProfilerWidget; | class ProfilerWidget; | ||||||
|  | template <typename> | ||||||
|  | class QFutureWatcher; | ||||||
|  | class QProgressBar; | ||||||
| class RegistersWidget; | class RegistersWidget; | ||||||
| class Updater; | class Updater; | ||||||
| class WaitTreeWidget; | class WaitTreeWidget; | ||||||
| class AboutDialog; |  | ||||||
| 
 | 
 | ||||||
| class GMainWindow : public QMainWindow { | class GMainWindow : public QMainWindow { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
|  | @ -64,6 +68,7 @@ signals: | ||||||
|      * system emulation handles and memory are still valid, but are about become invalid. |      * system emulation handles and memory are still valid, but are about become invalid. | ||||||
|      */ |      */ | ||||||
|     void EmulationStopping(); |     void EmulationStopping(); | ||||||
|  |     void UpdateProgress(size_t written, size_t total); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void InitializeWidgets(); |     void InitializeWidgets(); | ||||||
|  | @ -125,6 +130,9 @@ private slots: | ||||||
|     void OnGameListLoadFile(QString game_path); |     void OnGameListLoadFile(QString game_path); | ||||||
|     void OnGameListOpenSaveFolder(u64 program_id); |     void OnGameListOpenSaveFolder(u64 program_id); | ||||||
|     void OnMenuLoadFile(); |     void OnMenuLoadFile(); | ||||||
|  |     void OnMenuInstallCIA(); | ||||||
|  |     void OnUpdateProgress(size_t written, size_t total); | ||||||
|  |     void OnCIAInstallFinished(); | ||||||
|     /// Called whenever a user selects the "File->Select Game List Root" menu item
 |     /// Called whenever a user selects the "File->Select Game List Root" menu item
 | ||||||
|     void OnMenuSelectGameListRoot(); |     void OnMenuSelectGameListRoot(); | ||||||
|     void OnMenuRecentFile(); |     void OnMenuRecentFile(); | ||||||
|  | @ -149,8 +157,10 @@ private: | ||||||
| 
 | 
 | ||||||
|     GRenderWindow* render_window; |     GRenderWindow* render_window; | ||||||
|     GameList* game_list; |     GameList* game_list; | ||||||
|  |     QFutureWatcher<Service::AM::InstallStatus>* watcher = nullptr; | ||||||
| 
 | 
 | ||||||
|     // Status bar elements
 |     // Status bar elements
 | ||||||
|  |     QProgressBar* progress_bar = nullptr; | ||||||
|     QLabel* message_label = nullptr; |     QLabel* message_label = nullptr; | ||||||
|     QLabel* emu_speed_label = nullptr; |     QLabel* emu_speed_label = nullptr; | ||||||
|     QLabel* game_fps_label = nullptr; |     QLabel* game_fps_label = nullptr; | ||||||
|  | @ -185,3 +195,5 @@ protected: | ||||||
|     void dragEnterEvent(QDragEnterEvent* event) override; |     void dragEnterEvent(QDragEnterEvent* event) override; | ||||||
|     void dragMoveEvent(QDragMoveEvent* event) override; |     void dragMoveEvent(QDragMoveEvent* event) override; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | Q_DECLARE_METATYPE(size_t); | ||||||
|  |  | ||||||
|  | @ -58,6 +58,7 @@ | ||||||
|      </property> |      </property> | ||||||
|     </widget> |     </widget> | ||||||
|     <addaction name="action_Load_File"/> |     <addaction name="action_Load_File"/> | ||||||
|  |     <addaction name="action_Install_CIA"/> | ||||||
|     <addaction name="separator"/> |     <addaction name="separator"/> | ||||||
|     <addaction name="action_Select_Game_List_Root"/> |     <addaction name="action_Select_Game_List_Root"/> | ||||||
|     <addaction name="menu_recent_files"/> |     <addaction name="menu_recent_files"/> | ||||||
|  | @ -112,6 +113,11 @@ | ||||||
|     <string>Load File...</string> |     <string>Load File...</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|  |   <action name="action_Install_CIA"> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Install CIA...</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|   <action name="action_Load_Symbol_Map"> |   <action name="action_Load_Symbol_Map"> | ||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Load Symbol Map...</string> |     <string>Load Symbol Map...</string> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue