added software renderer. split common functions prev.
in gleswidget to renderstack (a QStackWidget), which in turn calls an actual renderer. added ability to target GLES directly, but this is maybe uneeded.
This commit is contained in:
164
src/qt/qt_rendererstack.cpp
Normal file
164
src/qt/qt_rendererstack.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
#include "qt_rendererstack.hpp"
|
||||
#include "ui_qt_rendererstack.h"
|
||||
|
||||
#include "qt_softwarerenderer.hpp"
|
||||
#include "qt_hardwarerenderer.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <86box/mouse.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/video.h>
|
||||
}
|
||||
|
||||
RendererStack::RendererStack(QWidget *parent) :
|
||||
QStackedWidget(parent),
|
||||
ui(new Ui::RendererStack)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
imagebufs = QVector<QImage>(2);
|
||||
imagebufs[0] = QImage{QSize(2048 + 64, 2048 + 64), QImage::Format_RGB32};
|
||||
imagebufs[1] = QImage{QSize(2048 + 64, 2048 + 64), QImage::Format_RGB32};
|
||||
}
|
||||
|
||||
RendererStack::~RendererStack()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
extern "C" void macos_poll_mouse();
|
||||
void
|
||||
qt_mouse_capture(int on)
|
||||
{
|
||||
if (!on)
|
||||
{
|
||||
mouse_capture = 0;
|
||||
QApplication::setOverrideCursor(Qt::ArrowCursor);
|
||||
#ifdef __APPLE__
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
mouse_capture = 1;
|
||||
QApplication::setOverrideCursor(Qt::BlankCursor);
|
||||
#ifdef __APPLE__
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void RendererStack::mousePoll()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
return macos_poll_mouse();
|
||||
#else
|
||||
mouse_x = mousedata.deltax;
|
||||
mouse_y = mousedata.deltay;
|
||||
mouse_z = mousedata.deltaz;
|
||||
mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0;
|
||||
mouse_buttons = mousedata.mousebuttons;
|
||||
#ifdef WAYLAND
|
||||
if (wayland)
|
||||
wl_mouse_poll();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void RendererStack::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture)
|
||||
{
|
||||
plat_mouse_capture(1);
|
||||
this->setCursor(Qt::BlankCursor);
|
||||
return;
|
||||
}
|
||||
if (mouse_capture && event->button() == Qt::MiddleButton && mouse_get_buttons() < 3)
|
||||
{
|
||||
plat_mouse_capture(0);
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
return;
|
||||
}
|
||||
if (mouse_capture)
|
||||
{
|
||||
mousedata.mousebuttons &= ~event->button();
|
||||
}
|
||||
}
|
||||
void RendererStack::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (mouse_capture)
|
||||
{
|
||||
mousedata.mousebuttons |= event->button();
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
void RendererStack::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (mouse_capture)
|
||||
{
|
||||
mousedata.deltay += event->pixelDelta().y();
|
||||
}
|
||||
}
|
||||
|
||||
int ignoreNextMouseEvent = 0;
|
||||
void RendererStack::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (QApplication::platformName().contains("wayland"))
|
||||
{
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
if (!mouse_capture) { event->ignore(); return; }
|
||||
#ifdef __APPLE__
|
||||
event->accept();
|
||||
return;
|
||||
#else
|
||||
static QPoint oldPos = QCursor::pos();
|
||||
if (ignoreNextMouseEvent) { oldPos = event->pos(); ignoreNextMouseEvent--; event->accept(); return; }
|
||||
mousedata.deltax += event->pos().x() - oldPos.x();
|
||||
mousedata.deltay += event->pos().y() - oldPos.y();
|
||||
QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2)));
|
||||
oldPos = event->pos();
|
||||
ignoreNextMouseEvent = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// called from blitter thread
|
||||
void RendererStack::blit(int x, int y, int w, int h)
|
||||
{
|
||||
if ((w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL))
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
sx = x;
|
||||
sy = y;
|
||||
sw = this->w = w;
|
||||
sh = this->h = h;
|
||||
auto imagebits = imagebufs[currentBuf].bits();
|
||||
video_copy(imagebits + y * ((2048 + 64) * 4) + x * 4, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t));
|
||||
|
||||
if (screenshots)
|
||||
{
|
||||
video_screenshot((uint32_t *)imagebits, 0, 0, 2048 + 64);
|
||||
}
|
||||
video_blit_complete();
|
||||
blitToRenderer(imagebufs[currentBuf], sx, sy, sw, sh);
|
||||
currentBuf = (currentBuf + 1) % 2;
|
||||
}
|
||||
|
||||
void RendererStack::on_RendererStack_currentChanged(int arg1) {
|
||||
disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr);
|
||||
switch (arg1) {
|
||||
case 0:
|
||||
connect(this, &RendererStack::blitToRenderer, dynamic_cast<SoftwareRenderer*>(currentWidget()), &SoftwareRenderer::onBlit);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
connect(this, &RendererStack::blitToRenderer, dynamic_cast<HardwareRenderer*>(currentWidget()), &HardwareRenderer::onBlit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user