Try to reuse the same QImage and just update the content.
But it requires some magic to trigger an update (calling bits()). Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
parent
e80fee86c5
commit
d250cc817e
7 changed files with 64 additions and 75 deletions
|
@ -34,14 +34,9 @@ void Emulator::refreshScreen(const bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Emulator::saveScreen(const QString & filename) const
|
void Emulator::loadVideoSettings(QImage * screenBuffer)
|
||||||
{
|
{
|
||||||
return ui->video->getScreen().save(filename);
|
ui->video->loadVideoSettings(screenBuffer);
|
||||||
}
|
|
||||||
|
|
||||||
void Emulator::loadVideoSettings()
|
|
||||||
{
|
|
||||||
ui->video->loadVideoSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::unloadVideoSettings()
|
void Emulator::unloadVideoSettings()
|
||||||
|
@ -49,11 +44,6 @@ void Emulator::unloadVideoSettings()
|
||||||
ui->video->unloadVideoSettings();
|
ui->video->unloadVideoSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::displayLogo()
|
|
||||||
{
|
|
||||||
ui->video->displayLogo();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emulator::setVideoSize(QMdiSubWindow * window, const QSize & size)
|
void Emulator::setVideoSize(QMdiSubWindow * window, const QSize & size)
|
||||||
{
|
{
|
||||||
window->showNormal();
|
window->showNormal();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
|
|
||||||
class QMdiSubWindow;
|
class QMdiSubWindow;
|
||||||
|
class QImage;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class Emulator;
|
class Emulator;
|
||||||
|
@ -20,10 +21,8 @@ public:
|
||||||
void redrawScreen(); // regenerate image and repaint
|
void redrawScreen(); // regenerate image and repaint
|
||||||
void refreshScreen(const bool force);
|
void refreshScreen(const bool force);
|
||||||
|
|
||||||
bool saveScreen(const QString & filename) const;
|
void loadVideoSettings(QImage * screenBuffer);
|
||||||
void loadVideoSettings();
|
|
||||||
void unloadVideoSettings();
|
void unloadVideoSettings();
|
||||||
void displayLogo();
|
|
||||||
|
|
||||||
void setZoom(QMdiSubWindow * window, const int x);
|
void setZoom(QMdiSubWindow * window, const int x);
|
||||||
void set43AspectRatio(QMdiSubWindow * window);
|
void set43AspectRatio(QMdiSubWindow * window);
|
||||||
|
|
|
@ -524,7 +524,7 @@ void QApple::on_actionScreenshot_triggered()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const bool ok = myFrame->saveScreen(filename);
|
const bool ok = myFrame->SaveScreen(filename);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
const QString message = QString::fromUtf8("Cannot save screenshot to %1").arg(filename);
|
const QString message = QString::fromUtf8("Cannot save screenshot to %1").arg(filename);
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
|
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
|
#include "Interface.h"
|
||||||
|
|
||||||
#include <QMdiSubWindow>
|
#include <QMdiSubWindow>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
QtFrame::QtFrame(Emulator * emulator, QMdiSubWindow * window) : myEmulator(emulator), myWindow(window), myForceRepaint(false)
|
QtFrame::QtFrame(Emulator * emulator, QMdiSubWindow * window) : myEmulator(emulator), myWindow(window), myForceRepaint(false)
|
||||||
{
|
{
|
||||||
|
myLogo = QImage(":/resources/APPLEWINLOGO.BMP").mirrored(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtFrame::SetForceRepaint(const bool force)
|
void QtFrame::SetForceRepaint(const bool force)
|
||||||
|
@ -17,6 +19,12 @@ void QtFrame::SetForceRepaint(const bool force)
|
||||||
myForceRepaint = force;
|
myForceRepaint = force;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtFrame::DisplayLogo()
|
||||||
|
{
|
||||||
|
QPainter painter(&myFrameBuffer);
|
||||||
|
painter.drawImage(mySX, mySY, myLogo);
|
||||||
|
}
|
||||||
|
|
||||||
void QtFrame::VideoPresentScreen()
|
void QtFrame::VideoPresentScreen()
|
||||||
{
|
{
|
||||||
myEmulator->refreshScreen(myForceRepaint);
|
myEmulator->refreshScreen(myForceRepaint);
|
||||||
|
@ -33,10 +41,25 @@ void QtFrame::FrameRefreshStatus(int drawflags)
|
||||||
|
|
||||||
void QtFrame::Initialize()
|
void QtFrame::Initialize()
|
||||||
{
|
{
|
||||||
LinuxFrame::Initialize();
|
static_assert(sizeof(bgra_t) == 4, "Invalid size of bgra_t");
|
||||||
|
Video & video = GetVideo();
|
||||||
|
|
||||||
|
mySX = video.GetFrameBufferBorderWidth();
|
||||||
|
mySY = video.GetFrameBufferBorderHeight();
|
||||||
|
mySW = video.GetFrameBufferBorderlessWidth();
|
||||||
|
mySH = video.GetFrameBufferBorderlessHeight();
|
||||||
|
|
||||||
|
const int width = video.GetFrameBufferWidth();
|
||||||
|
const int height = video.GetFrameBufferHeight();
|
||||||
|
|
||||||
|
myFrameBuffer = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
|
||||||
|
uchar * bits = myFrameBuffer.bits();
|
||||||
|
video.Initialize(bits);
|
||||||
|
|
||||||
FrameRefreshStatus(DRAW_TITLE);
|
FrameRefreshStatus(DRAW_TITLE);
|
||||||
myEmulator->loadVideoSettings();
|
myEmulator->loadVideoSettings(&myFrameBuffer);
|
||||||
myEmulator->displayLogo();
|
DisplayLogo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtFrame::Destroy()
|
void QtFrame::Destroy()
|
||||||
|
@ -55,7 +78,8 @@ void QtFrame::Set43Ratio()
|
||||||
myEmulator->set43AspectRatio(myWindow);
|
myEmulator->set43AspectRatio(myWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QtFrame::saveScreen(const QString & filename) const
|
bool QtFrame::SaveScreen(const QString & filename) const
|
||||||
{
|
{
|
||||||
return myEmulator->saveScreen(filename);
|
QImage screen = myFrameBuffer.copy(mySX, mySY, mySW, mySH);
|
||||||
|
return screen.save(filename);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#define QTFRAME_H
|
#define QTFRAME_H
|
||||||
|
|
||||||
#include "linux/linuxframe.h"
|
#include "linux/linuxframe.h"
|
||||||
#include <memory>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
class Emulator;
|
class Emulator;
|
||||||
class QMdiSubWindow;
|
class QMdiSubWindow;
|
||||||
|
@ -17,16 +17,25 @@ public:
|
||||||
virtual void FrameRefreshStatus(int drawflags);
|
virtual void FrameRefreshStatus(int drawflags);
|
||||||
virtual void Initialize();
|
virtual void Initialize();
|
||||||
virtual void Destroy();
|
virtual void Destroy();
|
||||||
|
virtual void DisplayLogo();
|
||||||
|
|
||||||
void SetForceRepaint(const bool force);
|
void SetForceRepaint(const bool force);
|
||||||
void SetZoom(const int x);
|
void SetZoom(const int x);
|
||||||
void Set43Ratio();
|
void Set43Ratio();
|
||||||
bool saveScreen(const QString & filename) const;
|
|
||||||
|
bool SaveScreen(const QString & filename) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Emulator * myEmulator;
|
Emulator * myEmulator;
|
||||||
QMdiSubWindow * myWindow;
|
QMdiSubWindow * myWindow;
|
||||||
bool myForceRepaint;
|
bool myForceRepaint;
|
||||||
|
|
||||||
|
QImage myLogo;
|
||||||
|
QImage myFrameBuffer;
|
||||||
|
int mySX;
|
||||||
|
int mySY;
|
||||||
|
int mySW;
|
||||||
|
int mySH;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QTFRAME_H
|
#endif // QTFRAME_H
|
||||||
|
|
|
@ -16,22 +16,17 @@
|
||||||
QVideo::QVideo(QWidget *parent) : QVIDEO_BASECLASS(parent)
|
QVideo::QVideo(QWidget *parent) : QVIDEO_BASECLASS(parent)
|
||||||
{
|
{
|
||||||
this->setMouseTracking(true);
|
this->setMouseTracking(true);
|
||||||
|
|
||||||
myLogo = QImage(":/resources/APPLEWINLOGO.BMP").mirrored(false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QVideo::loadVideoSettings()
|
void QVideo::loadVideoSettings(QImage * screenBuffer)
|
||||||
{
|
{
|
||||||
|
myFrameBuffer = screenBuffer;
|
||||||
Video & video = GetVideo();
|
Video & video = GetVideo();
|
||||||
|
|
||||||
mySX = video.GetFrameBufferBorderWidth();
|
mySX = video.GetFrameBufferBorderWidth();
|
||||||
mySY = video.GetFrameBufferBorderHeight();
|
mySY = video.GetFrameBufferBorderHeight();
|
||||||
mySW = video.GetFrameBufferBorderlessWidth();
|
mySW = video.GetFrameBufferBorderlessWidth();
|
||||||
mySH = video.GetFrameBufferBorderlessHeight();
|
mySH = video.GetFrameBufferBorderlessHeight();
|
||||||
myWidth = video.GetFrameBufferWidth();
|
|
||||||
myHeight = video.GetFrameBufferHeight();
|
|
||||||
|
|
||||||
myFrameBuffer = video.GetFrameBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QVideo::unloadVideoSettings()
|
void QVideo::unloadVideoSettings()
|
||||||
|
@ -39,45 +34,25 @@ void QVideo::unloadVideoSettings()
|
||||||
myFrameBuffer = nullptr;
|
myFrameBuffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage QVideo::getScreenImage() const
|
|
||||||
{
|
|
||||||
QImage frameBuffer(myFrameBuffer, myWidth, myHeight, QImage::Format_ARGB32_Premultiplied);
|
|
||||||
return frameBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage QVideo::getScreen() const
|
|
||||||
{
|
|
||||||
QImage frameBuffer = getScreenImage();
|
|
||||||
QImage screen = frameBuffer.copy(mySX, mySY, mySW, mySH);
|
|
||||||
|
|
||||||
return screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QVideo::displayLogo()
|
|
||||||
{
|
|
||||||
QImage frameBuffer = getScreenImage();
|
|
||||||
|
|
||||||
QPainter painter(&frameBuffer);
|
|
||||||
painter.drawImage(mySX, mySY, myLogo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QVideo::paintEvent(QPaintEvent *)
|
void QVideo::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
QImage frameBuffer = getScreenImage();
|
if (myFrameBuffer)
|
||||||
|
|
||||||
const QSize actual = size();
|
|
||||||
const double scaleX = double(actual.width()) / mySW;
|
|
||||||
const double scaleY = double(actual.height()) / mySH;
|
|
||||||
|
|
||||||
// then paint it on the widget with scale
|
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
myFrameBuffer->bits(); // triggers a refresh of the QImage
|
||||||
|
|
||||||
// scale and flip vertically
|
const QSize actual = size();
|
||||||
const QTransform transform(scaleX, 0.0, 0.0, -scaleY, 0.0, actual.height());
|
const double scaleX = double(actual.width()) / mySW;
|
||||||
painter.setTransform(transform);
|
const double scaleY = double(actual.height()) / mySH;
|
||||||
|
|
||||||
painter.drawImage(0, 0, frameBuffer, mySX, mySY, mySW, mySH);
|
// then paint it on the widget with scale
|
||||||
|
{
|
||||||
|
QPainter painter(this);
|
||||||
|
|
||||||
|
// scale and flip vertically
|
||||||
|
const QTransform transform(scaleX, 0.0, 0.0, -scaleY, 0.0, actual.height());
|
||||||
|
painter.setTransform(transform);
|
||||||
|
painter.drawImage(0, 0, *myFrameBuffer, mySX, mySY, mySW, mySH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,8 @@ class QVideo : public QVIDEO_BASECLASS
|
||||||
public:
|
public:
|
||||||
explicit QVideo(QWidget *parent = nullptr);
|
explicit QVideo(QWidget *parent = nullptr);
|
||||||
|
|
||||||
QImage getScreen() const;
|
void loadVideoSettings(QImage * screenBuffer);
|
||||||
void loadVideoSettings();
|
|
||||||
void unloadVideoSettings();
|
void unloadVideoSettings();
|
||||||
void displayLogo();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
@ -32,18 +30,12 @@ protected:
|
||||||
virtual void mouseReleaseEvent(QMouseEvent *event);
|
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QImage myLogo;
|
QImage * myFrameBuffer;
|
||||||
|
|
||||||
int mySX;
|
int mySX;
|
||||||
int mySY;
|
int mySY;
|
||||||
int mySW;
|
int mySW;
|
||||||
int mySH;
|
int mySH;
|
||||||
int myWidth;
|
|
||||||
int myHeight;
|
|
||||||
|
|
||||||
quint8 * myFrameBuffer;
|
|
||||||
|
|
||||||
QImage getScreenImage() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QVIDEO_H
|
#endif // QVIDEO_H
|
||||||
|
|
Loading…
Add table
Reference in a new issue