diff --git a/rpcs3/rpcs3qt/.qmake.conf b/rpcs3/rpcs3qt/.qmake.conf new file mode 100644 index 0000000000..18d50a7899 --- /dev/null +++ b/rpcs3/rpcs3qt/.qmake.conf @@ -0,0 +1,3 @@ +# P is project dir, B is build dir +P = $$PWD/.. +B = $$shadowed($$PWD) \ No newline at end of file diff --git a/rpcs3/rpcs3qt/glviewer.cpp b/rpcs3/rpcs3qt/glviewer.cpp new file mode 100644 index 0000000000..48106fbeba --- /dev/null +++ b/rpcs3/rpcs3qt/glviewer.cpp @@ -0,0 +1,90 @@ +#include "glviewer.h" +#include +#include +#include +#include + +GLViewer::GLViewer(QQuickItem* parent) + : QQuickItem(parent), + m_timerID(0), + m_fbo(0) +{ + this->setFlag(QQuickItem::ItemHasContents); +} + +GLViewer::~GLViewer() +{ + this->cleanup(); +} + +void GLViewer::timerEvent(QTimerEvent* evt) +{ + if (evt && evt->timerId() == m_timerID) + this->update(); +} + +QSGNode* GLViewer::updatePaintNode(QSGNode* node, UpdatePaintNodeData* data) +{ + QSGSimpleTextureNode* textureNode = static_cast(node); + if (!textureNode) + textureNode = new QSGSimpleTextureNode(); + // Push Qt state. + glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); + glPushAttrib(GL_ALL_ATTRIB_BITS); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glShadeModel(GL_FLAT); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glDisable(GL_STENCIL_TEST); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + delete m_fbo; + m_fbo = 0; + int width = this->width(); + int height = this->height(); + if (width && height) { + m_fbo = new QOpenGLFramebufferObject(width, height); + textureNode->setTexture(this->window()->createTextureFromId(m_fbo->texture(), m_fbo->size())); + } + else + { + textureNode->setTexture(this->window()->createTextureFromId(0, QSize(0,0))); + } + textureNode->setRect(this->boundingRect()); + + if (m_fbo) { + m_fbo->bind(); + } + // Restore (pop) Qt state. + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + glPopClientAttrib(); + + if (!m_timerID) + m_timerID = this->startTimer(16); + + return textureNode; +} + +void GLViewer::cleanup() { + this->killTimer(m_timerID); + m_timerID = 0; + if (m_fbo) { + delete m_fbo; + m_fbo = 0; + } +} diff --git a/rpcs3/rpcs3qt/glviewer.h b/rpcs3/rpcs3qt/glviewer.h new file mode 100644 index 0000000000..7ff0009158 --- /dev/null +++ b/rpcs3/rpcs3qt/glviewer.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +class GLViewer : public QQuickItem +{ + Q_OBJECT +public: + GLViewer(QQuickItem* parent = 0); + virtual ~GLViewer(); + +protected: + QSGNode* updatePaintNode(QSGNode* old, UpdatePaintNodeData* data); + void timerEvent(QTimerEvent* evt); + +private slots: + void cleanup(); + +private: + int m_timerID; + QOpenGLFramebufferObject* m_fbo; +}; diff --git a/rpcs3/rpcs3qt/main.cpp b/rpcs3/rpcs3qt/main.cpp new file mode 100644 index 0000000000..0aef5b2ab2 --- /dev/null +++ b/rpcs3/rpcs3qt/main.cpp @@ -0,0 +1,16 @@ +// Qt5.1+ frontend implementation for rpcs3. Known to work on Windows, Linux, Mac +// by Sacha Refshauge +#include +#include +#include "glviewer.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("GLViewer", 1, 0, "GLViewer"); + QQmlApplicationEngine engine(QUrl("qrc:/qml/main.qml")); + + return app.exec(); + Q_UNUSED(engine) +} diff --git a/rpcs3/rpcs3qt/qml.qrc b/rpcs3/rpcs3qt/qml.qrc new file mode 100644 index 0000000000..69145a822f --- /dev/null +++ b/rpcs3/rpcs3qt/qml.qrc @@ -0,0 +1,5 @@ + + + qml/main.qml + + diff --git a/rpcs3/rpcs3qt/qml/main.qml b/rpcs3/rpcs3qt/qml/main.qml new file mode 100644 index 0000000000..d115717bde --- /dev/null +++ b/rpcs3/rpcs3qt/qml/main.qml @@ -0,0 +1,62 @@ +import QtQuick 2.1 +import QtQuick.Controls 1.0 +import QtQuick.Window 2.0 +import GLViewer 1.0 + +ApplicationWindow { + visible: true + title: qsTr("RPCS3 Qt") + width: 500 + height: 500 + menuBar: MenuBar { + Menu { + title: qsTr("&Boot") + MenuItem { text: qsTr("&Boot Game...") } + MenuItem { text: qsTr("&Install PKG") } + MenuSeparator {} + MenuItem { text: qsTr("Boot &ELF") } + MenuItem { text: qsTr("Boot &SELF") } + MenuSeparator {} + MenuItem { text: qsTr("E\&xit"); onTriggered: Qt.quit() } + } + Menu { + title: qsTr("&System") + MenuItem { text: qsTr("&Pause") } + MenuItem { text: qsTr("&Stop") } + MenuSeparator {} + MenuItem { text: qsTr("Send '&Open System Menu' command") } + MenuItem { text: qsTr("Send 'E&xit' command") } + } + Menu { + title: qsTr("&Config") + MenuItem { text: qsTr("&Settings") } + MenuSeparator {} + MenuItem { text: qsTr("Virtual &File System Manager") } + MenuItem { text: qsTr("Virtual &HDD Manager") } + } + Menu { + title: qsTr("&Tools") + MenuItem { text: qsTr("&ELF Compiler") } + MenuItem { text: qsTr("&Memory Viewer") } + } + Menu { + title: qsTr("&Help") + MenuItem { text: qsTr("&About...") } + } + } + GLViewer { + anchors.fill: parent + Rectangle { + color: Qt.rgba(0, 0.5, 0.35); + height: Math.round(parent.height / 2) + width: height + radius: width + anchors.centerIn: parent + Text { + anchors.centerIn: parent + font.pixelSize: parent.height / 2 + text: "Qt" + } + } + } +} diff --git a/rpcs3/rpcs3qt/rpcs3qt.pro b/rpcs3/rpcs3qt/rpcs3qt.pro new file mode 100644 index 0000000000..977c740315 --- /dev/null +++ b/rpcs3/rpcs3qt/rpcs3qt.pro @@ -0,0 +1,19 @@ +# Qt5.1+ project for rpcs3. Works on Windows, Linux and Mac OSX +QT += gui opengl quick +CONFIG += c++11 + +# Qt UI +SOURCES += $$P/rpcs3qt/*.cpp +HEADERS += $$P/rpcs3qt/*.h + +# RPCS3 +HEADERS += $$P/stdafx.h +INCLUDEPATH += $$P $$P/.. +DEFINES += QT_UI + +# Installation path +# target.path = + +OTHER_FILES += $$P/rpcs3qt/qml/* + +RESOURCES += $$P/rpcs3qt/qml.qrc