summaryrefslogtreecommitdiff
path: root/src/citra_qt/bootmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/citra_qt/bootmanager.cpp')
-rw-r--r--src/citra_qt/bootmanager.cpp134
1 files changed, 66 insertions, 68 deletions
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 6dddde9ba..01cc6b9ca 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -22,13 +22,13 @@
22#include "video_core/debug_utils/debug_utils.h" 22#include "video_core/debug_utils/debug_utils.h"
23#include "video_core/video_core.h" 23#include "video_core/video_core.h"
24 24
25#define APP_NAME "citra" 25#define APP_NAME "citra"
26#define APP_VERSION "0.1-" VERSION 26#define APP_VERSION "0.1-" VERSION
27#define APP_TITLE APP_NAME " " APP_VERSION 27#define APP_TITLE APP_NAME " " APP_VERSION
28#define COPYRIGHT "Copyright (C) 2013-2014 Citra Team" 28#define COPYRIGHT "Copyright (C) 2013-2014 Citra Team"
29 29
30EmuThread::EmuThread(GRenderWindow* render_window) : 30EmuThread::EmuThread(GRenderWindow* render_window)
31 exec_step(false), running(false), stop_run(false), render_window(render_window) { 31 : exec_step(false), running(false), stop_run(false), render_window(render_window) {
32} 32}
33 33
34void EmuThread::run() { 34void EmuThread::run() {
@@ -64,7 +64,7 @@ void EmuThread::run() {
64 was_active = false; 64 was_active = false;
65 } else { 65 } else {
66 std::unique_lock<std::mutex> lock(running_mutex); 66 std::unique_lock<std::mutex> lock(running_mutex);
67 running_cv.wait(lock, [this]{ return IsRunning() || exec_step || stop_run; }); 67 running_cv.wait(lock, [this] { return IsRunning() || exec_step || stop_run; });
68 } 68 }
69 } 69 }
70 70
@@ -78,13 +78,13 @@ void EmuThread::run() {
78 render_window->moveContext(); 78 render_window->moveContext();
79} 79}
80 80
81// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL context. 81// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL
82// context.
82// The corresponding functionality is handled in EmuThread instead 83// The corresponding functionality is handled in EmuThread instead
83class GGLWidgetInternal : public QGLWidget 84class GGLWidgetInternal : public QGLWidget {
84{
85public: 85public:
86 GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent) 86 GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent)
87 : QGLWidget(fmt, parent), parent(parent) { 87 : QGLWidget(fmt, parent), parent(parent) {
88 } 88 }
89 89
90 void paintEvent(QPaintEvent* ev) override { 90 void paintEvent(QPaintEvent* ev) override {
@@ -98,37 +98,43 @@ public:
98 parent->OnFramebufferSizeChanged(); 98 parent->OnFramebufferSizeChanged();
99 } 99 }
100 100
101 void DisablePainting() { do_painting = false; } 101 void DisablePainting() {
102 void EnablePainting() { do_painting = true; } 102 do_painting = false;
103 }
104 void EnablePainting() {
105 do_painting = true;
106 }
103 107
104private: 108private:
105 GRenderWindow* parent; 109 GRenderWindow* parent;
106 bool do_painting; 110 bool do_painting;
107}; 111};
108 112
109GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : 113GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
110 QWidget(parent), keyboard_id(0), emu_thread(emu_thread), child(nullptr) { 114 : QWidget(parent), keyboard_id(0), emu_thread(emu_thread), child(nullptr) {
111 115
112 std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); 116 std::string window_title =
117 Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
113 setWindowTitle(QString::fromStdString(window_title)); 118 setWindowTitle(QString::fromStdString(window_title));
114 119
115 keyboard_id = KeyMap::NewDeviceId(); 120 keyboard_id = KeyMap::NewDeviceId();
116 ReloadSetKeymaps(); 121 ReloadSetKeymaps();
117} 122}
118 123
119void GRenderWindow::moveContext() 124void GRenderWindow::moveContext() {
120{
121 DoneCurrent(); 125 DoneCurrent();
122 // We need to move GL context to the swapping thread in Qt5 126// We need to move GL context to the swapping thread in Qt5
123#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) 127#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
124 // If the thread started running, move the GL Context to the new thread. Otherwise, move it back. 128 // If the thread started running, move the GL Context to the new thread. Otherwise, move it
125 auto thread = (QThread::currentThread() == qApp->thread() && emu_thread != nullptr) ? emu_thread : qApp->thread(); 129 // back.
130 auto thread = (QThread::currentThread() == qApp->thread() && emu_thread != nullptr)
131 ? emu_thread
132 : qApp->thread();
126 child->context()->moveToThread(thread); 133 child->context()->moveToThread(thread);
127#endif 134#endif
128} 135}
129 136
130void GRenderWindow::SwapBuffers() 137void GRenderWindow::SwapBuffers() {
131{
132#if !defined(QT_NO_DEBUG) 138#if !defined(QT_NO_DEBUG)
133 // Qt debug runtime prints a bogus warning on the console if you haven't called makeCurrent 139 // Qt debug runtime prints a bogus warning on the console if you haven't called makeCurrent
134 // since the last time you called swapBuffers. This presumably means something if you're using 140 // since the last time you called swapBuffers. This presumably means something if you're using
@@ -139,13 +145,11 @@ void GRenderWindow::SwapBuffers()
139 child->swapBuffers(); 145 child->swapBuffers();
140} 146}
141 147
142void GRenderWindow::MakeCurrent() 148void GRenderWindow::MakeCurrent() {
143{
144 child->makeCurrent(); 149 child->makeCurrent();
145} 150}
146 151
147void GRenderWindow::DoneCurrent() 152void GRenderWindow::DoneCurrent() {
148{
149 child->doneCurrent(); 153 child->doneCurrent();
150} 154}
151 155
@@ -157,36 +161,33 @@ void GRenderWindow::PollEvents() {
157// Older versions get the window size (density independent pixels), 161// Older versions get the window size (density independent pixels),
158// and hence, do not support DPI scaling ("retina" displays). 162// and hence, do not support DPI scaling ("retina" displays).
159// The result will be a viewport that is smaller than the extent of the window. 163// The result will be a viewport that is smaller than the extent of the window.
160void GRenderWindow::OnFramebufferSizeChanged() 164void GRenderWindow::OnFramebufferSizeChanged() {
161{ 165 // Screen changes potentially incur a change in screen DPI, hence we should update the
162 // Screen changes potentially incur a change in screen DPI, hence we should update the framebuffer size 166 // framebuffer size
163 qreal pixelRatio = windowPixelRatio(); 167 qreal pixelRatio = windowPixelRatio();
164 unsigned width = child->QPaintDevice::width() * pixelRatio; 168 unsigned width = child->QPaintDevice::width() * pixelRatio;
165 unsigned height = child->QPaintDevice::height() * pixelRatio; 169 unsigned height = child->QPaintDevice::height() * pixelRatio;
166 170
167 NotifyFramebufferLayoutChanged(EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height)); 171 NotifyFramebufferLayoutChanged(
172 EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height));
168} 173}
169 174
170void GRenderWindow::BackupGeometry() 175void GRenderWindow::BackupGeometry() {
171{
172 geometry = ((QGLWidget*)this)->saveGeometry(); 176 geometry = ((QGLWidget*)this)->saveGeometry();
173} 177}
174 178
175void GRenderWindow::RestoreGeometry() 179void GRenderWindow::RestoreGeometry() {
176{
177 // We don't want to back up the geometry here (obviously) 180 // We don't want to back up the geometry here (obviously)
178 QWidget::restoreGeometry(geometry); 181 QWidget::restoreGeometry(geometry);
179} 182}
180 183
181void GRenderWindow::restoreGeometry(const QByteArray& geometry) 184void GRenderWindow::restoreGeometry(const QByteArray& geometry) {
182{
183 // Make sure users of this class don't need to deal with backing up the geometry themselves 185 // Make sure users of this class don't need to deal with backing up the geometry themselves
184 QWidget::restoreGeometry(geometry); 186 QWidget::restoreGeometry(geometry);
185 BackupGeometry(); 187 BackupGeometry();
186} 188}
187 189
188QByteArray GRenderWindow::saveGeometry() 190QByteArray GRenderWindow::saveGeometry() {
189{
190 // If we are a top-level widget, store the current geometry 191 // If we are a top-level widget, store the current geometry
191 // otherwise, store the last backup 192 // otherwise, store the last backup
192 if (parent() == nullptr) 193 if (parent() == nullptr)
@@ -195,8 +196,7 @@ QByteArray GRenderWindow::saveGeometry()
195 return geometry; 196 return geometry;
196} 197}
197 198
198qreal GRenderWindow::windowPixelRatio() 199qreal GRenderWindow::windowPixelRatio() {
199{
200#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) 200#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
201 // windowHandle() might not be accessible until the window is displayed to screen. 201 // windowHandle() might not be accessible until the window is displayed to screen.
202 return windowHandle() ? windowHandle()->screen()->devicePixelRatio() : 1.0f; 202 return windowHandle() ? windowHandle()->screen()->devicePixelRatio() : 1.0f;
@@ -210,20 +210,16 @@ void GRenderWindow::closeEvent(QCloseEvent* event) {
210 QWidget::closeEvent(event); 210 QWidget::closeEvent(event);
211} 211}
212 212
213void GRenderWindow::keyPressEvent(QKeyEvent* event) 213void GRenderWindow::keyPressEvent(QKeyEvent* event) {
214{ 214 KeyMap::PressKey(*this, {event->key(), keyboard_id});
215 KeyMap::PressKey(*this, { event->key(), keyboard_id });
216} 215}
217 216
218void GRenderWindow::keyReleaseEvent(QKeyEvent* event) 217void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
219{ 218 KeyMap::ReleaseKey(*this, {event->key(), keyboard_id});
220 KeyMap::ReleaseKey(*this, { event->key(), keyboard_id });
221} 219}
222 220
223void GRenderWindow::mousePressEvent(QMouseEvent *event) 221void GRenderWindow::mousePressEvent(QMouseEvent* event) {
224{ 222 if (event->button() == Qt::LeftButton) {
225 if (event->button() == Qt::LeftButton)
226 {
227 auto pos = event->pos(); 223 auto pos = event->pos();
228 qreal pixelRatio = windowPixelRatio(); 224 qreal pixelRatio = windowPixelRatio();
229 this->TouchPressed(static_cast<unsigned>(pos.x() * pixelRatio), 225 this->TouchPressed(static_cast<unsigned>(pos.x() * pixelRatio),
@@ -231,30 +227,28 @@ void GRenderWindow::mousePressEvent(QMouseEvent *event)
231 } 227 }
232} 228}
233 229
234void GRenderWindow::mouseMoveEvent(QMouseEvent *event) 230void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
235{
236 auto pos = event->pos(); 231 auto pos = event->pos();
237 qreal pixelRatio = windowPixelRatio(); 232 qreal pixelRatio = windowPixelRatio();
238 this->TouchMoved(std::max(static_cast<unsigned>(pos.x() * pixelRatio), 0u), 233 this->TouchMoved(std::max(static_cast<unsigned>(pos.x() * pixelRatio), 0u),
239 std::max(static_cast<unsigned>(pos.y() * pixelRatio), 0u)); 234 std::max(static_cast<unsigned>(pos.y() * pixelRatio), 0u));
240} 235}
241 236
242void GRenderWindow::mouseReleaseEvent(QMouseEvent *event) 237void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
243{
244 if (event->button() == Qt::LeftButton) 238 if (event->button() == Qt::LeftButton)
245 this->TouchReleased(); 239 this->TouchReleased();
246} 240}
247 241
248void GRenderWindow::ReloadSetKeymaps() 242void GRenderWindow::ReloadSetKeymaps() {
249{
250 KeyMap::ClearKeyMapping(keyboard_id); 243 KeyMap::ClearKeyMapping(keyboard_id);
251 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { 244 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
252 KeyMap::SetKeyMapping({ Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id }, KeyMap::mapping_targets[i]); 245 KeyMap::SetKeyMapping(
246 {Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id},
247 KeyMap::mapping_targets[i]);
253 } 248 }
254} 249}
255 250
256void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) 251void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) {
257{
258 NotifyClientAreaSizeChanged(std::make_pair(width, height)); 252 NotifyClientAreaSizeChanged(std::make_pair(width, height));
259} 253}
260 254
@@ -267,7 +261,8 @@ void GRenderWindow::InitRenderTarget() {
267 delete layout(); 261 delete layout();
268 } 262 }
269 263
270 // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, WA_DontShowOnScreen, WA_DeleteOnClose 264 // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground,
265 // WA_DontShowOnScreen, WA_DeleteOnClose
271 QGLFormat fmt; 266 QGLFormat fmt;
272 fmt.setVersion(3, 3); 267 fmt.setVersion(3, 3);
273 fmt.setProfile(QGLFormat::CoreProfile); 268 fmt.setProfile(QGLFormat::CoreProfile);
@@ -279,7 +274,8 @@ void GRenderWindow::InitRenderTarget() {
279 child = new GGLWidgetInternal(fmt, this); 274 child = new GGLWidgetInternal(fmt, this);
280 QBoxLayout* layout = new QHBoxLayout(this); 275 QBoxLayout* layout = new QHBoxLayout(this);
281 276
282 resize(VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); 277 resize(VideoCore::kScreenTopWidth,
278 VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight);
283 layout->addWidget(child); 279 layout->addWidget(child);
284 layout->setMargin(0); 280 layout->setMargin(0);
285 setLayout(layout); 281 setLayout(layout);
@@ -292,7 +288,8 @@ void GRenderWindow::InitRenderTarget() {
292 BackupGeometry(); 288 BackupGeometry();
293} 289}
294 290
295void GRenderWindow::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) { 291void GRenderWindow::OnMinimalClientAreaChangeRequest(
292 const std::pair<unsigned, unsigned>& minimal_size) {
296 setMinimumSize(minimal_size.first, minimal_size.second); 293 setMinimumSize(minimal_size.first, minimal_size.second);
297} 294}
298 295
@@ -306,11 +303,12 @@ void GRenderWindow::OnEmulationStopping() {
306 child->EnablePainting(); 303 child->EnablePainting();
307} 304}
308 305
309void GRenderWindow::showEvent(QShowEvent * event) { 306void GRenderWindow::showEvent(QShowEvent* event) {
310 QWidget::showEvent(event); 307 QWidget::showEvent(event);
311 308
312 // windowHandle() is not initialized until the Window is shown, so we connect it here. 309// windowHandle() is not initialized until the Window is shown, so we connect it here.
313 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) 310#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
314 connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged()), Qt::UniqueConnection); 311 connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this,
315 #endif 312 SLOT(OnFramebufferSizeChanged()), Qt::UniqueConnection);
313#endif
316} 314}