mirror of https://github.com/mgba-emu/mgba.git
Qt: Add option to lock the maximum frame size (closes #1493)
This commit is contained in:
parent
be85200b3e
commit
d1a6e6b747
1
CHANGES
1
CHANGES
|
@ -1,5 +1,6 @@
|
||||||
0.11.0: (Future)
|
0.11.0: (Future)
|
||||||
Features:
|
Features:
|
||||||
|
- New option to lock the maximum frame size
|
||||||
- Scripting: New `input` API for getting raw keyboard/mouse/controller state
|
- Scripting: New `input` API for getting raw keyboard/mouse/controller state
|
||||||
- Scripting: New `storage` API for saving data for a script, e.g. settings
|
- Scripting: New `storage` API for saving data for a script, e.g. settings
|
||||||
- Scripting: Debugger integration to allow for breakpoints and watchpoints
|
- Scripting: Debugger integration to allow for breakpoints and watchpoints
|
||||||
|
|
|
@ -38,6 +38,8 @@ union mVideoBackendCommandData {
|
||||||
struct {
|
struct {
|
||||||
unsigned width;
|
unsigned width;
|
||||||
unsigned height;
|
unsigned height;
|
||||||
|
unsigned maxW;
|
||||||
|
unsigned maxH;
|
||||||
} u;
|
} u;
|
||||||
const void* image;
|
const void* image;
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct VideoBackend {
|
||||||
void (*layerDimensions)(const struct VideoBackend*, enum VideoLayer, struct mRectangle*);
|
void (*layerDimensions)(const struct VideoBackend*, enum VideoLayer, struct mRectangle*);
|
||||||
void (*swap)(struct VideoBackend*);
|
void (*swap)(struct VideoBackend*);
|
||||||
void (*clear)(struct VideoBackend*);
|
void (*clear)(struct VideoBackend*);
|
||||||
void (*contextResized)(struct VideoBackend*, unsigned w, unsigned h);
|
void (*contextResized)(struct VideoBackend*, unsigned w, unsigned h, unsigned maxW, unsigned maxH);
|
||||||
void (*setImageSize)(struct VideoBackend*, enum VideoLayer, int w, int h);
|
void (*setImageSize)(struct VideoBackend*, enum VideoLayer, int w, int h);
|
||||||
void (*imageSize)(struct VideoBackend*, enum VideoLayer, int* w, int* h);
|
void (*imageSize)(struct VideoBackend*, enum VideoLayer, int* w, int* h);
|
||||||
void (*setImage)(struct VideoBackend*, enum VideoLayer, const void* frame);
|
void (*setImage)(struct VideoBackend*, enum VideoLayer, const void* frame);
|
||||||
|
|
|
@ -61,7 +61,7 @@ static void _mVideoProxyBackendClear(struct VideoBackend* v) {
|
||||||
mVideoProxyBackendSubmit(proxy, &cmd, NULL);
|
mVideoProxyBackendSubmit(proxy, &cmd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w, unsigned h) {
|
static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) {
|
||||||
struct mVideoProxyBackend* proxy = (struct mVideoProxyBackend*) v;
|
struct mVideoProxyBackend* proxy = (struct mVideoProxyBackend*) v;
|
||||||
struct mVideoBackendCommand cmd = {
|
struct mVideoBackendCommand cmd = {
|
||||||
.cmd = mVB_CMD_CONTEXT_RESIZED,
|
.cmd = mVB_CMD_CONTEXT_RESIZED,
|
||||||
|
@ -69,6 +69,8 @@ static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w
|
||||||
.u = {
|
.u = {
|
||||||
.width = w,
|
.width = w,
|
||||||
.height = h,
|
.height = h,
|
||||||
|
.maxW = maxW,
|
||||||
|
.maxH = maxH,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -139,8 +141,8 @@ void mVideoProxyBackendInit(struct mVideoProxyBackend* proxy, struct VideoBacken
|
||||||
proxy->d.drawFrame = _mVideoProxyBackendDrawFrame;
|
proxy->d.drawFrame = _mVideoProxyBackendDrawFrame;
|
||||||
proxy->backend = backend;
|
proxy->backend = backend;
|
||||||
|
|
||||||
RingFIFOInit(&proxy->in, 0x400);
|
RingFIFOInit(&proxy->in, sizeof(union mVideoBackendCommandData) * 0x80);
|
||||||
RingFIFOInit(&proxy->out, 0x400);
|
RingFIFOInit(&proxy->out, sizeof(union mVideoBackendCommandData) * 0x80);
|
||||||
MutexInit(&proxy->inLock);
|
MutexInit(&proxy->inLock);
|
||||||
MutexInit(&proxy->outLock);
|
MutexInit(&proxy->outLock);
|
||||||
ConditionInit(&proxy->inWait);
|
ConditionInit(&proxy->inWait);
|
||||||
|
@ -209,7 +211,7 @@ bool mVideoProxyBackendRun(struct mVideoProxyBackend* proxy, bool block) {
|
||||||
proxy->backend->clear(proxy->backend);
|
proxy->backend->clear(proxy->backend);
|
||||||
break;
|
break;
|
||||||
case mVB_CMD_CONTEXT_RESIZED:
|
case mVB_CMD_CONTEXT_RESIZED:
|
||||||
proxy->backend->contextResized(proxy->backend, cmd.data.u.width, cmd.data.u.height);
|
proxy->backend->contextResized(proxy->backend, cmd.data.u.width, cmd.data.u.height, cmd.data.u.maxW, cmd.data.u.maxH);
|
||||||
break;
|
break;
|
||||||
case mVB_CMD_SET_IMAGE_SIZE:
|
case mVB_CMD_SET_IMAGE_SIZE:
|
||||||
proxy->backend->setImageSize(proxy->backend, cmd.layer, cmd.data.s.width, cmd.data.s.height);
|
proxy->backend->setImageSize(proxy->backend, cmd.layer, cmd.data.s.width, cmd.data.s.height);
|
||||||
|
|
|
@ -103,20 +103,29 @@ static void mGLContextDeinit(struct VideoBackend* v) {
|
||||||
glDeleteTextures(VIDEO_LAYER_MAX, context->layers);
|
glDeleteTextures(VIDEO_LAYER_MAX, context->layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h) {
|
static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) {
|
||||||
unsigned drawW = w;
|
unsigned drawW = w;
|
||||||
unsigned drawH = h;
|
unsigned drawH = h;
|
||||||
|
|
||||||
unsigned maxW;
|
|
||||||
unsigned maxH;
|
if (maxW && drawW > maxW) {
|
||||||
VideoBackendGetFrameSize(v, &maxW, &maxH);
|
drawW = maxW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxH && drawH > maxH) {
|
||||||
|
drawH = maxH;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned lockW;
|
||||||
|
unsigned lockH;
|
||||||
|
VideoBackendGetFrameSize(v, &lockW, &lockH);
|
||||||
|
|
||||||
if (v->lockAspectRatio) {
|
if (v->lockAspectRatio) {
|
||||||
lockAspectRatioUInt(maxW, maxH, &drawW, &drawH);
|
lockAspectRatioUInt(lockW, lockH, &drawW, &drawH);
|
||||||
}
|
}
|
||||||
if (v->lockIntegerScaling) {
|
if (v->lockIntegerScaling) {
|
||||||
lockIntegerRatioUInt(maxW, &drawW);
|
lockIntegerRatioUInt(lockW, &drawW);
|
||||||
lockIntegerRatioUInt(maxH, &drawH);
|
lockIntegerRatioUInt(lockH, &drawH);
|
||||||
}
|
}
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
|
@ -271,20 +271,28 @@ static void mGLES2ContextDeinit(struct VideoBackend* v) {
|
||||||
free(context->initialShader.uniforms);
|
free(context->initialShader.uniforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h) {
|
static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) {
|
||||||
struct mGLES2Context* context = (struct mGLES2Context*) v;
|
struct mGLES2Context* context = (struct mGLES2Context*) v;
|
||||||
unsigned drawW = w;
|
unsigned drawW = w;
|
||||||
unsigned drawH = h;
|
unsigned drawH = h;
|
||||||
|
|
||||||
unsigned maxW = context->width;
|
if (maxW && drawW > maxW) {
|
||||||
unsigned maxH = context->height;
|
drawW = maxW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxH && drawH > maxH) {
|
||||||
|
drawH = maxH;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned lockW = context->width;
|
||||||
|
unsigned lockH = context->height;
|
||||||
|
|
||||||
if (v->lockAspectRatio) {
|
if (v->lockAspectRatio) {
|
||||||
lockAspectRatioUInt(maxW, maxH, &drawW, &drawH);
|
lockAspectRatioUInt(lockW, lockH, &drawW, &drawH);
|
||||||
}
|
}
|
||||||
if (v->lockIntegerScaling) {
|
if (v->lockIntegerScaling) {
|
||||||
lockIntegerRatioUInt(maxW, &drawW);
|
lockIntegerRatioUInt(lockW, &drawW);
|
||||||
lockIntegerRatioUInt(maxH, &drawH);
|
lockIntegerRatioUInt(lockH, &drawH);
|
||||||
}
|
}
|
||||||
size_t n;
|
size_t n;
|
||||||
for (n = 0; n < context->nShaders; ++n) {
|
for (n = 0; n < context->nShaders; ++n) {
|
||||||
|
|
|
@ -57,6 +57,7 @@ public:
|
||||||
virtual void setVideoScale(int) {}
|
virtual void setVideoScale(int) {}
|
||||||
virtual void setBackgroundImage(const QImage&) = 0;
|
virtual void setBackgroundImage(const QImage&) = 0;
|
||||||
virtual QSize contentSize() const = 0;
|
virtual QSize contentSize() const = 0;
|
||||||
|
virtual void setMaximumSize(const QSize& size) = 0;
|
||||||
|
|
||||||
virtual void setVideoProxy(std::shared_ptr<VideoProxy> proxy) { m_videoProxy = std::move(proxy); }
|
virtual void setVideoProxy(std::shared_ptr<VideoProxy> proxy) { m_videoProxy = std::move(proxy); }
|
||||||
std::shared_ptr<VideoProxy> videoProxy() { return m_videoProxy; }
|
std::shared_ptr<VideoProxy> videoProxy() { return m_videoProxy; }
|
||||||
|
@ -105,6 +106,7 @@ private:
|
||||||
bool m_filter = false;
|
bool m_filter = false;
|
||||||
QTimer m_mouseTimer;
|
QTimer m_mouseTimer;
|
||||||
std::shared_ptr<VideoProxy> m_videoProxy;
|
std::shared_ptr<VideoProxy> m_videoProxy;
|
||||||
|
QSize m_maxSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,6 +524,10 @@ int DisplayGL::framebufferHandle() {
|
||||||
return m_painter->glTex();
|
return m_painter->glTex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayGL::setMaximumSize(const QSize& size) {
|
||||||
|
QMetaObject::invokeMethod(m_painter.get(), "setMaximumSize", Q_ARG(const QSize&, size));
|
||||||
|
}
|
||||||
|
|
||||||
PainterGL::PainterGL(QWindow* window, mGLWidget* widget, const QSurfaceFormat& format)
|
PainterGL::PainterGL(QWindow* window, mGLWidget* widget, const QSurfaceFormat& format)
|
||||||
: m_window(window)
|
: m_window(window)
|
||||||
, m_format(format)
|
, m_format(format)
|
||||||
|
@ -720,6 +724,11 @@ void PainterGL::resize(const QSize& size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PainterGL::setMaximumSize(const QSize& size) {
|
||||||
|
m_maxSize = size;
|
||||||
|
resizeContext();
|
||||||
|
}
|
||||||
|
|
||||||
void PainterGL::lockAspectRatio(bool lock) {
|
void PainterGL::lockAspectRatio(bool lock) {
|
||||||
m_backend->lockAspectRatio = lock;
|
m_backend->lockAspectRatio = lock;
|
||||||
resize(m_size);
|
resize(m_size);
|
||||||
|
@ -911,7 +920,11 @@ void PainterGL::unpause() {
|
||||||
|
|
||||||
void PainterGL::performDraw() {
|
void PainterGL::performDraw() {
|
||||||
float r = m_window->devicePixelRatio();
|
float r = m_window->devicePixelRatio();
|
||||||
m_backend->contextResized(m_backend, m_size.width() * r, m_size.height() * r);
|
QSize maxSize = m_maxSize;
|
||||||
|
if (!maxSize.isValid()) {
|
||||||
|
maxSize = QSize(0, 0);
|
||||||
|
}
|
||||||
|
m_backend->contextResized(m_backend, m_size.width() * r, m_size.height() * r, maxSize.width() * r, maxSize.height() * r);
|
||||||
if (m_buffer) {
|
if (m_buffer) {
|
||||||
m_backend->setImage(m_backend, VIDEO_LAYER_IMAGE, m_buffer);
|
m_backend->setImage(m_backend, VIDEO_LAYER_IMAGE, m_buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ public:
|
||||||
void setVideoProxy(std::shared_ptr<VideoProxy>) override;
|
void setVideoProxy(std::shared_ptr<VideoProxy>) override;
|
||||||
int framebufferHandle() override;
|
int framebufferHandle() override;
|
||||||
QSize contentSize() const override { return m_cachedContentSize; }
|
QSize contentSize() const override { return m_cachedContentSize; }
|
||||||
|
void setMaximumSize(const QSize& size) override;
|
||||||
|
|
||||||
static bool highestCompatible(QSurfaceFormat&);
|
static bool highestCompatible(QSurfaceFormat&);
|
||||||
static bool supportsFormat(const QSurfaceFormat&);
|
static bool supportsFormat(const QSurfaceFormat&);
|
||||||
|
@ -172,6 +173,7 @@ public slots:
|
||||||
void pause();
|
void pause();
|
||||||
void unpause();
|
void unpause();
|
||||||
void resize(const QSize& size);
|
void resize(const QSize& size);
|
||||||
|
void setMaximumSize(const QSize& size);
|
||||||
void lockAspectRatio(bool lock);
|
void lockAspectRatio(bool lock);
|
||||||
void lockIntegerScaling(bool lock);
|
void lockIntegerScaling(bool lock);
|
||||||
void interframeBlending(bool enable);
|
void interframeBlending(bool enable);
|
||||||
|
@ -230,6 +232,7 @@ private:
|
||||||
VideoBackend* m_backend = nullptr;
|
VideoBackend* m_backend = nullptr;
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
QSize m_dims;
|
QSize m_dims;
|
||||||
|
QSize m_maxSize;
|
||||||
MessagePainter* m_messagePainter = nullptr;
|
MessagePainter* m_messagePainter = nullptr;
|
||||||
QElapsedTimer m_delayTimer;
|
QElapsedTimer m_delayTimer;
|
||||||
std::shared_ptr<VideoProxy> m_videoProxy;
|
std::shared_ptr<VideoProxy> m_videoProxy;
|
||||||
|
|
|
@ -134,7 +134,20 @@ void DisplayQt::paintEvent(QPaintEvent*) {
|
||||||
if (!drawSize.isValid() || drawSize.width() < 1 || drawSize.height() < 1) {
|
if (!drawSize.isValid() || drawSize.width() < 1 || drawSize.height() < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QRect full(clampSize(contentSize(), size(), isAspectRatioLocked(), isIntegerScalingLocked()));
|
QSize usedSize = size();
|
||||||
|
QPoint screenOrigin(0, 0);
|
||||||
|
if (m_maxSize.isValid()) {
|
||||||
|
if (m_maxSize.width() < usedSize.width()) {
|
||||||
|
screenOrigin.setX((usedSize.width() - m_maxSize.width()) / 2);
|
||||||
|
usedSize.setWidth(m_maxSize.width());
|
||||||
|
}
|
||||||
|
if (m_maxSize.height() < usedSize.height()) {
|
||||||
|
screenOrigin.setY((usedSize.height() - m_maxSize.height()) / 2);
|
||||||
|
usedSize.setHeight(m_maxSize.height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QRect full(clampSize(contentSize(), usedSize, isAspectRatioLocked(), isIntegerScalingLocked()));
|
||||||
|
full.translate(screenOrigin);
|
||||||
painter.save();
|
painter.save();
|
||||||
painter.translate(full.topLeft());
|
painter.translate(full.topLeft());
|
||||||
painter.scale(full.width() / static_cast<qreal>(frame.width), full.height() / static_cast<qreal>(frame.height));
|
painter.scale(full.width() / static_cast<qreal>(frame.width), full.height() / static_cast<qreal>(frame.height));
|
||||||
|
@ -220,7 +233,7 @@ void DisplayQt::swap(struct VideoBackend*) {
|
||||||
void DisplayQt::clear(struct VideoBackend*) {
|
void DisplayQt::clear(struct VideoBackend*) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayQt::contextResized(struct VideoBackend*, unsigned, unsigned) {
|
void DisplayQt::contextResized(struct VideoBackend*, unsigned, unsigned, unsigned, unsigned) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayQt::setImageSize(struct VideoBackend* v, enum VideoLayer layer, int w, int h) {
|
void DisplayQt::setImageSize(struct VideoBackend* v, enum VideoLayer layer, int w, int h) {
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
VideoShader* shaders() override { return nullptr; }
|
VideoShader* shaders() override { return nullptr; }
|
||||||
QSize contentSize() const override;
|
QSize contentSize() const override;
|
||||||
VideoBackend* videoBackend() override { return &m_backend; }
|
VideoBackend* videoBackend() override { return &m_backend; }
|
||||||
|
void setMaximumSize(const QSize& size) override { m_maxSize = size; }
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void stopDrawing() override;
|
void stopDrawing() override;
|
||||||
|
@ -56,7 +58,7 @@ private:
|
||||||
static void layerDimensions(const struct VideoBackend*, enum VideoLayer, struct mRectangle*);
|
static void layerDimensions(const struct VideoBackend*, enum VideoLayer, struct mRectangle*);
|
||||||
static void swap(struct VideoBackend*);
|
static void swap(struct VideoBackend*);
|
||||||
static void clear(struct VideoBackend*);
|
static void clear(struct VideoBackend*);
|
||||||
static void contextResized(struct VideoBackend*, unsigned w, unsigned h);
|
static void contextResized(struct VideoBackend*, unsigned w, unsigned h, unsigned maxW, unsigned maxH);
|
||||||
static void setImageSize(struct VideoBackend*, enum VideoLayer, int w, int h);
|
static void setImageSize(struct VideoBackend*, enum VideoLayer, int w, int h);
|
||||||
static void imageSize(struct VideoBackend*, enum VideoLayer, int* w, int* h);
|
static void imageSize(struct VideoBackend*, enum VideoLayer, int* w, int* h);
|
||||||
static void setImage(struct VideoBackend*, enum VideoLayer, const void* frame);
|
static void setImage(struct VideoBackend*, enum VideoLayer, const void* frame);
|
||||||
|
@ -69,6 +71,7 @@ private:
|
||||||
int m_width = -1;
|
int m_width = -1;
|
||||||
int m_height = -1;
|
int m_height = -1;
|
||||||
QImage m_oldBacking{nullptr};
|
QImage m_oldBacking{nullptr};
|
||||||
|
QSize m_maxSize;
|
||||||
std::shared_ptr<CoreController> m_context = nullptr;
|
std::shared_ptr<CoreController> m_context = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -252,6 +252,9 @@ void Window::argumentsPassed() {
|
||||||
|
|
||||||
void Window::resizeFrame(const QSize& size) {
|
void Window::resizeFrame(const QSize& size) {
|
||||||
QSize newSize(size);
|
QSize newSize(size);
|
||||||
|
if (!m_config->getOption("lockFrameSize").toInt()) {
|
||||||
|
m_savedSize = size;
|
||||||
|
}
|
||||||
if (windowHandle()) {
|
if (windowHandle()) {
|
||||||
QRect geom = windowHandle()->screen()->availableGeometry();
|
QRect geom = windowHandle()->screen()->availableGeometry();
|
||||||
if (newSize.width() > geom.width()) {
|
if (newSize.width() > geom.width()) {
|
||||||
|
@ -1522,7 +1525,10 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
for (int i = 1; i <= 8; ++i) {
|
for (int i = 1; i <= 8; ++i) {
|
||||||
auto setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() {
|
auto setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() {
|
||||||
auto setSize = m_frameSizes[i];
|
auto setSize = m_frameSizes[i];
|
||||||
showNormal();
|
bool lockFrameSize = m_config->getOption("lockFrameSize").toInt();
|
||||||
|
if (!lockFrameSize) {
|
||||||
|
showNormal();
|
||||||
|
}
|
||||||
#if defined(M_CORE_GBA)
|
#if defined(M_CORE_GBA)
|
||||||
QSize minimumSize = QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS);
|
QSize minimumSize = QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS);
|
||||||
#elif defined(M_CORE_GB)
|
#elif defined(M_CORE_GB)
|
||||||
|
@ -1538,7 +1544,11 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
size *= i;
|
size *= i;
|
||||||
m_savedScale = i;
|
m_savedScale = i;
|
||||||
m_config->setOption("scaleMultiplier", i); // TODO: Port to other
|
m_config->setOption("scaleMultiplier", i); // TODO: Port to other
|
||||||
|
m_savedSize = size;
|
||||||
resizeFrame(size);
|
resizeFrame(size);
|
||||||
|
if (lockFrameSize) {
|
||||||
|
m_display->setMaximumSize(size);
|
||||||
|
}
|
||||||
setSize->setActive(true);
|
setSize->setActive(true);
|
||||||
}, "frame");
|
}, "frame");
|
||||||
setSize->setExclusive(true);
|
setSize->setExclusive(true);
|
||||||
|
@ -1553,8 +1563,22 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
#else
|
#else
|
||||||
fullscreenKeys = QKeySequence("Ctrl+F");
|
fullscreenKeys = QKeySequence("Ctrl+F");
|
||||||
#endif
|
#endif
|
||||||
|
m_actions.addSeparator("frame");
|
||||||
m_actions.addAction(tr("Toggle fullscreen"), "fullscreen", this, &Window::toggleFullScreen, "frame", fullscreenKeys);
|
m_actions.addAction(tr("Toggle fullscreen"), "fullscreen", this, &Window::toggleFullScreen, "frame", fullscreenKeys);
|
||||||
|
|
||||||
|
ConfigOption* lockFrameSize = m_config->addOption("lockFrameSize");
|
||||||
|
lockFrameSize->addBoolean(tr("&Lock frame size"), &m_actions, "frame");
|
||||||
|
lockFrameSize->connect([this](const QVariant& value) {
|
||||||
|
if (m_display) {
|
||||||
|
if (value.toBool()) {
|
||||||
|
m_display->setMaximumSize(m_display->size());
|
||||||
|
} else {
|
||||||
|
m_display->setMaximumSize({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
m_config->updateOption("lockFrameSize");
|
||||||
|
|
||||||
ConfigOption* lockAspectRatio = m_config->addOption("lockAspectRatio");
|
ConfigOption* lockAspectRatio = m_config->addOption("lockAspectRatio");
|
||||||
lockAspectRatio->addBoolean(tr("Lock aspect ratio"), &m_actions, "av");
|
lockAspectRatio->addBoolean(tr("Lock aspect ratio"), &m_actions, "av");
|
||||||
lockAspectRatio->connect([this](const QVariant& value) {
|
lockAspectRatio->connect([this](const QVariant& value) {
|
||||||
|
@ -2216,6 +2240,11 @@ void Window::setController(CoreController* controller, const QString& fname) {
|
||||||
void Window::attachDisplay() {
|
void Window::attachDisplay() {
|
||||||
m_display->attach(m_controller);
|
m_display->attach(m_controller);
|
||||||
connect(m_display.get(), &QGBA::Display::drawingStarted, this, &Window::changeRenderer);
|
connect(m_display.get(), &QGBA::Display::drawingStarted, this, &Window::changeRenderer);
|
||||||
|
if (m_config->getOption("lockFrameSize").toInt()) {
|
||||||
|
m_display->setMaximumSize(m_savedSize);
|
||||||
|
} else {
|
||||||
|
m_display->setMaximumSize({});
|
||||||
|
}
|
||||||
m_display->startDrawing(m_controller);
|
m_display->startDrawing(m_controller);
|
||||||
|
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
|
|
@ -194,6 +194,7 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<QGBA::Display> m_display;
|
std::unique_ptr<QGBA::Display> m_display;
|
||||||
QSize m_initialSize;
|
QSize m_initialSize;
|
||||||
|
QSize m_savedSize;
|
||||||
int m_savedScale;
|
int m_savedScale;
|
||||||
|
|
||||||
// TODO: Move these to a new class
|
// TODO: Move these to a new class
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void mSDLGLDoViewport(int w, int h, struct VideoBackend* v) {
|
void mSDLGLDoViewport(int w, int h, struct VideoBackend* v) {
|
||||||
v->contextResized(v, w, h);
|
v->contextResized(v, w, h, 0, 0);
|
||||||
v->clear(v);
|
v->clear(v);
|
||||||
v->swap(v);
|
v->swap(v);
|
||||||
v->clear(v);
|
v->clear(v);
|
||||||
|
|
Loading…
Reference in New Issue