Qt: Make clicking tiles work
@@ -66,6 +66,8 @@ void mMapCacheConfigureSystem(struct mMapCache* cache, mMapCacheSystemInfo config);
void mMapCacheConfigureMap(struct mMapCache* cache, uint32_t mapStart); void mMapCacheWriteVRAM(struct mMapCache* cache, uint32_t address); +uint32_t mMapCacheTileId(struct mMapCache* cache, unsigned x, unsigned y); + bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* entry, unsigned x, unsigned y); void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y);
@@ -114,7 +114,7 @@ break;
} } -static inline size_t _tileId(struct mMapCache* cache, unsigned x, unsigned y) { +uint32_t mMapCacheTileId(struct mMapCache* cache, unsigned x, unsigned y) { int tilesWide = mMapCacheSystemInfoGetTilesWide(cache->sysConfig); int tilesHigh = mMapCacheSystemInfoGetTilesHigh(cache->sysConfig); int stride = 1 << mMapCacheSystemInfoGetMacroTileSize(cache->sysConfig);@@ -130,7 +130,7 @@ return stride * y + x;
} void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y) { - size_t location = _tileId(cache, x, y); + size_t location = mMapCacheTileId(cache, x, y); struct mMapCacheEntry* status = &cache->status[location]; const color_t* tile = NULL; if (!mMapCacheEntryFlagsIsVramClean(status->flags)) {@@ -156,7 +156,7 @@ entry[location] = *status;
} bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* entry, unsigned x, unsigned y) { - size_t location = _tileId(cache, x, y); + size_t location = mMapCacheTileId(cache, x, y); struct mMapCacheEntry* status = &cache->status[location]; int paletteId = mMapCacheEntryFlagsGetPaletteId(status->flags); const color_t* tile = NULL;
@@ -9,6 +9,7 @@ #include "CoreController.h"
#include "GBAApp.h" #include <QFontDatabase> +#include <QHBoxLayout> #include <mgba/core/interface.h> #ifdef M_CORE_GBA@@ -34,10 +35,23 @@
const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont); m_ui.tileId->setFont(font); + m_ui.paletteId->setFont(font); m_ui.address->setFont(font); m_ui.r->setFont(font); m_ui.g->setFont(font); m_ui.b->setFont(font); +} + +void AssetTile::addCustomProperty(const QString& id, const QString& visibleName) { + QHBoxLayout* newLayout = new QHBoxLayout; + newLayout->addWidget(new QLabel(visibleName)); + QLabel* value = new QLabel; + value->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + value->setAlignment(Qt::AlignRight); + newLayout->addWidget(value); + m_customProperties[id] = value; + int index = layout()->indexOf(m_ui.line); + static_cast<QBoxLayout*>(layout())->insertLayout(index, newLayout); } void AssetTile::setController(std::shared_ptr<CoreController> controller) {@@ -94,14 +108,28 @@ dispIndex -= m_boundary / 2;
} data = mTileCacheGetTile(tileCache, index, paletteId); m_ui.tileId->setText(QString::number(dispIndex)); + m_ui.paletteId->setText(QString::number(paletteId)); m_ui.address->setText(tr("%0%1%2") .arg(m_addressWidth == 4 ? index >= m_boundary / 2 : 0) .arg(m_addressWidth == 4 ? ":" : "x") .arg(dispIndex * bpp | base, m_addressWidth, 16, QChar('0'))); + int flip = 0; + if (m_flipH) { + flip |= 007; + } + if (m_flipV) { + flip |= 070; + } for (int i = 0; i < 64; ++i) { - m_ui.preview->setColor(i, data[i]); + m_ui.preview->setColor(i ^ flip, data[i]); } m_ui.preview->update(); +} + +void AssetTile::setFlip(bool h, bool v) { + m_flipH = h; + m_flipV = v; + selectIndex(m_index); } void AssetTile::selectColor(int index) {@@ -122,3 +150,10 @@ m_ui.g->setText(tr("0x%0 (%1)").arg(g, 2, 16, QChar('0')).arg(g, 2, 10, QChar('0')));
m_ui.b->setText(tr("0x%0 (%1)").arg(b, 2, 16, QChar('0')).arg(b, 2, 10, QChar('0'))); } +void AssetTile::setCustomProperty(const QString& id, const QVariant& value) { + QLabel* label = m_customProperties[id]; + if (!label) { + return; + } + label->setText(value.toString()); +}
@@ -21,12 +21,15 @@
public: AssetTile(QWidget* parent = nullptr); void setController(std::shared_ptr<CoreController>); + void addCustomProperty(const QString& id, const QString& visibleName); public slots: void setPalette(int); void setBoundary(int boundary, int set0, int set1); void selectIndex(int); + void setFlip(bool h, bool v); void selectColor(int); + void setCustomProperty(const QString& id, const QVariant& value); private: Ui::AssetTile m_ui;@@ -40,6 +43,10 @@ int m_addressWidth;
int m_addressBase; int m_boundary; int m_boundaryBase; + bool m_flipH = false; + bool m_flipV = false; + + QMap<QString, QLabel*> m_customProperties; }; }
@@ -2,6 +2,14 @@ <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <class>AssetTile</class> <widget class="QGroupBox" name="AssetTile"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>171</width> + <height>355</height> + </rect> + </property> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> <horstretch>0</horstretch>@@ -36,6 +44,27 @@ </widget>
</item> <item> <widget class="QLabel" name="tileId"> + <property name="text"> + <string>0</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Palette #</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="paletteId"> <property name="text"> <string>0</string> </property>
@@ -10,9 +10,16 @@ #include "GBAApp.h"
#include "LogController.h" #include <mgba-util/png-io.h> +#ifdef M_CORE_GBA +#include <mgba/internal/gba/memory.h> +#endif +#ifdef M_CORE_GB +#include <mgba/internal/gb/memory.h> +#endif #include <QButtonGroup> #include <QFontDatabase> +#include <QMouseEvent> #include <QRadioButton> #include <QTimer>@@ -28,17 +35,22 @@
switch (m_controller->platform()) { #ifdef M_CORE_GBA case PLATFORM_GBA: - m_ui.tile->setBoundary(2048, 0, 2); + m_boundary = 2048; + m_addressBase = BASE_VRAM; + m_addressWidth = 8; break; #endif #ifdef M_CORE_GB case PLATFORM_GB: - m_ui.tile->setBoundary(1024, 0, 0); + m_boundary = 1024; + m_addressBase = GB_BASE_VRAM; + m_addressWidth = 4; break; #endif default: return; } + m_ui.tile->setBoundary(m_boundary, 0, 0); connect(m_ui.magnification, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [this]() { updateTiles(true);@@ -67,6 +79,10 @@ connect(m_ui.exportButton, &QAbstractButton::clicked, this, &MapView::exportMap);
#else m_ui.exportButton->setVisible(false); #endif + m_ui.map->installEventFilter(this); + m_ui.tile->addCustomProperty("mapAddr", tr("Map Addr.")); + m_ui.tile->addCustomProperty("flip", tr("Mirror")); + selectTile(0, 0); } void MapView::selectMap(int map) {@@ -78,6 +94,45 @@ return;
} m_map = map; updateTiles(true); +} + +void MapView::selectTile(int x, int y) { + CoreController::Interrupter interrupter(m_controller); + mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map); + size_t tileCache = mTileCacheSetIndex(&m_cacheSet->tiles, mapCache->tileCache); + m_ui.tile->setBoundary(m_boundary, tileCache, tileCache); + uint32_t location = mMapCacheTileId(mapCache, x, y); + mMapCacheEntry* entry = &m_mapStatus[location]; + m_ui.tile->selectIndex(entry->tileId + mapCache->tileStart); + m_ui.tile->setPalette(mMapCacheEntryFlagsGetPaletteId(entry->flags)); + m_ui.tile->setFlip(mMapCacheEntryFlagsGetHMirror(entry->flags), mMapCacheEntryFlagsGetVMirror(entry->flags)); + location <<= (mMapCacheSystemInfoGetMapAlign(mapCache->sysConfig)); + location += m_addressBase + mapCache->mapStart; + + QString flip(tr("None")); + if (mMapCacheEntryFlagsGetHMirror(entry->flags) && mMapCacheEntryFlagsGetVMirror(entry->flags)) { + flip = tr("Both"); + } else if (mMapCacheEntryFlagsGetHMirror(entry->flags)) { + flip = tr("Horizontal"); + } else if (mMapCacheEntryFlagsGetVMirror(entry->flags)) { + flip = tr("Vertical"); + } + m_ui.tile->setCustomProperty("flip", flip); + m_ui.tile->setCustomProperty("mapAddr", QString("%0%1") + .arg(m_addressWidth == 8 ? "0x" : "") + .arg(location, m_addressWidth, 16, QChar('0'))); +} + +bool MapView::eventFilter(QObject* obj, QEvent* event) { + if (event->type() != QEvent::MouseButtonPress) { + return false; + } + int x = static_cast<QMouseEvent*>(event)->x(); + int y = static_cast<QMouseEvent*>(event)->y(); + x /= 8 * m_ui.magnification->value(); + y /= 8 * m_ui.magnification->value(); + selectTile(x, y); + return true; } void MapView::updateTilesGBA(bool force) {
@@ -28,6 +28,10 @@ #endif
private slots: void selectMap(int); + void selectTile(int x, int y); + +protected: + bool eventFilter(QObject*, QEvent*) override; private: #ifdef M_CORE_GBA@@ -43,6 +47,9 @@ std::shared_ptr<CoreController> m_controller;
mMapCacheEntry m_mapStatus[128 * 128] = {}; // TODO: Correct size int m_map = 0; QImage m_rawMap; + int m_boundary; + int m_addressBase; + int m_addressWidth; }; }
@@ -6,8 +6,8 @@ <property name="geometry">
<rect> <x>0</x> <y>0</y> - <width>498</width> - <height>335</height> + <width>641</width> + <height>489</height> </rect> </property> <property name="windowTitle">@@ -30,8 +30,8 @@ <property name="geometry">
<rect> <x>0</x> <y>0</y> - <width>314</width> - <height>309</height> + <width>457</width> + <height>463</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout">