diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index eef257025..c13af9403 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -204,8 +204,8 @@ bool AssetView::lookupObjGBA(int id, struct ObjInfo* info) { GBAObjAttributesCGetPriority(obj->c), GBAObjAttributesBGetX(obj->b), GBAObjAttributesAGetY(obj->a), - GBAObjAttributesBIsHFlip(obj->b), - GBAObjAttributesBIsVFlip(obj->b), + bool(GBAObjAttributesBIsHFlip(obj->b)), + bool(GBAObjAttributesBIsVFlip(obj->b)), }; GBARegisterDISPCNT dispcnt = gba->memory.io[0]; // FIXME: Register name can't be imported due to namespacing issues if (!GBARegisterDISPCNTIsObjCharacterMapping(dispcnt)) { @@ -255,8 +255,8 @@ bool AssetView::lookupObjGB(int id, struct ObjInfo* info) { GBObjAttributesGetPriority(obj->attr), obj->x, obj->y, - GBObjAttributesIsXFlip(obj->attr), - GBObjAttributesIsYFlip(obj->attr), + bool(GBObjAttributesIsXFlip(obj->attr)), + bool(GBObjAttributesIsYFlip(obj->attr)), }; *info = newInfo; return true; diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 121bd9171..989e0f775 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -38,6 +38,7 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent }); m_glowTimer.start(); + m_ui.renderedView->installEventFilter(this); m_ui.compositedView->installEventFilter(this); connect(m_ui.queue, &QListWidget::itemChanged, this, [this](QListWidgetItem* item) { @@ -58,10 +59,19 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent } invalidateQueue(); }); + connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), this, [this]() { + invalidateQueue(); + + QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); + m_ui.renderedView->setPixmap(rendered); + }); } -void FrameView::selectLayer(const QPointF& coord) { - for (const Layer& layer : m_queue) { +bool FrameView::lookupLayer(const QPointF& coord, Layer*& out) { + for (Layer& layer : m_queue) { + if (!layer.enabled || m_disabled.contains(layer.id)) { + continue; + } QPointF location = layer.location; QSizeF layerDims(layer.image.width(), layer.image.height()); QRegion region; @@ -82,11 +92,33 @@ void FrameView::selectLayer(const QPointF& coord) { } if (region.contains(QPoint(coord.x(), coord.y()))) { - m_active = layer.id; - m_glowFrame = 0; - break; + out = &layer; + return true; } } + return false; +} + +void FrameView::selectLayer(const QPointF& coord) { + Layer* layer; + if (!lookupLayer(coord, layer)) { + return; + } + if (layer->id == m_active) { + m_active = {}; + } else { + m_active = layer->id; + } + m_glowFrame = 0; +} + +void FrameView::disableLayer(const QPointF& coord) { + Layer* layer; + if (!lookupLayer(coord, layer)) { + return; + } + layer->enabled = false; + m_disabled.insert(layer->id); } void FrameView::updateTilesGBA(bool force) { @@ -99,6 +131,7 @@ void FrameView::updateTilesGBA(bool force) { updateRendered(); uint16_t* io = static_cast(m_controller->thread()->core->board)->memory.io; + QRgb backdrop = M_RGB5_TO_RGB8(static_cast(m_controller->thread()->core->board)->video.palette[0]); int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]); std::array enabled{ @@ -124,7 +157,7 @@ void FrameView::updateTilesGBA(bool force) { } m_queue.append({ { LayerId::SPRITE, sprite }, - !m_disabled.contains({ LayerId::SPRITE, sprite}), + !m_disabled.contains({ LayerId::SPRITE, sprite }), QPixmap::fromImage(obj), {}, offset, false }); @@ -150,7 +183,7 @@ void FrameView::updateTilesGBA(bool force) { }; m_queue.append({ { LayerId::BACKGROUND, bg }, - !m_disabled.contains({ LayerId::BACKGROUND, bg}), + !m_disabled.contains({ LayerId::BACKGROUND, bg }), QPixmap::fromImage(compositeMap(bg, m_mapStatus[bg])), {}, offset, true }); @@ -161,6 +194,15 @@ void FrameView::updateTilesGBA(bool force) { } } } + QImage backdropImage(QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS), QImage::Format_Mono); + backdropImage.fill(1); + backdropImage.setColorTable({backdrop, backdrop | 0xFF000000 }); + m_queue.append({ + { LayerId::BACKDROP }, + !m_disabled.contains({ LayerId::BACKDROP }), + QPixmap::fromImage(backdropImage), + {}, {0, 0}, false + }); } invalidateQueue(QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS)); } @@ -178,19 +220,18 @@ void FrameView::updateTilesGB(bool force) { } void FrameView::invalidateQueue(const QSize& dims) { - QSize realDims = dims; - if (!dims.isValid()) { - realDims = m_composited.size() / m_ui.magnification->value(); + if (dims.isValid()) { + m_dims = dims; } bool blockSignals = m_ui.queue->blockSignals(true); - QPixmap composited(realDims); + QPixmap composited(m_dims); QPainter painter(&composited); QPalette palette; QColor activeColor = palette.color(QPalette::HighlightedText); activeColor.setAlpha(sin(m_glowFrame * M_PI / 60) * 16 + 96); - QRectF rect(0, 0, realDims.width(), realDims.height()); + QRectF rect(0, 0, m_dims.width(), m_dims.height()); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.fillRect(rect, QColor(0, 0, 0, 0)); @@ -264,7 +305,7 @@ void FrameView::invalidateQueue(const QSize& dims) { } m_ui.queue->blockSignals(blockSignals); - m_composited = composited.scaled(realDims * m_ui.magnification->value()); + m_composited = composited.scaled(m_dims * m_ui.magnification->value()); m_ui.compositedView->setPixmap(m_composited); } @@ -273,18 +314,25 @@ void FrameView::updateRendered() { return; } m_rendered.convertFromImage(m_controller->getPixels()); - m_rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); - m_ui.renderedView->setPixmap(m_rendered); + QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); + m_ui.renderedView->setPixmap(rendered); } bool FrameView::eventFilter(QObject* obj, QEvent* event) { - if (event->type() != QEvent::MouseButtonPress) { - return false; + QPointF pos; + switch (event->type()) { + case QEvent::MouseButtonPress: + pos = static_cast(event)->localPos(); + pos /= m_ui.magnification->value(); + selectLayer(pos); + return true; + case QEvent::MouseButtonDblClick: + pos = static_cast(event)->localPos(); + pos /= m_ui.magnification->value(); + disableLayer(pos); + return true; } - QPointF pos = static_cast(event)->localPos(); - pos /= m_ui.magnification->value(); - selectLayer(pos); - return true; + return false; } QString FrameView::LayerId::readable() const { @@ -301,6 +349,9 @@ QString FrameView::LayerId::readable() const { case SPRITE: typeStr = tr("Sprite"); break; + case BACKDROP: + typeStr = tr("Backdrop"); + break; } if (index < 0) { return typeStr; diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index 626dfbd62..4fd1bea09 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -30,6 +30,7 @@ public: public slots: void selectLayer(const QPointF& coord); + void disableLayer(const QPointF& coord); protected: #ifdef M_CORE_GBA @@ -41,13 +42,18 @@ protected: bool eventFilter(QObject* obj, QEvent* event) override; +private slots: + void invalidateQueue(const QSize& dims = QSize()); + void updateRendered(); + private: struct LayerId { enum { NONE = 0, BACKGROUND, WINDOW, - SPRITE + SPRITE, + BACKDROP } type = NONE; int index = -1; @@ -65,8 +71,7 @@ private: bool repeats; }; - void invalidateQueue(const QSize& dims = QSize()); - void updateRendered(); + bool lookupLayer(const QPointF& coord, Layer*&); Ui::FrameView m_ui; @@ -75,6 +80,7 @@ private: int m_glowFrame; QTimer m_glowTimer; + QSize m_dims; QList m_queue; QSet m_disabled; QPixmap m_composited;