diff --git a/include/core/tileset.h b/include/core/tileset.h index 3d137056..c804a0f9 100644 --- a/include/core/tileset.h +++ b/include/core/tileset.h @@ -90,7 +90,11 @@ public: uint16_t firstMetatileId() const; uint16_t lastMetatileId() const; - bool contains(uint16_t metatileId) const { return metatileId >= firstMetatileId() && metatileId <= lastMetatileId(); } + bool containsMetatileId(uint16_t metatileId) const { return metatileId >= firstMetatileId() && metatileId <= lastMetatileId(); } + + uint16_t firstTileId() const; + uint16_t lastTileId() const; + bool containsTileId(uint16_t tileId) const { return tileId > firstTileId() && tileId <= lastTileId(); } int numTiles() const { return m_tiles.length(); } int maxTiles() const; diff --git a/src/core/tileset.cpp b/src/core/tileset.cpp index d76b0138..0aa1f7d6 100644 --- a/src/core/tileset.cpp +++ b/src/core/tileset.cpp @@ -107,6 +107,14 @@ int Tileset::maxMetatiles() const { return this->is_secondary ? Project::getNumMetatilesSecondary() : Project::getNumMetatilesPrimary(); } +uint16_t Tileset::firstTileId() const { + return this->is_secondary ? Project::getNumTilesPrimary() : 0; +} + +uint16_t Tileset::lastTileId() const { + return qMax(1, firstMetatileId() + m_tiles.length()) - 1; +} + int Tileset::maxTiles() const { return this->is_secondary ? Project::getNumTilesSecondary() : Project::getNumTilesPrimary(); } @@ -250,8 +258,8 @@ QString Tileset::getMetatileLabelPrefix(const QString &name) } bool Tileset::metatileIsValid(uint16_t metatileId, const Tileset *primaryTileset, const Tileset *secondaryTileset) { - return (primaryTileset && primaryTileset->contains(metatileId)) - || (secondaryTileset && secondaryTileset->contains(metatileId)); + return (primaryTileset && primaryTileset->containsMetatileId(metatileId)) + || (secondaryTileset && secondaryTileset->containsMetatileId(metatileId)); } QList> Tileset::getBlockPalettes(const Tileset *primaryTileset, const Tileset *secondaryTileset, bool useTruePalettes) { diff --git a/src/ui/metatileselector.cpp b/src/ui/metatileselector.cpp index 639dc5fa..00725b9a 100644 --- a/src/ui/metatileselector.cpp +++ b/src/ui/metatileselector.cpp @@ -204,7 +204,7 @@ uint16_t MetatileSelector::posToMetatileId(int x, int y, bool *ok) const { if (ok) *ok = true; int index = y * this->numMetatilesWide + x; uint16_t metatileId = static_cast(index); - if (primaryTileset() && primaryTileset()->contains(metatileId)) { + if (primaryTileset() && primaryTileset()->containsMetatileId(metatileId)) { return metatileId; } @@ -215,7 +215,7 @@ uint16_t MetatileSelector::posToMetatileId(int x, int y, bool *ok) const { int numPrimaryRounded = numPrimaryMetatilesRounded(); int firstSecondaryRow = numPrimaryRounded / this->numMetatilesWide; metatileId = static_cast(Project::getNumMetatilesPrimary() + index - numPrimaryRounded); - if (secondaryTileset() && secondaryTileset()->contains(metatileId) && y >= firstSecondaryRow) { + if (secondaryTileset() && secondaryTileset()->containsMetatileId(metatileId) && y >= firstSecondaryRow) { return metatileId; } @@ -224,12 +224,12 @@ uint16_t MetatileSelector::posToMetatileId(int x, int y, bool *ok) const { } QPoint MetatileSelector::metatileIdToPos(uint16_t metatileId, bool *ok) const { - if (primaryTileset() && primaryTileset()->contains(metatileId)) { + if (primaryTileset() && primaryTileset()->containsMetatileId(metatileId)) { if (ok) *ok = true; int index = metatileId; return QPoint(index % this->numMetatilesWide, index / this->numMetatilesWide); } - if (secondaryTileset() && secondaryTileset()->contains(metatileId)) { + if (secondaryTileset() && secondaryTileset()->containsMetatileId(metatileId)) { if (ok) *ok = true; int index = metatileId - Project::getNumMetatilesPrimary() + numPrimaryMetatilesRounded(); return QPoint(index % this->numMetatilesWide, index / this->numMetatilesWide); diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index 99320682..17074063 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -794,7 +794,7 @@ void TilesetEditor::importTilesetTiles(Tileset *tileset) { int numTilesWide = image.width() / Tile::pixelWidth(); int numTilesHigh = image.height() / Tile::pixelHeight(); int totalTiles = numTilesHigh * numTilesWide; - int maxAllowedTiles = primary ? Project::getNumTilesPrimary() : Project::getNumTilesTotal() - Project::getNumTilesPrimary(); + int maxAllowedTiles = primary ? Project::getNumTilesPrimary() : Project::getNumTilesSecondary(); if (totalTiles > maxAllowedTiles) { ErrorMessage::show(QStringLiteral("Failed to import tiles."), QString("The maximum number of tiles allowed in the %1 tileset is %2, but the provided image contains %3 total tiles.") @@ -899,7 +899,7 @@ void TilesetEditor::on_actionChange_Metatiles_Count_triggered() // Our selected metatile ID may have become invalid. Make sure it's in-bounds. uint16_t metatileId = this->metatileSelector->getSelectedMetatileId(); Tileset *tileset = Tileset::getMetatileTileset(metatileId, this->primaryTileset, this->secondaryTileset); - if (tileset && !tileset->contains(metatileId)) { + if (tileset && !tileset->containsMetatileId(metatileId)) { this->metatileSelector->select(qBound(tileset->firstMetatileId(), metatileId, tileset->lastMetatileId())); } @@ -1233,31 +1233,25 @@ void TilesetEditor::countTileUsage() { this->tileSelector->usedTiles.resize(Project::getNumTilesTotal()); this->tileSelector->usedTiles.fill(0); - // Count usage of our primary tileset's tiles in the secondary tilesets it gets paired with. - QSet tilesetNames = this->project->getPairedTilesetLabels(this->primaryTileset); - for (const auto &tilesetName : tilesetNames) { - Tileset *tileset = this->project->getTileset(tilesetName); - if (!tileset) continue; - for (const auto &metatile : tileset->metatiles()) { - for (const auto &tile : metatile->tiles) { - if (tile.tileId < Project::getNumTilesPrimary()) - this->tileSelector->usedTiles[tile.tileId]++; + auto countTilesetTileUsage = [this](Tileset *searchTileset) { + // Count usage of our search tileset's tiles (in itself, and in any tilesets it gets paired with). + QSet tilesetNames = this->project->getPairedTilesetLabels(searchTileset); + tilesetNames.insert(searchTileset->name); + for (const auto &tilesetName : tilesetNames) { + Tileset *tileset = this->project->getTileset(tilesetName); + if (!tileset) continue; + for (const auto &metatile : tileset->metatiles()) { + for (const auto &tile : metatile->tiles) { + if (searchTileset->containsTileId(tile.tileId)) { + this->tileSelector->usedTiles[tile.tileId]++; + } + } } } - } + }; - // Count usage of our secondary tileset's tiles in the primary tilesets it gets paired with. - tilesetNames = this->project->getPairedTilesetLabels(this->secondaryTileset); - for (const auto &tilesetName : tilesetNames) { - Tileset *tileset = this->project->getTileset(tilesetName); - if (!tileset) continue; - for (const auto &metatile : tileset->metatiles()) { - for (const auto &tile : metatile->tiles) { - if (tile.tileId >= Project::getNumTilesPrimary()) - this->tileSelector->usedTiles[tile.tileId]++; - } - } - } + countTilesetTileUsage(this->primaryTileset); + countTilesetTileUsage(this->secondaryTileset); } void TilesetEditor::on_copyButton_MetatileLabel_clicked() { @@ -1396,9 +1390,9 @@ void TilesetEditor::applyMetatileSwapToLayouts(uint16_t metatileIdA, uint16_t me // Get which tilesets our swapped metatiles belong to. auto addSourceTileset = [this](uint16_t metatileId, TilesetPair *tilesets) { - if (this->primaryTileset->contains(metatileId)) { + if (this->primaryTileset->containsMetatileId(metatileId)) { tilesets->primary = this->primaryTileset; - } else if (this->secondaryTileset->contains(metatileId)) { + } else if (this->secondaryTileset->containsMetatileId(metatileId)) { tilesets->secondary = this->secondaryTileset; } else { // Invalid metatile, shouldn't happen diff --git a/src/ui/tileseteditormetatileselector.cpp b/src/ui/tileseteditormetatileselector.cpp index ebb05187..77b14aca 100644 --- a/src/ui/tileseteditormetatileselector.cpp +++ b/src/ui/tileseteditormetatileselector.cpp @@ -205,7 +205,7 @@ uint16_t TilesetEditorMetatileSelector::posToMetatileId(int x, int y, bool *ok) if (ok) *ok = true; int index = y * this->numMetatilesWide + x; uint16_t metatileId = static_cast(index); - if (this->primaryTileset && this->primaryTileset->contains(metatileId)) { + if (this->primaryTileset && this->primaryTileset->containsMetatileId(metatileId)) { return metatileId; } @@ -216,7 +216,7 @@ uint16_t TilesetEditorMetatileSelector::posToMetatileId(int x, int y, bool *ok) int numPrimaryRounded = numPrimaryMetatilesRounded(); int firstSecondaryRow = numPrimaryRounded / this->numMetatilesWide; metatileId = static_cast(Project::getNumMetatilesPrimary() + index - numPrimaryRounded); - if (this->secondaryTileset && this->secondaryTileset->contains(metatileId) && y >= firstSecondaryRow) { + if (this->secondaryTileset && this->secondaryTileset->containsMetatileId(metatileId) && y >= firstSecondaryRow) { return metatileId; } @@ -225,12 +225,12 @@ uint16_t TilesetEditorMetatileSelector::posToMetatileId(int x, int y, bool *ok) } QPoint TilesetEditorMetatileSelector::metatileIdToPos(uint16_t metatileId, bool *ok) const { - if (this->primaryTileset && this->primaryTileset->contains(metatileId)) { + if (this->primaryTileset && this->primaryTileset->containsMetatileId(metatileId)) { if (ok) *ok = true; int index = metatileId; return QPoint(index % this->numMetatilesWide, index / this->numMetatilesWide); } - if (this->secondaryTileset && this->secondaryTileset->contains(metatileId)) { + if (this->secondaryTileset && this->secondaryTileset->containsMetatileId(metatileId)) { if (ok) *ok = true; int index = metatileId - Project::getNumMetatilesPrimary() + numPrimaryMetatilesRounded(); return QPoint(index % this->numMetatilesWide, index / this->numMetatilesWide); diff --git a/src/ui/tileseteditortileselector.cpp b/src/ui/tileseteditortileselector.cpp index e088cdee..e82e7dc6 100644 --- a/src/ui/tileseteditortileselector.cpp +++ b/src/ui/tileseteditortileselector.cpp @@ -54,22 +54,26 @@ void TilesetEditorTileSelector::updateBasePixmap() { int y = (tileId / this->numTilesWide) * this->cellHeight; painter.drawImage(x, y, tileImage); } - - if (this->showDivider) { - int row = Util::roundUpToMultiple(Project::getNumTilesPrimary(), this->numTilesWide) / this->numTilesWide; - const int y = row * this->cellHeight; - painter.setPen(Qt::white); - painter.drawLine(0, y, this->numTilesWide * this->cellWidth, y); - } - painter.end(); + this->basePixmap = QPixmap::fromImage(image); } void TilesetEditorTileSelector::draw() { if (this->basePixmap.isNull()) updateBasePixmap(); - setPixmap(this->basePixmap); + + QPixmap pixmap = this->basePixmap; + + if (this->showDivider) { + QPainter painter(&pixmap); + int row = Util::roundUpToMultiple(Project::getNumTilesPrimary(), this->numTilesWide) / this->numTilesWide; + const int y = row * this->cellHeight; + painter.setPen(Qt::white); + painter.drawLine(0, y, this->numTilesWide * this->cellWidth, y); + } + + setPixmap(pixmap); if (!this->externalSelection || (this->externalSelectionWidth == 1 && this->externalSelectionHeight == 1)) { this->drawSelection();