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.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
new file mode 100644
index 000000000..d7104eb02
--- /dev/null
+++ b/src/citra_qt/main.cpp
@@ -0,0 +1,230 @@
1#include <QtGui>
2#include <QDesktopWidget>
3#include <QFileDialog>
4#include "qhexedit.h"
5#include "main.hxx"
6
7#include "common.h"
8#include "platform.h"
9#if EMU_PLATFORM == PLATFORM_LINUX
10#include <unistd.h>
11#endif
12
13#include "bootmanager.hxx"
14#include "hotkeys.hxx"
15
16//debugger
17#include "disasm.hxx"
18#include "cpu_regs.hxx"
19#include "callstack.hxx"
20#include "ramview.hxx"
21
22#include "system.h"
23#include "loader.h"
24#include "core.h"
25#include "version.h"
26
27
28GMainWindow::GMainWindow()
29{
30 ui.setupUi(this);
31 statusBar()->hide();
32
33 render_window = new GRenderWindow;
34 render_window->hide();
35
36 disasm = new GDisAsmView(this, render_window->GetEmuThread());
37 addDockWidget(Qt::BottomDockWidgetArea, disasm);
38 disasm->hide();
39
40 arm_regs = new GARM11RegsView(this);
41 addDockWidget(Qt::RightDockWidgetArea, arm_regs);
42 arm_regs->hide();
43
44 QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging"));
45 debug_menu->addAction(disasm->toggleViewAction());
46 debug_menu->addAction(arm_regs->toggleViewAction());
47
48 // Set default UI state
49 // geometry: 55% of the window contents are in the upper screen half, 45% in the lower half
50 QDesktopWidget* desktop = ((QApplication*)QApplication::instance())->desktop();
51 QRect screenRect = desktop->screenGeometry(this);
52 int x, y, w, h;
53 w = screenRect.width() * 2 / 3;
54 h = screenRect.height() / 2;
55 x = (screenRect.x() + screenRect.width()) / 2 - w / 2;
56 y = (screenRect.y() + screenRect.height()) / 2 - h * 55 / 100;
57 setGeometry(x, y, w, h);
58
59
60 // Restore UI state
61 QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra");
62 restoreGeometry(settings.value("geometry").toByteArray());
63 restoreState(settings.value("state").toByteArray());
64 render_window->restoreGeometry(settings.value("geometryRenderWindow").toByteArray());
65
66 ui.action_Single_Window_Mode->setChecked(settings.value("singleWindowMode", false).toBool());
67 SetupEmuWindowMode();
68
69 // Setup connections
70 connect(ui.action_load_elf, SIGNAL(triggered()), this, SLOT(OnMenuLoadELF()));
71 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame()));
72 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame()));
73 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame()));
74 connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(SetupEmuWindowMode()));
75 connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog()));
76
77 // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues
78 connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), disasm, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
79 connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), arm_regs, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection);
80
81 // Setup hotkeys
82 RegisterHotkey("Main Window", "Load Image", QKeySequence::Open);
83 RegisterHotkey("Main Window", "Start Emulation");
84 LoadHotkeys(settings);
85
86 connect(GetHotkey("Main Window", "Load Image", this), SIGNAL(activated()), this, SLOT(OnMenuLoadImage()));
87 connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame()));
88
89 show();
90
91 System::Init(render_window);
92}
93
94GMainWindow::~GMainWindow()
95{
96 // will get automatically deleted otherwise
97 if (render_window->parent() == NULL)
98 delete render_window;
99}
100
101void GMainWindow::BootGame(const char* filename)
102{
103 render_window->DoneCurrent(); // make sure EmuThread can access GL context
104 render_window->GetEmuThread().SetFilename(filename);
105
106 NOTICE_LOG(MASTER_LOG, "citra starting...\n");
107
108 if (Core::Init(/*render_window*/)) {
109 ERROR_LOG(MASTER_LOG, "core initialization failed, exiting...");
110 Core::Stop();
111 exit(1);
112 }
113
114 // Load a game or die...
115 std::string boot_filename = filename;
116 std::string error_str;
117 bool res = Loader::LoadFile(boot_filename, &error_str);
118
119 if (!res) {
120 ERROR_LOG(BOOT, "Failed to load ROM: %s", error_str.c_str());
121 }
122
123 disasm->Init();
124 arm_regs->OnCPUStepped();
125
126 render_window->GetEmuThread().start();
127
128 SetupEmuWindowMode();
129 render_window->show();
130}
131
132void GMainWindow::OnMenuLoadELF()
133{
134 QString filename = QFileDialog::getOpenFileName(this, tr("Load ELF"), QString(), QString());
135 if (filename.size())
136 BootGame(filename.toLatin1().data());
137}
138
139void GMainWindow::OnStartGame()
140{
141 render_window->show();
142 render_window->GetEmuThread().SetCpuRunning(true);
143
144 ui.action_Start->setEnabled(false);
145 ui.action_Pause->setEnabled(true);
146 ui.action_Stop->setEnabled(true);
147}
148
149void GMainWindow::OnPauseGame()
150{
151 render_window->GetEmuThread().SetCpuRunning(false);
152
153 ui.action_Start->setEnabled(true);
154 ui.action_Pause->setEnabled(false);
155 ui.action_Stop->setEnabled(true);
156}
157
158void GMainWindow::OnStopGame()
159{
160 render_window->GetEmuThread().SetCpuRunning(false);
161
162 ui.action_Start->setEnabled(true);
163 ui.action_Pause->setEnabled(false);
164 ui.action_Stop->setEnabled(false);
165}
166
167void GMainWindow::OnOpenHotkeysDialog()
168{
169 GHotkeysDialog dialog(this);
170 dialog.exec();
171}
172
173
174void GMainWindow::SetupEmuWindowMode()
175{
176 //if (!render_window->GetEmuThread().isRunning())
177 // return;
178
179 bool enable = ui.action_Single_Window_Mode->isChecked();
180 if (enable && render_window->parent() == NULL) // switch to single window mode
181 {
182 render_window->BackupGeometry();
183 ui.horizontalLayout->addWidget(render_window);
184 render_window->setVisible(true);
185 render_window->DoneCurrent();
186 }
187 else if (!enable && render_window->parent() != NULL) // switch to multiple windows mode
188 {
189 ui.horizontalLayout->removeWidget(render_window);
190 render_window->setParent(NULL);
191 render_window->setVisible(true);
192 render_window->DoneCurrent();
193 render_window->RestoreGeometry();
194 }
195}
196
197void GMainWindow::OnConfigure()
198{
199 //GControllerConfigDialog* dialog = new GControllerConfigDialog(controller_ports, this);
200}
201
202void GMainWindow::closeEvent(QCloseEvent* event)
203{
204 // Save window layout
205 QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Citra team", "Citra");
206 settings.setValue("geometry", saveGeometry());
207 settings.setValue("state", saveState());
208 settings.setValue("geometryRenderWindow", render_window->saveGeometry());
209 settings.setValue("singleWindowMode", ui.action_Single_Window_Mode->isChecked());
210 settings.setValue("firstStart", false);
211 SaveHotkeys(settings);
212
213 render_window->close();
214
215 QWidget::closeEvent(event);
216}
217
218#ifdef main
219#undef main
220#endif
221
222int __cdecl main(int argc, char* argv[])
223{
224 QApplication::setAttribute(Qt::AA_X11InitThreads);
225 QApplication app(argc, argv);
226 GMainWindow main_window;
227
228 main_window.show();
229 return app.exec();
230}