aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei <bunneidev@gmail.com>2015-04-16 23:31:14 -0400
committerGravatar bunnei <bunneidev@gmail.com>2015-05-01 18:27:00 -0400
commit28df8dbfeb17cf5a002a5504a6bd2ba5091bf07c (patch)
tree57733ea06f6594a5fd4ed7b191130b963895deb2 /src
parentd5665fea89dc2684e145e82a1b07086f11a13a65 (diff)
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 c2b7ba0e..fa4e976f 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -30,21 +30,19 @@
EmuThread::EmuThread(GRenderWindow* render_window) :
exec_cpu_step(false), cpu_running(false), stop_run(false), render_window(render_window) {
+ shutdown_event.Reset();
connect(this, SIGNAL(started()), render_window, SLOT(moveContext()));
}
-void EmuThread::run()
-{
+void EmuThread::run() {
stop_run = false;
// holds whether the cpu was running during the last iteration,
// so that the DebugModeLeft signal can be emitted before the
// next execution step
bool was_active = false;
- while (!stop_run)
- {
- if (cpu_running)
- {
+ while (!stop_run) {
+ if (cpu_running) {
if (!was_active)
emit DebugModeLeft();
@@ -53,9 +51,7 @@ void EmuThread::run()
was_active = cpu_running || exec_cpu_step;
if (!was_active)
emit DebugModeEntered();
- }
- else if (exec_cpu_step)
- {
+ } else if (exec_cpu_step) {
if (!was_active)
emit DebugModeLeft();
@@ -67,15 +63,14 @@ void EmuThread::run()
was_active = false;
}
}
+
render_window->moveContext();
- Core::Stop();
+ shutdown_event.Set();
}
-void EmuThread::Stop()
-{
- if (!isRunning())
- {
+void EmuThread::Stop() {
+ if (!isRunning()) {
LOG_WARNING(Frontend, "EmuThread::Stop called while emu thread wasn't running, returning...");
return;
}
@@ -88,23 +83,19 @@ void EmuThread::Stop()
// TODO: Waiting here is just a bad workaround for retarded shutdown logic.
wait(1000);
- if (isRunning())
- {
+ if (isRunning()) {
LOG_WARNING(Frontend, "EmuThread still running, terminating...");
quit();
// TODO: Waiting 50 seconds can be necessary if the logging subsystem has a lot of spam
// queued... This should be fixed.
wait(50000);
- if (isRunning())
- {
+ if (isRunning()) {
LOG_CRITICAL(Frontend, "EmuThread STILL running, something is wrong here...");
terminate();
}
}
LOG_INFO(Frontend, "EmuThread stopped");
-
- System::Shutdown();
}
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index 8083d275..f6f09773 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -9,6 +9,7 @@
#include "common/common.h"
#include "common/emu_window.h"
+#include "common/thread.h"
class QScreen;
class QKeyEvent;
@@ -37,20 +38,31 @@ public:
void ExecStep() { exec_cpu_step = true; }
/**
- * Allow the CPU to continue processing instructions without interruption
+ * Sets whether the CPU is running
*
* @note This function is thread-safe
*/
void SetCpuRunning(bool running) { cpu_running = running; }
/**
- * Allow the CPU to continue processing instructions without interruption
- *
- * @note This function is thread-safe
- */
+ * Allow the CPU to continue processing instructions without interruption
+ *
+ * @note This function is thread-safe
+ */
bool IsCpuRunning() { return cpu_running; }
+ /**
+ * Shutdown (permantently stops) the CPU
+ */
+ void ShutdownCpu() { stop_run = true; };
+
+ /**
+ * Waits for the CPU shutdown to complete
+ */
+ void WaitForCpuShutdown() { shutdown_event.Wait(); }
+
+
public slots:
/**
* Stop emulation and wait for the thread to finish.
@@ -71,6 +83,8 @@ private:
GRenderWindow* render_window;
+ Common::Event shutdown_event;
+
signals:
/**
* Emitted when the CPU has halted execution
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 9f9ebc91..fe1dac62 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -57,7 +57,6 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
render_window = new GRenderWindow(this, *this);
render_window->hide();
- emu_thread = new EmuThread(render_window);
profilerWidget = new ProfilerWidget(this);
addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
@@ -197,9 +196,9 @@ void GMainWindow::OnDisplayTitleBars(bool show)
}
}
-void GMainWindow::BootGame(std::string filename)
-{
+void GMainWindow::BootGame(std::string filename) {
LOG_INFO(Frontend, "Citra starting...\n");
+
System::Init(render_window);
// Load a game or die...
@@ -211,6 +210,7 @@ void GMainWindow::BootGame(std::string filename)
registersWidget->OnDebugModeEntered();
callstackWidget->OnDebugModeEntered();
+ emu_thread = new EmuThread(render_window);
emu_thread->start();
render_window->show();
@@ -248,14 +248,22 @@ void GMainWindow::OnPauseGame()
ui.action_Stop->setEnabled(true);
}
-void GMainWindow::OnStopGame()
-{
+void GMainWindow::OnStopGame() {
emu_thread->SetCpuRunning(false);
- // TODO: Shutdown core
+
+ emu_thread->ShutdownCpu();
+ emu_thread->WaitForCpuShutdown();
+ emu_thread->Stop();
+
+ delete emu_thread;
+
+ System::Shutdown();
ui.action_Start->setEnabled(true);
ui.action_Pause->setEnabled(false);
ui.action_Stop->setEnabled(false);
+
+ render_window->hide();
}
void GMainWindow::OnOpenHotkeysDialog()