summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-04-16 23:31:14 -0400
committerGravatar bunnei2015-05-01 18:27:00 -0400
commit28df8dbfeb17cf5a002a5504a6bd2ba5091bf07c (patch)
tree57733ea06f6594a5fd4ed7b191130b963895deb2 /src
parentEmuThread: Remove unused filename attribute. (diff)
downloadyuzu-28df8dbfeb17cf5a002a5504a6bd2ba5091bf07c.tar.gz
yuzu-28df8dbfeb17cf5a002a5504a6bd2ba5091bf07c.tar.xz
yuzu-28df8dbfeb17cf5a002a5504a6bd2ba5091bf07c.zip
Qt: Create emu thread on bootup, kill it on shutdown.
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/bootmanager.cpp31
-rw-r--r--src/citra_qt/bootmanager.h24
-rw-r--r--src/citra_qt/main.cpp20
3 files changed, 44 insertions, 31 deletions
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index c2b7ba0e2..fa4e976f4 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -30,21 +30,19 @@
30EmuThread::EmuThread(GRenderWindow* render_window) : 30EmuThread::EmuThread(GRenderWindow* render_window) :
31 exec_cpu_step(false), cpu_running(false), stop_run(false), render_window(render_window) { 31 exec_cpu_step(false), cpu_running(false), stop_run(false), render_window(render_window) {
32 32
33 shutdown_event.Reset();
33 connect(this, SIGNAL(started()), render_window, SLOT(moveContext())); 34 connect(this, SIGNAL(started()), render_window, SLOT(moveContext()));
34} 35}
35 36
36void EmuThread::run() 37void EmuThread::run() {
37{
38 stop_run = false; 38 stop_run = false;
39 39
40 // holds whether the cpu was running during the last iteration, 40 // holds whether the cpu was running during the last iteration,
41 // so that the DebugModeLeft signal can be emitted before the 41 // so that the DebugModeLeft signal can be emitted before the
42 // next execution step 42 // next execution step
43 bool was_active = false; 43 bool was_active = false;
44 while (!stop_run) 44 while (!stop_run) {
45 { 45 if (cpu_running) {
46 if (cpu_running)
47 {
48 if (!was_active) 46 if (!was_active)
49 emit DebugModeLeft(); 47 emit DebugModeLeft();
50 48
@@ -53,9 +51,7 @@ void EmuThread::run()
53 was_active = cpu_running || exec_cpu_step; 51 was_active = cpu_running || exec_cpu_step;
54 if (!was_active) 52 if (!was_active)
55 emit DebugModeEntered(); 53 emit DebugModeEntered();
56 } 54 } else if (exec_cpu_step) {
57 else if (exec_cpu_step)
58 {
59 if (!was_active) 55 if (!was_active)
60 emit DebugModeLeft(); 56 emit DebugModeLeft();
61 57
@@ -67,15 +63,14 @@ void EmuThread::run()
67 was_active = false; 63 was_active = false;
68 } 64 }
69 } 65 }
66
70 render_window->moveContext(); 67 render_window->moveContext();
71 68
72 Core::Stop(); 69 shutdown_event.Set();
73} 70}
74 71
75void EmuThread::Stop() 72void EmuThread::Stop() {
76{ 73 if (!isRunning()) {
77 if (!isRunning())
78 {
79 LOG_WARNING(Frontend, "EmuThread::Stop called while emu thread wasn't running, returning..."); 74 LOG_WARNING(Frontend, "EmuThread::Stop called while emu thread wasn't running, returning...");
80 return; 75 return;
81 } 76 }
@@ -88,23 +83,19 @@ void EmuThread::Stop()
88 83
89 // TODO: Waiting here is just a bad workaround for retarded shutdown logic. 84 // TODO: Waiting here is just a bad workaround for retarded shutdown logic.
90 wait(1000); 85 wait(1000);
91 if (isRunning()) 86 if (isRunning()) {
92 {
93 LOG_WARNING(Frontend, "EmuThread still running, terminating..."); 87 LOG_WARNING(Frontend, "EmuThread still running, terminating...");
94 quit(); 88 quit();
95 89
96 // TODO: Waiting 50 seconds can be necessary if the logging subsystem has a lot of spam 90 // TODO: Waiting 50 seconds can be necessary if the logging subsystem has a lot of spam
97 // queued... This should be fixed. 91 // queued... This should be fixed.
98 wait(50000); 92 wait(50000);
99 if (isRunning()) 93 if (isRunning()) {
100 {
101 LOG_CRITICAL(Frontend, "EmuThread STILL running, something is wrong here..."); 94 LOG_CRITICAL(Frontend, "EmuThread STILL running, something is wrong here...");
102 terminate(); 95 terminate();
103 } 96 }
104 } 97 }
105 LOG_INFO(Frontend, "EmuThread stopped"); 98 LOG_INFO(Frontend, "EmuThread stopped");
106
107 System::Shutdown();
108} 99}
109 100
110 101
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index 8083d275b..f6f09773c 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -9,6 +9,7 @@
9 9
10#include "common/common.h" 10#include "common/common.h"
11#include "common/emu_window.h" 11#include "common/emu_window.h"
12#include "common/thread.h"
12 13
13class QScreen; 14class QScreen;
14class QKeyEvent; 15class QKeyEvent;
@@ -37,20 +38,31 @@ public:
37 void ExecStep() { exec_cpu_step = true; } 38 void ExecStep() { exec_cpu_step = true; }
38 39
39 /** 40 /**
40 * Allow the CPU to continue processing instructions without interruption 41 * Sets whether the CPU is running
41 * 42 *
42 * @note This function is thread-safe 43 * @note This function is thread-safe
43 */ 44 */
44 void SetCpuRunning(bool running) { cpu_running = running; } 45 void SetCpuRunning(bool running) { cpu_running = running; }
45 46
46 /** 47 /**
47 * Allow the CPU to continue processing instructions without interruption 48 * Allow the CPU to continue processing instructions without interruption
48 * 49 *
49 * @note This function is thread-safe 50 * @note This function is thread-safe
50 */ 51 */
51 bool IsCpuRunning() { return cpu_running; } 52 bool IsCpuRunning() { return cpu_running; }
52 53
53 54
55 /**
56 * Shutdown (permantently stops) the CPU
57 */
58 void ShutdownCpu() { stop_run = true; };
59
60 /**
61 * Waits for the CPU shutdown to complete
62 */
63 void WaitForCpuShutdown() { shutdown_event.Wait(); }
64
65
54public slots: 66public slots:
55 /** 67 /**
56 * Stop emulation and wait for the thread to finish. 68 * Stop emulation and wait for the thread to finish.
@@ -71,6 +83,8 @@ private:
71 83
72 GRenderWindow* render_window; 84 GRenderWindow* render_window;
73 85
86 Common::Event shutdown_event;
87
74signals: 88signals:
75 /** 89 /**
76 * Emitted when the CPU has halted execution 90 * Emitted when the CPU has halted execution
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 9f9ebc918..fe1dac622 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -57,7 +57,6 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
57 57
58 render_window = new GRenderWindow(this, *this); 58 render_window = new GRenderWindow(this, *this);
59 render_window->hide(); 59 render_window->hide();
60 emu_thread = new EmuThread(render_window);
61 60
62 profilerWidget = new ProfilerWidget(this); 61 profilerWidget = new ProfilerWidget(this);
63 addDockWidget(Qt::BottomDockWidgetArea, profilerWidget); 62 addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
@@ -197,9 +196,9 @@ void GMainWindow::OnDisplayTitleBars(bool show)
197 } 196 }
198} 197}
199 198
200void GMainWindow::BootGame(std::string filename) 199void GMainWindow::BootGame(std::string filename) {
201{
202 LOG_INFO(Frontend, "Citra starting...\n"); 200 LOG_INFO(Frontend, "Citra starting...\n");
201
203 System::Init(render_window); 202 System::Init(render_window);
204 203
205 // Load a game or die... 204 // Load a game or die...
@@ -211,6 +210,7 @@ void GMainWindow::BootGame(std::string filename)
211 registersWidget->OnDebugModeEntered(); 210 registersWidget->OnDebugModeEntered();
212 callstackWidget->OnDebugModeEntered(); 211 callstackWidget->OnDebugModeEntered();
213 212
213 emu_thread = new EmuThread(render_window);
214 emu_thread->start(); 214 emu_thread->start();
215 215
216 render_window->show(); 216 render_window->show();
@@ -248,14 +248,22 @@ void GMainWindow::OnPauseGame()
248 ui.action_Stop->setEnabled(true); 248 ui.action_Stop->setEnabled(true);
249} 249}
250 250
251void GMainWindow::OnStopGame() 251void GMainWindow::OnStopGame() {
252{
253 emu_thread->SetCpuRunning(false); 252 emu_thread->SetCpuRunning(false);
254 // TODO: Shutdown core 253
254 emu_thread->ShutdownCpu();
255 emu_thread->WaitForCpuShutdown();
256 emu_thread->Stop();
257
258 delete emu_thread;
259
260 System::Shutdown();
255 261
256 ui.action_Start->setEnabled(true); 262 ui.action_Start->setEnabled(true);
257 ui.action_Pause->setEnabled(false); 263 ui.action_Pause->setEnabled(false);
258 ui.action_Stop->setEnabled(false); 264 ui.action_Stop->setEnabled(false);
265
266 render_window->hide();
259} 267}
260 268
261void GMainWindow::OnOpenHotkeysDialog() 269void GMainWindow::OnOpenHotkeysDialog()