summaryrefslogtreecommitdiff
path: root/src/citra_qt/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/citra_qt/main.cpp')
-rw-r--r--src/citra_qt/main.cpp176
1 files changed, 56 insertions, 120 deletions
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 32cceaf7e..2ca1e51f6 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <clocale> 5#include <clocale>
6#include <memory>
6#include <thread> 7#include <thread>
7 8
8#include <QDesktopWidget> 9#include <QDesktopWidget>
@@ -13,9 +14,11 @@
13 14
14#include "citra_qt/bootmanager.h" 15#include "citra_qt/bootmanager.h"
15#include "citra_qt/config.h" 16#include "citra_qt/config.h"
17#include "citra_qt/configure_dialog.h"
16#include "citra_qt/game_list.h" 18#include "citra_qt/game_list.h"
17#include "citra_qt/hotkeys.h" 19#include "citra_qt/hotkeys.h"
18#include "citra_qt/main.h" 20#include "citra_qt/main.h"
21#include "citra_qt/ui_settings.h"
19 22
20// Debugger 23// Debugger
21#include "citra_qt/debugger/callstack.h" 24#include "citra_qt/debugger/callstack.h"
@@ -30,7 +33,6 @@
30#include "citra_qt/debugger/ramview.h" 33#include "citra_qt/debugger/ramview.h"
31#include "citra_qt/debugger/registers.h" 34#include "citra_qt/debugger/registers.h"
32 35
33#include "common/make_unique.h"
34#include "common/microprofile.h" 36#include "common/microprofile.h"
35#include "common/platform.h" 37#include "common/platform.h"
36#include "common/scm_rev.h" 38#include "common/scm_rev.h"
@@ -50,12 +52,10 @@
50 52
51#include "video_core/video_core.h" 53#include "video_core/video_core.h"
52 54
53GMainWindow::GMainWindow() : emu_thread(nullptr) 55GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr)
54{ 56{
55 Pica::g_debug_context = Pica::DebugContext::Construct(); 57 Pica::g_debug_context = Pica::DebugContext::Construct();
56 58
57 Config config;
58
59 ui.setupUi(this); 59 ui.setupUi(this);
60 statusBar()->hide(); 60 statusBar()->hide();
61 61
@@ -133,33 +133,18 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
133 setGeometry(x, y, w, h); 133 setGeometry(x, y, w, h);
134 134
135 // Restore UI state 135 // Restore UI state
136 QSettings settings; 136 restoreGeometry(UISettings::values.geometry);
137 137 restoreState(UISettings::values.state);
138 settings.beginGroup("UILayout"); 138 render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
139 restoreGeometry(settings.value("geometry").toByteArray()); 139 microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
140 restoreState(settings.value("state").toByteArray()); 140 microProfileDialog->setVisible(UISettings::values.microprofile_visible);
141 render_window->restoreGeometry(settings.value("geometryRenderWindow").toByteArray());
142 microProfileDialog->restoreGeometry(settings.value("microProfileDialogGeometry").toByteArray());
143 microProfileDialog->setVisible(settings.value("microProfileDialogVisible").toBool());
144 settings.endGroup();
145
146 game_list->LoadInterfaceLayout(settings);
147
148 ui.action_Use_Gdbstub->setChecked(Settings::values.use_gdbstub);
149 SetGdbstubEnabled(ui.action_Use_Gdbstub->isChecked());
150
151 GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port));
152
153 ui.action_Use_Hardware_Renderer->setChecked(Settings::values.use_hw_renderer);
154 SetHardwareRendererEnabled(ui.action_Use_Hardware_Renderer->isChecked());
155 141
156 ui.action_Use_Shader_JIT->setChecked(Settings::values.use_shader_jit); 142 game_list->LoadInterfaceLayout();
157 SetShaderJITEnabled(ui.action_Use_Shader_JIT->isChecked());
158 143
159 ui.action_Single_Window_Mode->setChecked(settings.value("singleWindowMode", true).toBool()); 144 ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode);
160 ToggleWindowMode(); 145 ToggleWindowMode();
161 146
162 ui.actionDisplay_widget_title_bars->setChecked(settings.value("displayTitleBars", true).toBool()); 147 ui.actionDisplay_widget_title_bars->setChecked(UISettings::values.display_titlebar);
163 OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked()); 148 OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked());
164 149
165 // Prepare actions for recent files 150 // Prepare actions for recent files
@@ -172,21 +157,16 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
172 } 157 }
173 UpdateRecentFiles(); 158 UpdateRecentFiles();
174 159
175 confirm_before_closing = settings.value("confirmClose", true).toBool();
176
177 // Setup connections 160 // Setup connections
178 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString))); 161 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)), Qt::DirectConnection);
179 connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile())); 162 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(OnConfigure()));
163 connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()),Qt::DirectConnection);
180 connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap())); 164 connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap()));
181 connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this, SLOT(OnMenuSelectGameListRoot())); 165 connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this, SLOT(OnMenuSelectGameListRoot()));
182 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame())); 166 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame()));
183 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame())); 167 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame()));
184 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame())); 168 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame()));
185 connect(ui.action_Use_Hardware_Renderer, SIGNAL(triggered(bool)), this, SLOT(SetHardwareRendererEnabled(bool)));
186 connect(ui.action_Use_Shader_JIT, SIGNAL(triggered(bool)), this, SLOT(SetShaderJITEnabled(bool)));
187 connect(ui.action_Use_Gdbstub, SIGNAL(triggered(bool)), this, SLOT(SetGdbstubEnabled(bool)));
188 connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode())); 169 connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
189 connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
190 170
191 connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget, SLOT(OnEmulationStarting(EmuThread*))); 171 connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget, SLOT(OnEmulationStarting(EmuThread*)));
192 connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping())); 172 connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping()));
@@ -201,7 +181,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
201 // Setup hotkeys 181 // Setup hotkeys
202 RegisterHotkey("Main Window", "Load File", QKeySequence::Open); 182 RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
203 RegisterHotkey("Main Window", "Start Emulation"); 183 RegisterHotkey("Main Window", "Start Emulation");
204 LoadHotkeys(settings); 184 LoadHotkeys();
205 185
206 connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this, SLOT(OnMenuLoadFile())); 186 connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this, SLOT(OnMenuLoadFile()));
207 connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame())); 187 connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame()));
@@ -211,7 +191,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
211 191
212 show(); 192 show();
213 193
214 game_list->PopulateAsync(settings.value("gameListRootDir", ".").toString(), settings.value("gameListDeepScan", false).toBool()); 194 game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
215 195
216 QStringList args = QApplication::arguments(); 196 QStringList args = QApplication::arguments();
217 if (args.length() >= 2) { 197 if (args.length() >= 2) {
@@ -319,7 +299,7 @@ void GMainWindow::BootGame(const std::string& filename) {
319 return; 299 return;
320 300
321 // Create and start the emulation thread 301 // Create and start the emulation thread
322 emu_thread = Common::make_unique<EmuThread>(render_window); 302 emu_thread = std::make_unique<EmuThread>(render_window);
323 emit EmulationStarting(emu_thread.get()); 303 emit EmulationStarting(emu_thread.get());
324 render_window->moveContext(); 304 render_window->moveContext();
325 emu_thread->start(); 305 emu_thread->start();
@@ -375,32 +355,24 @@ void GMainWindow::ShutdownGame() {
375 emulation_running = false; 355 emulation_running = false;
376} 356}
377 357
378void GMainWindow::StoreRecentFile(const std::string& filename) 358void GMainWindow::StoreRecentFile(const std::string& filename) {
379{ 359 UISettings::values.recent_files.prepend(QString::fromStdString(filename));
380 QSettings settings; 360 UISettings::values.recent_files.removeDuplicates();
381 QStringList recent_files = settings.value("recentFiles").toStringList(); 361 while (UISettings::values.recent_files.size() > max_recent_files_item) {
382 recent_files.prepend(QString::fromStdString(filename)); 362 UISettings::values.recent_files.removeLast();
383 recent_files.removeDuplicates();
384 while (recent_files.size() > max_recent_files_item) {
385 recent_files.removeLast();
386 } 363 }
387 364
388 settings.setValue("recentFiles", recent_files);
389
390 UpdateRecentFiles(); 365 UpdateRecentFiles();
391} 366}
392 367
393void GMainWindow::UpdateRecentFiles() { 368void GMainWindow::UpdateRecentFiles() {
394 QSettings settings; 369 unsigned int num_recent_files = std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item));
395 QStringList recent_files = settings.value("recentFiles").toStringList();
396
397 unsigned int num_recent_files = std::min(recent_files.size(), static_cast<int>(max_recent_files_item));
398 370
399 for (unsigned int i = 0; i < num_recent_files; i++) { 371 for (unsigned int i = 0; i < num_recent_files; i++) {
400 QString text = QString("&%1. %2").arg(i + 1).arg(QFileInfo(recent_files[i]).fileName()); 372 QString text = QString("&%1. %2").arg(i + 1).arg(QFileInfo(UISettings::values.recent_files[i]).fileName());
401 actions_recent_files[i]->setText(text); 373 actions_recent_files[i]->setText(text);
402 actions_recent_files[i]->setData(recent_files[i]); 374 actions_recent_files[i]->setData(UISettings::values.recent_files[i]);
403 actions_recent_files[i]->setToolTip(recent_files[i]); 375 actions_recent_files[i]->setToolTip(UISettings::values.recent_files[i]);
404 actions_recent_files[i]->setVisible(true); 376 actions_recent_files[i]->setVisible(true);
405 } 377 }
406 378
@@ -417,40 +389,32 @@ void GMainWindow::UpdateRecentFiles() {
417} 389}
418 390
419void GMainWindow::OnGameListLoadFile(QString game_path) { 391void GMainWindow::OnGameListLoadFile(QString game_path) {
420 BootGame(game_path.toLocal8Bit().data()); 392 BootGame(game_path.toStdString());
421} 393}
422 394
423void GMainWindow::OnMenuLoadFile() { 395void GMainWindow::OnMenuLoadFile() {
424 QSettings settings; 396 QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), UISettings::values.roms_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)"));
425 QString rom_path = settings.value("romsPath", QString()).toString();
426
427 QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), rom_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)"));
428 if (!filename.isEmpty()) { 397 if (!filename.isEmpty()) {
429 settings.setValue("romsPath", QFileInfo(filename).path()); 398 UISettings::values.roms_path = QFileInfo(filename).path();
430 399
431 BootGame(filename.toLocal8Bit().data()); 400 BootGame(filename.toStdString());
432 } 401 }
433} 402}
434 403
435void GMainWindow::OnMenuLoadSymbolMap() { 404void GMainWindow::OnMenuLoadSymbolMap() {
436 QSettings settings; 405 QString filename = QFileDialog::getOpenFileName(this, tr("Load Symbol Map"), UISettings::values.symbols_path, tr("Symbol map (*)"));
437 QString symbol_path = settings.value("symbolsPath", QString()).toString();
438
439 QString filename = QFileDialog::getOpenFileName(this, tr("Load Symbol Map"), symbol_path, tr("Symbol map (*)"));
440 if (!filename.isEmpty()) { 406 if (!filename.isEmpty()) {
441 settings.setValue("symbolsPath", QFileInfo(filename).path()); 407 UISettings::values.symbols_path = QFileInfo(filename).path();
442 408
443 LoadSymbolMap(filename.toLocal8Bit().data()); 409 LoadSymbolMap(filename.toStdString());
444 } 410 }
445} 411}
446 412
447void GMainWindow::OnMenuSelectGameListRoot() { 413void GMainWindow::OnMenuSelectGameListRoot() {
448 QSettings settings;
449
450 QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); 414 QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory"));
451 if (!dir_path.isEmpty()) { 415 if (!dir_path.isEmpty()) {
452 settings.setValue("gameListRootDir", dir_path); 416 UISettings::values.gamedir = dir_path;
453 game_list->PopulateAsync(dir_path, settings.value("gameListDeepScan").toBool()); 417 game_list->PopulateAsync(dir_path, UISettings::values.gamedir_deepscan);
454 } 418 }
455} 419}
456 420
@@ -461,15 +425,12 @@ void GMainWindow::OnMenuRecentFile() {
461 QString filename = action->data().toString(); 425 QString filename = action->data().toString();
462 QFileInfo file_info(filename); 426 QFileInfo file_info(filename);
463 if (file_info.exists()) { 427 if (file_info.exists()) {
464 BootGame(filename.toLocal8Bit().data()); 428 BootGame(filename.toStdString());
465 } else { 429 } else {
466 // Display an error message and remove the file from the list. 430 // Display an error message and remove the file from the list.
467 QMessageBox::information(this, tr("File not found"), tr("File \"%1\" not found").arg(filename)); 431 QMessageBox::information(this, tr("File not found"), tr("File \"%1\" not found").arg(filename));
468 432
469 QSettings settings; 433 UISettings::values.recent_files.removeOne(filename);
470 QStringList recent_files = settings.value("recentFiles").toStringList();
471 recent_files.removeOne(filename);
472 settings.setValue("recentFiles", recent_files);
473 UpdateRecentFiles(); 434 UpdateRecentFiles();
474 } 435 }
475} 436}
@@ -496,31 +457,6 @@ void GMainWindow::OnStopGame() {
496 ShutdownGame(); 457 ShutdownGame();
497} 458}
498 459
499void GMainWindow::OnOpenHotkeysDialog() {
500 GHotkeysDialog dialog(this);
501 dialog.exec();
502}
503
504void GMainWindow::SetHardwareRendererEnabled(bool enabled) {
505 VideoCore::g_hw_renderer_enabled = enabled;
506
507 Config config;
508 Settings::values.use_hw_renderer = enabled;
509 config.Save();
510}
511
512void GMainWindow::SetGdbstubEnabled(bool enabled) {
513 GDBStub::ToggleServer(enabled);
514}
515
516void GMainWindow::SetShaderJITEnabled(bool enabled) {
517 VideoCore::g_shader_jit_enabled = enabled;
518
519 Config config;
520 Settings::values.use_shader_jit = enabled;
521 config.Save();
522}
523
524void GMainWindow::ToggleWindowMode() { 460void GMainWindow::ToggleWindowMode() {
525 if (ui.action_Single_Window_Mode->isChecked()) { 461 if (ui.action_Single_Window_Mode->isChecked()) {
526 // Render in the main window... 462 // Render in the main window...
@@ -547,11 +483,17 @@ void GMainWindow::ToggleWindowMode() {
547} 483}
548 484
549void GMainWindow::OnConfigure() { 485void GMainWindow::OnConfigure() {
550 //GControllerConfigDialog* dialog = new GControllerConfigDialog(controller_ports, this); 486 ConfigureDialog configureDialog(this);
487 auto result = configureDialog.exec();
488 if (result == QDialog::Accepted)
489 {
490 configureDialog.applyConfiguration();
491 config->Save();
492 }
551} 493}
552 494
553bool GMainWindow::ConfirmClose() { 495bool GMainWindow::ConfirmClose() {
554 if (emu_thread == nullptr || !confirm_before_closing) 496 if (emu_thread == nullptr || !UISettings::values.confirm_before_closing)
555 return true; 497 return true;
556 498
557 auto answer = QMessageBox::question(this, tr("Citra"), 499 auto answer = QMessageBox::question(this, tr("Citra"),
@@ -566,23 +508,18 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
566 return; 508 return;
567 } 509 }
568 510
569 // Save window layout 511 UISettings::values.geometry = saveGeometry();
570 QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra"); 512 UISettings::values.state = saveState();
513 UISettings::values.renderwindow_geometry = render_window->saveGeometry();
514 UISettings::values.microprofile_geometry = microProfileDialog->saveGeometry();
515 UISettings::values.microprofile_visible = microProfileDialog->isVisible();
571 516
572 settings.beginGroup("UILayout"); 517 UISettings::values.single_window_mode = ui.action_Single_Window_Mode->isChecked();
573 settings.setValue("geometry", saveGeometry()); 518 UISettings::values.display_titlebar = ui.actionDisplay_widget_title_bars->isChecked();
574 settings.setValue("state", saveState()); 519 UISettings::values.first_start = false;
575 settings.setValue("geometryRenderWindow", render_window->saveGeometry());
576 settings.setValue("microProfileDialogGeometry", microProfileDialog->saveGeometry());
577 settings.setValue("microProfileDialogVisible", microProfileDialog->isVisible());
578 settings.endGroup();
579 520
580 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked()); 521 game_list->SaveInterfaceLayout();
581 settings.setValue("displayTitleBars", ui.actionDisplay_widget_title_bars->isChecked()); 522 SaveHotkeys();
582 settings.setValue("firstStart", false);
583 settings.setValue("confirmClose", confirm_before_closing);
584 game_list->SaveInterfaceLayout(settings);
585 SaveHotkeys(settings);
586 523
587 // Shutdown session if the emu thread is active... 524 // Shutdown session if the emu thread is active...
588 if (emu_thread != nullptr) 525 if (emu_thread != nullptr)
@@ -607,7 +544,6 @@ int main(int argc, char* argv[]) {
607 }); 544 });
608 545
609 // Init settings params 546 // Init settings params
610 QSettings::setDefaultFormat(QSettings::IniFormat);
611 QCoreApplication::setOrganizationName("Citra team"); 547 QCoreApplication::setOrganizationName("Citra team");
612 QCoreApplication::setApplicationName("Citra"); 548 QCoreApplication::setApplicationName("Citra");
613 549