mirror of https://github.com/mgba-emu/mgba.git
114 lines
2.9 KiB
C++
114 lines
2.9 KiB
C++
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#include "DisplayQt.h"
|
|
|
|
#include "CoreController.h"
|
|
#include "utils.h"
|
|
|
|
#include <QPainter>
|
|
|
|
#include <mgba/core/core.h>
|
|
#include <mgba/core/thread.h>
|
|
#include <mgba-util/math.h>
|
|
|
|
using namespace QGBA;
|
|
|
|
DisplayQt::DisplayQt(QWidget* parent)
|
|
: Display(parent)
|
|
{
|
|
}
|
|
|
|
void DisplayQt::startDrawing(std::shared_ptr<CoreController> controller) {
|
|
QSize size = controller->screenDimensions();
|
|
m_width = size.width();
|
|
m_height = size.height();
|
|
setSystemDimensions(m_width, m_height);
|
|
m_backing = std::move(QImage());
|
|
m_oldBacking = std::move(QImage());
|
|
m_isDrawing = true;
|
|
m_context = controller;
|
|
emit drawingStarted();
|
|
}
|
|
|
|
void DisplayQt::stopDrawing() {
|
|
m_isDrawing = false;
|
|
m_context.reset();
|
|
}
|
|
|
|
void DisplayQt::lockAspectRatio(bool lock) {
|
|
Display::lockAspectRatio(lock);
|
|
update();
|
|
}
|
|
|
|
void DisplayQt::lockIntegerScaling(bool lock) {
|
|
Display::lockIntegerScaling(lock);
|
|
update();
|
|
}
|
|
|
|
void DisplayQt::interframeBlending(bool lock) {
|
|
Display::interframeBlending(lock);
|
|
update();
|
|
}
|
|
|
|
void DisplayQt::filter(bool filter) {
|
|
Display::filter(filter);
|
|
update();
|
|
}
|
|
|
|
void DisplayQt::framePosted() {
|
|
update();
|
|
const color_t* buffer = m_context->drawContext();
|
|
if (const_cast<const QImage&>(m_backing).bits() == reinterpret_cast<const uchar*>(buffer)) {
|
|
return;
|
|
}
|
|
m_oldBacking = m_backing;
|
|
#ifdef COLOR_16_BIT
|
|
#ifdef COLOR_5_6_5
|
|
m_backing = QImage(reinterpret_cast<const uchar*>(buffer), m_width, m_height, QImage::Format_RGB16);
|
|
#else
|
|
m_backing = QImage(reinterpret_cast<const uchar*>(buffer), m_width, m_height, QImage::Format_RGB555);
|
|
#endif
|
|
#else
|
|
m_backing = QImage(reinterpret_cast<const uchar*>(buffer), m_width, m_height, QImage::Format_ARGB32);
|
|
m_backing = m_backing.convertToFormat(QImage::Format_RGB32);
|
|
#endif
|
|
#ifndef COLOR_5_6_5
|
|
m_backing = m_backing.rgbSwapped();
|
|
#endif
|
|
}
|
|
|
|
void DisplayQt::resizeContext() {
|
|
if (!m_context) {
|
|
return;
|
|
}
|
|
QSize size = m_context->screenDimensions();
|
|
if (m_width != size.width() || m_height != size.height()) {
|
|
m_width = size.width();
|
|
m_height = size.height();
|
|
m_oldBacking = std::move(QImage());
|
|
m_backing = std::move(QImage());
|
|
}
|
|
}
|
|
|
|
void DisplayQt::paintEvent(QPaintEvent*) {
|
|
QPainter painter(this);
|
|
painter.fillRect(QRect(QPoint(), size()), Qt::black);
|
|
if (isFiltered()) {
|
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
}
|
|
QRect full(clampSize(QSize(m_width, m_height), size(), isAspectRatioLocked(), isIntegerScalingLocked()));
|
|
|
|
if (hasInterframeBlending()) {
|
|
painter.drawImage(full, m_oldBacking, QRect(0, 0, m_width, m_height));
|
|
painter.setOpacity(0.5);
|
|
}
|
|
painter.drawImage(full, m_backing, QRect(0, 0, m_width, m_height));
|
|
painter.setOpacity(1);
|
|
if (isShowOSD()) {
|
|
messagePainter()->paint(&painter);
|
|
}
|
|
}
|