diff --git a/include/mainwindow.h b/include/mainwindow.h index eff9b871..8178b625 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -128,7 +128,7 @@ private slots: private: Ui::MainWindow *ui; - TilesetEditor *tilesetEditor; + TilesetEditor *tilesetEditor = nullptr; QStandardItemModel *mapListModel; QList *mapGroupsModel; QMap mapListIndexes; diff --git a/include/ui/imageproviders.h b/include/ui/imageproviders.h index 4bff143a..c48f920f 100644 --- a/include/ui/imageproviders.h +++ b/include/ui/imageproviders.h @@ -8,7 +8,8 @@ QImage getCollisionMetatileImage(Block); QImage getCollisionMetatileImage(int, int); -QImage getMetatileImage(int, Tileset*, Tileset*); -QImage getTileImage(int, Tileset*, Tileset*); +QImage getMetatileImage(uint16_t, Tileset*, Tileset*); +QImage getTileImage(uint16_t, Tileset*, Tileset*); +QImage getColoredTileImage(uint16_t, Tileset*, Tileset*, QList); #endif // IMAGEPROVIDERS_H diff --git a/include/ui/tileseteditor.h b/include/ui/tileseteditor.h index 2ea6f3ed..43370ab0 100644 --- a/include/ui/tileseteditor.h +++ b/include/ui/tileseteditor.h @@ -4,6 +4,7 @@ #include #include "project.h" #include "tileseteditormetatileselector.h" +#include "tileseteditortileselector.h" namespace Ui { class TilesetEditor; @@ -21,15 +22,22 @@ private slots: void onHoveredMetatileChanged(uint16_t); void onHoveredMetatileCleared(); void onSelectedMetatileChanged(uint16_t); + void onHoveredTileChanged(uint16_t); + void onHoveredTileCleared(); + void onSelectedTileChanged(uint16_t); private: - void initMetatilesSelector(); + void initMetatileSelector(); + void initTileSelector(); Ui::TilesetEditor *ui; TilesetEditorMetatileSelector *metatileSelector; + TilesetEditorTileSelector *tileSelector; Project *project; + uint paletteNum; QString primaryTilesetLabel; QString secondaryTilesetLabel; QGraphicsScene *metatilesScene; + QGraphicsScene *tilesScene; }; #endif // TILESETEDITOR_H diff --git a/include/ui/tileseteditortileselector.h b/include/ui/tileseteditortileselector.h new file mode 100644 index 00000000..d13aa19e --- /dev/null +++ b/include/ui/tileseteditortileselector.h @@ -0,0 +1,47 @@ +#ifndef TILESETEDITORTILESELECTOR_H +#define TILESETEDITORTILESELECTOR_H + +#include "selectablepixmapitem.h" +#include "tileset.h" + +class TilesetEditorTileSelector: public SelectablePixmapItem { + Q_OBJECT +public: + TilesetEditorTileSelector(Tileset *primaryTileset, Tileset *secondaryTileset): SelectablePixmapItem(16, 16, 1, 1) { + this->primaryTileset = primaryTileset; + this->secondaryTileset = secondaryTileset; + this->numTilesWide = 16; + this->paletteNum = 0; + setAcceptHoverEvents(true); + } + void draw(); + void select(uint16_t metatileId); + void setTilesets(Tileset*, Tileset*); + void setPaletteNum(int); + uint16_t getSelectedTile(); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + void hoverMoveEvent(QGraphicsSceneHoverEvent*); + void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + +private: + Tileset *primaryTileset; + Tileset *secondaryTileset; + uint16_t selectedTile; + int numTilesWide; + int paletteNum; + void updateSelectedTile(); + uint16_t getTileId(int x, int y); + QPoint getTileCoords(uint16_t); + QList getCurPaletteTable(); + +signals: + void hoveredTileChanged(uint16_t); + void hoveredTileCleared(); + void selectedTileChanged(uint16_t); +}; + +#endif // TILESETEDITORTILESELECTOR_H diff --git a/porymap.pro b/porymap.pro index 62c92337..311630d9 100644 --- a/porymap.pro +++ b/porymap.pro @@ -42,6 +42,7 @@ SOURCES += src/core/block.cpp \ src/ui/selectablepixmapitem.cpp \ src/ui/tileseteditor.cpp \ src/ui/tileseteditormetatileselector.cpp \ + src/ui/tileseteditortileselector.cpp \ src/editor.cpp \ src/main.cpp \ src/mainwindow.cpp \ @@ -78,6 +79,7 @@ HEADERS += include/core/block.h \ include/ui/selectablepixmapitem.h \ include/ui/tileseteditor.h \ include/ui/tileseteditormetatileselector.h \ + include/ui/tileseteditortileselector.h \ include/editor.h \ include/mainwindow.h \ include/project.h \ diff --git a/src/ui/imageproviders.cpp b/src/ui/imageproviders.cpp index d5873800..bda02cc0 100644 --- a/src/ui/imageproviders.cpp +++ b/src/ui/imageproviders.cpp @@ -13,7 +13,7 @@ QImage getCollisionMetatileImage(int collision, int elevation) { return collisionImage.toImage(); } -QImage getMetatileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) { +QImage getMetatileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset) { QImage metatile_image(16, 16, QImage::Format_RGBA8888); Metatile* metatile = Tileset::getMetatile(tile, primaryTileset, secondaryTileset); @@ -71,7 +71,7 @@ QImage getMetatileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTil return metatile_image; } -QImage getTileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) { +QImage getTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset) { Tileset *tileset = Tileset::getBlockTileset(tile, primaryTileset, secondaryTileset); int local_index = Metatile::getBlockIndex(tile); if (!tileset || !tileset->tiles) { @@ -79,3 +79,11 @@ QImage getTileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTileset } return tileset->tiles->value(local_index, QImage()); } + +QImage getColoredTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset, QList palette) { + QImage tileImage = getTileImage(tile, primaryTileset, secondaryTileset); + for (int i = 0; i < 16; i++) { + tileImage.setColor(i, palette.at(i)); + } + return tileImage; +} diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp index 6579d72d..63c90ff1 100644 --- a/src/ui/tileseteditor.cpp +++ b/src/ui/tileseteditor.cpp @@ -12,7 +12,8 @@ TilesetEditor::TilesetEditor(Project *project, QString primaryTilesetLabel, QStr this->primaryTilesetLabel = primaryTilesetLabel; this->secondaryTilesetLabel = secondaryTilesetLabel; - initMetatilesSelector(); + initMetatileSelector(); + initTileSelector(); } TilesetEditor::~TilesetEditor() @@ -20,7 +21,7 @@ TilesetEditor::~TilesetEditor() delete ui; } -void TilesetEditor::initMetatilesSelector() +void TilesetEditor::initMetatileSelector() { Tileset *primaryTileset = this->project->getTileset(this->primaryTilesetLabel); Tileset *secondaryTileset = this->project->getTileset(this->secondaryTilesetLabel); @@ -41,6 +42,27 @@ void TilesetEditor::initMetatilesSelector() this->ui->graphicsView_Metatiles->setFixedSize(this->metatileSelector->pixmap().width() + 2, this->metatileSelector->pixmap().height() + 2); } +void TilesetEditor::initTileSelector() +{ + Tileset *primaryTileset = this->project->getTileset(this->primaryTilesetLabel); + Tileset *secondaryTileset = this->project->getTileset(this->secondaryTilesetLabel); + this->tileSelector = new TilesetEditorTileSelector(primaryTileset, secondaryTileset); + connect(this->tileSelector, SIGNAL(hoveredTileChanged(uint16_t)), + this, SLOT(onHoveredTileChanged(uint16_t))); + connect(this->tileSelector, SIGNAL(hoveredTileCleared()), + this, SLOT(onHoveredTileCleared())); + connect(this->tileSelector, SIGNAL(selectedTileChanged(uint16_t)), + this, SLOT(onSelectedTileChanged(uint16_t))); + + this->tilesScene = new QGraphicsScene; + this->tilesScene->addItem(this->tileSelector); + this->tileSelector->select(0); + this->tileSelector->draw(); + + this->ui->graphicsView_Tiles->setScene(this->tilesScene); + this->ui->graphicsView_Tiles->setFixedSize(this->tileSelector->pixmap().width() + 2, this->tileSelector->pixmap().height() + 2); +} + void TilesetEditor::onHoveredMetatileChanged(uint16_t metatileId) { QString message = QString("Metatile: 0x%1") .arg(QString("%1").arg(metatileId, 3, 16, QChar('0')).toUpper()); @@ -54,3 +76,17 @@ void TilesetEditor::onHoveredMetatileCleared() { void TilesetEditor::onSelectedMetatileChanged(uint16_t) { } + +void TilesetEditor::onHoveredTileChanged(uint16_t tile) { + QString message = QString("Tile: 0x%1") + .arg(QString("%1").arg(tile, 3, 16, QChar('0')).toUpper()); + this->ui->statusbar->showMessage(message); +} + +void TilesetEditor::onHoveredTileCleared() { + this->ui->statusbar->clearMessage(); +} + +void TilesetEditor::onSelectedTileChanged(uint16_t) { + +} diff --git a/src/ui/tileseteditortileselector.cpp b/src/ui/tileseteditortileselector.cpp new file mode 100644 index 00000000..367af1b4 --- /dev/null +++ b/src/ui/tileseteditortileselector.cpp @@ -0,0 +1,126 @@ +#include "tileseteditortileselector.h" +#include "imageproviders.h" +#include "project.h" +#include + +void TilesetEditorTileSelector::draw() { + if (!this->primaryTileset || !this->primaryTileset->tiles + || !this->secondaryTileset || !this->secondaryTileset->tiles) { + this->setPixmap(QPixmap()); + } + + int totalTiles = Project::getNumTilesTotal(); + int primaryLength = this->primaryTileset->tiles->length(); + int secondaryLength = this->secondaryTileset->tiles->length(); + int height = totalTiles / this->numTilesWide; + QList palette = this->getCurPaletteTable(); + QImage image(this->numTilesWide * 16, height * 16, QImage::Format_RGBA8888); + + QPainter painter(&image); + for (uint16_t tile = 0; tile < totalTiles; tile++) { + QImage tileImage; + if (tile < primaryLength) { + tileImage = getColoredTileImage(tile, this->primaryTileset, this->secondaryTileset, palette).scaled(16, 16); + } else if (tile < Project::getNumTilesPrimary()) { + tileImage = QImage(16, 16, QImage::Format_RGBA8888); + tileImage.fill(palette.at(0)); + } else if (tile < Project::getNumTilesPrimary() + secondaryLength) { + tileImage = getColoredTileImage(tile, this->primaryTileset, this->secondaryTileset, palette).scaled(16, 16); + } else { + tileImage = QImage(16, 16, QImage::Format_RGBA8888); + QPainter painter(&tileImage); + painter.fillRect(0, 0, 16, 16, palette.at(0)); + } + + int y = tile / this->numTilesWide; + int x = tile % this->numTilesWide; + QPoint origin = QPoint(x * 16, y * 16); + painter.drawImage(origin, tileImage); + } + + painter.end(); + this->setPixmap(QPixmap::fromImage(image)); + this->drawSelection(); +} + +QList TilesetEditorTileSelector::getCurPaletteTable() { + QList paletteTable; + for (int i = 0; i < this->primaryTileset->palettes->at(this->paletteNum).length(); i++) { + paletteTable.append(this->primaryTileset->palettes->at(this->paletteNum).at(i)); + } + + return paletteTable; +} + +void TilesetEditorTileSelector::select(uint16_t tile) { + QPoint coords = this->getTileCoords(tile); + SelectablePixmapItem::select(coords.x(), coords.y(), 0, 0); + this->selectedTile = tile; + emit selectedTileChanged(tile); +} + +void TilesetEditorTileSelector::setTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) { + this->primaryTileset = primaryTileset; + this->secondaryTileset = secondaryTileset; + this->draw(); +} + +void TilesetEditorTileSelector::setPaletteNum(int paletteNum) { + this->paletteNum = paletteNum; + this->draw(); +} + +void TilesetEditorTileSelector::updateSelectedTile() { + QPoint origin = this->getSelectionStart(); + this->selectedTile = this->getTileId(origin.x(), origin.y()); +} + +uint16_t TilesetEditorTileSelector::getSelectedTile() { + return this->selectedTile; +} + +uint16_t TilesetEditorTileSelector::getTileId(int x, int y) { + return static_cast(y * this->numTilesWide + x); +} + +void TilesetEditorTileSelector::mousePressEvent(QGraphicsSceneMouseEvent *event) { + SelectablePixmapItem::mousePressEvent(event); + this->updateSelectedTile(); + emit selectedTileChanged(this->selectedTile); +} + +void TilesetEditorTileSelector::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + SelectablePixmapItem::mouseMoveEvent(event); + this->updateSelectedTile(); + + QPoint pos = this->getCellPos(event->pos()); + uint16_t tile = this->getTileId(pos.x(), pos.y()); + emit hoveredTileChanged(tile); + emit selectedTileChanged(tile); +} + +void TilesetEditorTileSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + SelectablePixmapItem::mouseReleaseEvent(event); + this->updateSelectedTile(); + emit selectedTileChanged(this->selectedTile); +} + +void TilesetEditorTileSelector::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { + QPoint pos = this->getCellPos(event->pos()); + uint16_t tile = this->getTileId(pos.x(), pos.y()); + emit this->hoveredTileChanged(tile); +} + +void TilesetEditorTileSelector::hoverLeaveEvent(QGraphicsSceneHoverEvent*) { + emit this->hoveredTileCleared(); +} + +QPoint TilesetEditorTileSelector::getTileCoords(uint16_t tile) { + if (tile >= Project::getNumTilesTotal()) + { + // Invalid tile. + return QPoint(0, 0); + } + + return QPoint(tile % this->numTilesWide, tile / this->numTilesWide); +}