commit
613b0a8df8
|
@ -1,5 +1,6 @@
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "bootmanager.hxx"
|
#include "bootmanager.hxx"
|
||||||
|
@ -19,7 +20,8 @@
|
||||||
|
|
||||||
EmuThread::EmuThread(GRenderWindow* render_window) :
|
EmuThread::EmuThread(GRenderWindow* render_window) :
|
||||||
exec_cpu_step(false), cpu_running(false),
|
exec_cpu_step(false), cpu_running(false),
|
||||||
render_window(render_window), filename("")
|
render_window(render_window), filename(""),
|
||||||
|
stop_run(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +32,8 @@ void EmuThread::SetFilename(std::string filename)
|
||||||
|
|
||||||
void EmuThread::run()
|
void EmuThread::run()
|
||||||
{
|
{
|
||||||
while (true)
|
stop_run = false;
|
||||||
|
while (!stop_run)
|
||||||
{
|
{
|
||||||
for (int tight_loop = 0; tight_loop < 10000; ++tight_loop)
|
for (int tight_loop = 0; tight_loop < 10000; ++tight_loop)
|
||||||
{
|
{
|
||||||
|
@ -40,11 +43,14 @@ void EmuThread::run()
|
||||||
exec_cpu_step = false;
|
exec_cpu_step = false;
|
||||||
|
|
||||||
Core::SingleStep();
|
Core::SingleStep();
|
||||||
if (!cpu_running)
|
if (!cpu_running) {
|
||||||
emit CPUStepped();
|
emit CPUStepped();
|
||||||
|
yieldCurrentThread();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
render_window->moveContext();
|
||||||
|
|
||||||
Core::Stop();
|
Core::Stop();
|
||||||
}
|
}
|
||||||
|
@ -56,17 +62,21 @@ void EmuThread::Stop()
|
||||||
INFO_LOG(MASTER_LOG, "EmuThread::Stop called while emu thread wasn't running, returning...");
|
INFO_LOG(MASTER_LOG, "EmuThread::Stop called while emu thread wasn't running, returning...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
stop_run = true;
|
||||||
|
|
||||||
//core::g_state = core::SYS_DIE;
|
//core::g_state = core::SYS_DIE;
|
||||||
|
|
||||||
wait(1000);
|
wait(500);
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
{
|
{
|
||||||
WARN_LOG(MASTER_LOG, "EmuThread still running, terminating...");
|
WARN_LOG(MASTER_LOG, "EmuThread still running, terminating...");
|
||||||
terminate();
|
quit();
|
||||||
wait(1000);
|
wait(1000);
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
|
{
|
||||||
WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here...");
|
WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here...");
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
INFO_LOG(MASTER_LOG, "EmuThread stopped");
|
INFO_LOG(MASTER_LOG, "EmuThread stopped");
|
||||||
}
|
}
|
||||||
|
@ -77,17 +87,13 @@ void EmuThread::Stop()
|
||||||
class GGLWidgetInternal : public QGLWidget
|
class GGLWidgetInternal : public QGLWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent) : QGLWidget(parent)
|
GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent) : QGLWidget(fmt, parent)
|
||||||
{
|
{
|
||||||
doneCurrent();
|
|
||||||
parent_ = parent;
|
parent_ = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void paintEvent(QPaintEvent* ev)
|
void paintEvent(QPaintEvent* ev)
|
||||||
{
|
{
|
||||||
// Apparently, Windows doesn't display anything if we don't call this here.
|
|
||||||
// TODO: Breaks linux though because we aren't calling doneCurrent() ... -.-
|
|
||||||
// makeCurrent();
|
|
||||||
}
|
}
|
||||||
void resizeEvent(QResizeEvent* ev) {
|
void resizeEvent(QResizeEvent* ev) {
|
||||||
parent_->SetClientAreaWidth(size().width());
|
parent_->SetClientAreaWidth(size().width());
|
||||||
|
@ -118,24 +124,37 @@ GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this
|
||||||
layout->addWidget(child);
|
layout->addWidget(child);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
QObject::connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext()));
|
||||||
|
|
||||||
BackupGeometry();
|
BackupGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GRenderWindow::moveContext()
|
||||||
|
{
|
||||||
|
DoneCurrent();
|
||||||
|
// We need to move GL context to the swapping thread in Qt5
|
||||||
|
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
// If the thread started running, move the GL Context to the new thread. Otherwise, move it back.
|
||||||
|
child->context()->moveToThread((QThread::currentThread() == qApp->thread()) ? &emu_thread : qApp->thread());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
GRenderWindow::~GRenderWindow()
|
GRenderWindow::~GRenderWindow()
|
||||||
{
|
{
|
||||||
emu_thread.Stop();
|
if (emu_thread.isRunning())
|
||||||
|
emu_thread.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::SwapBuffers()
|
void GRenderWindow::SwapBuffers()
|
||||||
{
|
{
|
||||||
child->makeCurrent(); // TODO: Not necessary?
|
// MakeCurrent is already called in renderer_opengl
|
||||||
child->swapBuffers();
|
child->swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::closeEvent(QCloseEvent* event)
|
void GRenderWindow::closeEvent(QCloseEvent* event)
|
||||||
{
|
{
|
||||||
emu_thread.Stop();
|
if (emu_thread.isRunning())
|
||||||
|
emu_thread.Stop();
|
||||||
QWidget::closeEvent(event);
|
QWidget::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,4 +231,5 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event)
|
||||||
if (!key_processed)
|
if (!key_processed)
|
||||||
QWidget::keyPressEvent(event);
|
QWidget::keyPressEvent(event);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
|
#include <atomic>
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "common/emu_window.h"
|
#include "common/emu_window.h"
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ private:
|
||||||
|
|
||||||
bool exec_cpu_step;
|
bool exec_cpu_step;
|
||||||
bool cpu_running;
|
bool cpu_running;
|
||||||
|
std::atomic<bool> stop_run;
|
||||||
|
|
||||||
GRenderWindow* render_window;
|
GRenderWindow* render_window;
|
||||||
|
|
||||||
|
@ -81,6 +83,8 @@ signals:
|
||||||
|
|
||||||
class GRenderWindow : public QWidget, public EmuWindow
|
class GRenderWindow : public QWidget, public EmuWindow
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GRenderWindow(QWidget* parent = NULL);
|
GRenderWindow(QWidget* parent = NULL);
|
||||||
~GRenderWindow();
|
~GRenderWindow();
|
||||||
|
@ -103,6 +107,9 @@ public:
|
||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void keyReleaseEvent(QKeyEvent* event);
|
void keyReleaseEvent(QKeyEvent* event);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void moveContext();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QGLWidget* child;
|
QGLWidget* child;
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,6 @@ void GMainWindow::BootGame(std::string filename)
|
||||||
registersWidget->OnCPUStepped();
|
registersWidget->OnCPUStepped();
|
||||||
callstackWidget->OnCPUStepped();
|
callstackWidget->OnCPUStepped();
|
||||||
|
|
||||||
render_window->DoneCurrent(); // make sure EmuThread can access GL context
|
|
||||||
render_window->GetEmuThread().SetFilename(filename);
|
render_window->GetEmuThread().SetFilename(filename);
|
||||||
render_window->GetEmuThread().start();
|
render_window->GetEmuThread().start();
|
||||||
|
|
||||||
|
@ -204,7 +203,6 @@ void GMainWindow::ToggleWindowMode()
|
||||||
ui.horizontalLayout->removeWidget(render_window);
|
ui.horizontalLayout->removeWidget(render_window);
|
||||||
render_window->setParent(NULL);
|
render_window->setParent(NULL);
|
||||||
render_window->setVisible(true);
|
render_window->setVisible(true);
|
||||||
render_window->DoneCurrent();
|
|
||||||
render_window->RestoreGeometry();
|
render_window->RestoreGeometry();
|
||||||
}
|
}
|
||||||
else if (!enable && render_window->parent() == NULL)
|
else if (!enable && render_window->parent() == NULL)
|
||||||
|
@ -212,7 +210,6 @@ void GMainWindow::ToggleWindowMode()
|
||||||
render_window->BackupGeometry();
|
render_window->BackupGeometry();
|
||||||
ui.horizontalLayout->addWidget(render_window);
|
ui.horizontalLayout->addWidget(render_window);
|
||||||
render_window->setVisible(true);
|
render_window->setVisible(true);
|
||||||
render_window->DoneCurrent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ void Init(EmuWindow* emu_window) {
|
||||||
glewExperimental = GL_TRUE;
|
glewExperimental = GL_TRUE;
|
||||||
|
|
||||||
g_emu_window = emu_window;
|
g_emu_window = emu_window;
|
||||||
g_emu_window->MakeCurrent();
|
|
||||||
g_renderer = new RendererOpenGL();
|
g_renderer = new RendererOpenGL();
|
||||||
g_renderer->SetWindow(g_emu_window);
|
g_renderer->SetWindow(g_emu_window);
|
||||||
g_renderer->Init();
|
g_renderer->Init();
|
||||||
|
|
Reference in New Issue