all repos — mgba @ bb71c72bf8a3324716febc2c4a7515c5f655c59d

mGBA Game Boy Advance Emulator

src/platform/qt/DisplayQt.cpp (view raw)

  1/* Copyright (c) 2013-2015 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "DisplayQt.h"
  7
  8#include "CoreController.h"
  9#include "utils.h"
 10
 11#include <QPainter>
 12
 13#include <mgba/core/core.h>
 14#include <mgba/core/thread.h>
 15#include <mgba-util/math.h>
 16
 17using namespace QGBA;
 18
 19DisplayQt::DisplayQt(QWidget* parent)
 20	: Display(parent)
 21{
 22}
 23
 24void DisplayQt::startDrawing(std::shared_ptr<CoreController> controller) {
 25	QSize size = controller->screenDimensions();
 26	m_width = size.width();
 27	m_height = size.height();
 28	m_backing = QImage();
 29	m_oldBacking = QImage();
 30	m_isDrawing = true;
 31	m_context = controller;
 32	emit drawingStarted();
 33}
 34
 35void DisplayQt::stopDrawing() {
 36	m_isDrawing = false;
 37	m_context.reset();
 38}
 39
 40void DisplayQt::lockAspectRatio(bool lock) {
 41	Display::lockAspectRatio(lock);
 42	update();
 43}
 44
 45void DisplayQt::lockIntegerScaling(bool lock) {
 46	Display::lockIntegerScaling(lock);
 47	update();
 48}
 49
 50void DisplayQt::interframeBlending(bool lock) {
 51	Display::interframeBlending(lock);
 52	update();
 53}
 54
 55void DisplayQt::filter(bool filter) {
 56	Display::filter(filter);
 57	update();
 58}
 59
 60void DisplayQt::framePosted() {
 61	update();
 62	const color_t* buffer = m_context->drawContext();
 63	if (const_cast<const QImage&>(m_backing).bits() == reinterpret_cast<const uchar*>(buffer)) {
 64		return;
 65	}
 66	m_oldBacking = m_backing;
 67#ifdef COLOR_16_BIT
 68#ifdef COLOR_5_6_5
 69	m_backing = QImage(reinterpret_cast<const uchar*>(buffer), m_width, m_height, QImage::Format_RGB16);
 70#else
 71	m_backing = QImage(reinterpret_cast<const uchar*>(buffer), m_width, m_height, QImage::Format_RGB555);
 72#endif
 73#else
 74	m_backing = QImage(reinterpret_cast<const uchar*>(buffer), m_width, m_height, QImage::Format_ARGB32);
 75	m_backing = m_backing.convertToFormat(QImage::Format_RGB32);
 76#endif
 77#ifndef COLOR_5_6_5
 78	m_backing = m_backing.rgbSwapped();
 79#endif
 80}
 81
 82void DisplayQt::resizeContext() {
 83	if (!m_context) {
 84		return;
 85	}
 86	QSize size = m_context->screenDimensions();
 87	if (m_width != size.width() || m_height != size.height()) {
 88		m_width = size.width();
 89		m_height = size.height();
 90		m_oldBacking = std::move(QImage());
 91		m_backing = std::move(QImage());
 92	}
 93}
 94
 95void DisplayQt::paintEvent(QPaintEvent*) {
 96	QPainter painter(this);
 97	painter.fillRect(QRect(QPoint(), size()), Qt::black);
 98	if (isFiltered()) {
 99		painter.setRenderHint(QPainter::SmoothPixmapTransform);
100	}
101	QRect full(clampSize(QSize(m_width, m_height), size(), isAspectRatioLocked(), isIntegerScalingLocked()));
102
103	if (hasInterframeBlending()) {
104		painter.drawImage(full, m_oldBacking, QRect(0, 0, m_width, m_height));
105		painter.setOpacity(0.5);
106	}
107	painter.drawImage(full, m_backing, QRect(0, 0, m_width, m_height));
108	painter.setOpacity(1);
109	if (isShowOSD()) {
110		messagePainter()->paint(&painter);
111	}
112}