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