1 #ifndef QTMAIN_H 2 #define QTMAIN_H 3 4 #include <QTouchEvent> 5 #include <QMouseEvent> 6 #include <QInputDialog> 7 #include "Common/GPU/OpenGL/GLSLProgram.h" 8 #include <QGLWidget> 9 10 #ifndef SDL 11 #include <QAudioOutput> 12 #include <QAudioFormat> 13 #endif 14 #if defined(MOBILE_DEVICE) 15 #include <QAccelerometer> 16 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 17 QTM_USE_NAMESPACE 18 #endif 19 #endif 20 21 #include <cassert> 22 #include <atomic> 23 #include <thread> 24 25 #include "Common/System/Display.h" 26 #include "Common/TimeUtil.h" 27 #include "Common/File/VFS/VFS.h" 28 #include "Common/File/VFS/AssetReader.h" 29 #include "Common/GPU/OpenGL/GLCommon.h" 30 #include "Common/GPU/OpenGL/GLFeatures.h" 31 #include "Common/Input/InputState.h" 32 #include "Common/Input/KeyCodes.h" 33 #include "Common/GPU/thin3d.h" 34 #include "Common/Net/Resolve.h" 35 #include "NKCodeFromQt.h" 36 37 #include "Common/GraphicsContext.h" 38 #include "Core/Core.h" 39 #include "Core/Config.h" 40 #include "Core/ConfigValues.h" 41 #include "Core/System.h" 42 #include "Common/GPU/thin3d_create.h" 43 #include "Common/GPU/OpenGL/GLRenderManager.h" 44 45 // Input 46 void SimulateGamepad(); 47 48 class QtGLGraphicsContext : public GraphicsContext { 49 public: QtGLGraphicsContext()50 QtGLGraphicsContext() { 51 CheckGLExtensions(); 52 draw_ = Draw::T3DCreateGLContext(); 53 SetGPUBackend(GPUBackend::OPENGL); 54 renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); 55 renderManager_->SetInflightFrames(g_Config.iInflightFrames); 56 bool success = draw_->CreatePresets(); 57 _assert_msg_(success, "Failed to compile preset shaders"); 58 59 // TODO: Need to figure out how to implement SetSwapInterval for Qt. 60 } 61 ~QtGLGraphicsContext()62 ~QtGLGraphicsContext() { 63 delete draw_; 64 draw_ = nullptr; 65 renderManager_ = nullptr; 66 } 67 Shutdown()68 void Shutdown() override {} SwapInterval(int interval)69 void SwapInterval(int interval) override { 70 // See TODO in constructor. 71 // renderManager_->SwapInterval(interval); 72 } SwapBuffers()73 void SwapBuffers() override {} Resize()74 void Resize() override {} 75 GetDrawContext()76 Draw::DrawContext *GetDrawContext() override { 77 return draw_; 78 } 79 ThreadStart()80 void ThreadStart() override { 81 renderManager_->ThreadStart(draw_); 82 } 83 ThreadFrame()84 bool ThreadFrame() override { 85 return renderManager_->ThreadFrame(); 86 } 87 ThreadEnd()88 void ThreadEnd() override { 89 renderManager_->ThreadEnd(); 90 } 91 StopThread()92 void StopThread() override { 93 renderManager_->WaitUntilQueueIdle(); 94 renderManager_->StopThread(); 95 } 96 97 private: 98 Draw::DrawContext *draw_ = nullptr; 99 GLRenderManager *renderManager_ = nullptr; 100 }; 101 102 enum class EmuThreadState { 103 DISABLED, 104 START_REQUESTED, 105 RUNNING, 106 QUIT_REQUESTED, 107 STOPPED, 108 }; 109 110 111 // GUI, thread manager 112 class MainUI : public QGLWidget 113 { 114 Q_OBJECT 115 public: 116 explicit MainUI(QWidget *parent = 0); 117 ~MainUI(); 118 119 void resizeGL(int w, int h); 120 121 public slots: 122 QString InputBoxGetQString(QString title, QString defaultValue); 123 124 signals: 125 void doubleClick(); 126 void newFrame(); 127 128 protected: 129 void timerEvent(QTimerEvent *); 130 void changeEvent(QEvent *e); 131 bool event(QEvent *e); 132 133 void initializeGL(); 134 void paintGL(); 135 136 void updateAccelerometer(); 137 138 void EmuThreadFunc(); 139 void EmuThreadStart(); 140 void EmuThreadStop(); 141 void EmuThreadJoin(); 142 143 private: 144 QtGLGraphicsContext *graphicsContext; 145 146 float xscale, yscale; 147 #if defined(MOBILE_DEVICE) 148 QAccelerometer* acc; 149 #endif 150 151 std::thread emuThread; 152 std::atomic<int> emuThreadState; 153 }; 154 155 class QTCamera : public QObject { 156 Q_OBJECT 157 public: QTCamera()158 QTCamera() {} ~QTCamera()159 ~QTCamera() {}; 160 161 signals: 162 void onStartCamera(int width, int height); 163 void onStopCamera(); 164 165 public slots: 166 void startCamera(int width, int height); 167 void stopCamera(); 168 }; 169 170 extern MainUI* emugl; 171 172 #ifndef SDL 173 174 // Audio 175 class MainAudio : public QObject { 176 Q_OBJECT 177 public: MainAudio()178 MainAudio() {} 179 ~MainAudio(); 180 public slots: 181 void run(); 182 protected: 183 void timerEvent(QTimerEvent *); 184 private: 185 QIODevice* feed; 186 QAudioOutput* output; 187 int mixlen; 188 char* mixbuf; 189 int timer; 190 }; 191 192 #endif //SDL 193 194 #endif 195 196