diff --git a/include/mainwindow.h b/include/mainwindow.h index f6ed14ab..2d4622d5 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -76,6 +76,9 @@ public: Q_INVOKABLE void addFilledRect(int x, int y, int width, int height, QString color = "#000000", int layer = 0); Q_INVOKABLE void addImage(int x, int y, QString filepath, int layer = 0); Q_INVOKABLE void createImage(int x, int y, QString filepath, int width = -1, int height = -1, unsigned offset = 0, bool hflip = false, bool vflip = false, bool setTransparency = false, int layer = 0); + Q_INVOKABLE void addTileImage(int x, int y, int tileId, bool xflip, bool yflip, int palette, int layer = 0); + Q_INVOKABLE void addTilesImage(int x, int y, QJSValue tilesObj, int layer = 0); + Q_INVOKABLE void addMetatileImage(int x, int y, int metatileId, int layer = 0); void refreshAfterPaletteChange(Tileset *tileset); void setTilesetPalette(Tileset *tileset, int paletteIndex, QList> colors); Q_INVOKABLE void setPrimaryTilesetPalette(int paletteIndex, QList> colors); diff --git a/include/ui/imageproviders.h b/include/ui/imageproviders.h index c90ce995..db04bdb2 100644 --- a/include/ui/imageproviders.h +++ b/include/ui/imageproviders.h @@ -9,6 +9,7 @@ QImage getCollisionMetatileImage(Block); QImage getCollisionMetatileImage(int, int); QImage getMetatileImage(uint16_t, Tileset*, Tileset*, QList, QList, bool useTruePalettes = false); +QImage getMetatileImage(Metatile*, Tileset*, Tileset*, QList, QList, bool useTruePalettes = false); QImage getTileImage(uint16_t, Tileset*, Tileset*); QImage getPalettedTileImage(uint16_t, Tileset*, Tileset*, int, bool useTruePalettes = false); QImage getGreyscaleTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset); diff --git a/include/ui/overlay.h b/include/ui/overlay.h index 68277b16..04ee7764 100644 --- a/include/ui/overlay.h +++ b/include/ui/overlay.h @@ -82,6 +82,7 @@ public: void addText(QString text, int x, int y, QString color = "#000000", int fontSize = 12); void addRect(int x, int y, int width, int height, QString color = "#000000", bool filled = false); bool addImage(int x, int y, QString filepath, int width = -1, int height = -1, unsigned offset = 0, bool hflip = false, bool vflip = false, bool setTransparency = false); + bool addImage(int x, int y, QImage image); private: QList items; bool hidden; diff --git a/src/mainwindow_scriptapi.cpp b/src/mainwindow_scriptapi.cpp index ef7a169c..933991d7 100644 --- a/src/mainwindow_scriptapi.cpp +++ b/src/mainwindow_scriptapi.cpp @@ -3,6 +3,7 @@ #include "scripting.h" #include "editcommands.h" #include "config.h" +#include "imageproviders.h" QJSValue MainWindow::getBlock(int x, int y) { if (!this->editor || !this->editor->map) @@ -291,6 +292,60 @@ void MainWindow::createImage(int x, int y, QString filepath, int width, int heig this->ui->graphicsView_Map->scene()->update(); } +void MainWindow::addTileImage(int x, int y, int tileId, bool xflip, bool yflip, int palette, int layer) { + if (!this->ui || !this->ui->graphicsView_Map || layer == INT_MAX + || !this->editor || !this->editor->map || !this->editor->map->layout + || !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary) + return; + QImage image = getPalettedTileImage(tileId, + this->editor->map->layout->tileset_primary, + this->editor->map->layout->tileset_secondary, + palette) + .mirrored(xflip, yflip); + if (this->ui->graphicsView_Map->getOverlay(layer)->addImage(x, y, image)) + this->ui->graphicsView_Map->scene()->update(); +} + +void MainWindow::addTilesImage(int x, int y, QJSValue tilesObj, int layer) { + if (!this->ui || !this->ui->graphicsView_Map || layer == INT_MAX + || !this->editor || !this->editor->map || !this->editor->map->layout + || !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary) + return; + + // Create metatile from JS tiles array + Metatile metatile; + int numTiles = this->getNumTilesInMetatile(); + int numTileObjs = qMin(tilesObj.property("length").toInt(), numTiles); + int i = 0; + for (; i < numTileObjs; i++) + metatile.tiles.append(Scripting::toTile(tilesObj.property(i))); + for (; i < numTiles; i++) + metatile.tiles.append(Tile()); + + // Create image from metatile + QImage image = getMetatileImage(&metatile, + this->editor->map->layout->tileset_primary, + this->editor->map->layout->tileset_secondary, + this->editor->map->metatileLayerOrder, + this->editor->map->metatileLayerOpacity); + if (this->ui->graphicsView_Map->getOverlay(layer)->addImage(x, y, image)) + this->ui->graphicsView_Map->scene()->update(); +} + +void MainWindow::addMetatileImage(int x, int y, int metatileId, int layer) { + if (!this->ui || !this->ui->graphicsView_Map || layer == INT_MAX + || !this->editor || !this->editor->map || !this->editor->map->layout + || !this->editor->map->layout->tileset_primary || !this->editor->map->layout->tileset_secondary) + return; + QImage image = getMetatileImage(static_cast(metatileId), + this->editor->map->layout->tileset_primary, + this->editor->map->layout->tileset_secondary, + this->editor->map->metatileLayerOrder, + this->editor->map->metatileLayerOpacity); + if (this->ui->graphicsView_Map->getOverlay(layer)->addImage(x, y, image)) + this->ui->graphicsView_Map->scene()->update(); +} + void MainWindow::refreshAfterPaletteChange(Tileset *tileset) { if (this->tilesetEditor) { this->tilesetEditor->updateTilesets(this->editor->map->layout->tileset_primary_label, this->editor->map->layout->tileset_secondary_label); diff --git a/src/ui/imageproviders.cpp b/src/ui/imageproviders.cpp index f5a4357a..9d714348 100644 --- a/src/ui/imageproviders.cpp +++ b/src/ui/imageproviders.cpp @@ -15,7 +15,25 @@ QImage getCollisionMetatileImage(int collision, int elevation) { } QImage getMetatileImage( - uint16_t tile, + uint16_t metatileId, + Tileset *primaryTileset, + Tileset *secondaryTileset, + QList layerOrder, + QList layerOpacity, + bool useTruePalettes) +{ + Metatile* metatile = Tileset::getMetatile(metatileId, primaryTileset, secondaryTileset); + Tileset* blockTileset = Tileset::getBlockTileset(metatileId, primaryTileset, secondaryTileset); + if (!metatile || !blockTileset) { + QImage metatile_image(16, 16, QImage::Format_RGBA8888); + metatile_image.fill(Qt::magenta); + return metatile_image; + } + return getMetatileImage(metatile, primaryTileset, secondaryTileset, layerOrder, layerOpacity, useTruePalettes); +} + +QImage getMetatileImage( + Metatile *metatile, Tileset *primaryTileset, Tileset *secondaryTileset, QList layerOrder, @@ -23,19 +41,12 @@ QImage getMetatileImage( bool useTruePalettes) { QImage metatile_image(16, 16, QImage::Format_RGBA8888); - metatile_image.fill(Qt::black); - - Metatile* metatile = Tileset::getMetatile(tile, primaryTileset, secondaryTileset); if (!metatile) { metatile_image.fill(Qt::magenta); return metatile_image; } + metatile_image.fill(Qt::black); - Tileset* blockTileset = Tileset::getBlockTileset(tile, primaryTileset, secondaryTileset); - if (!blockTileset) { - metatile_image.fill(Qt::magenta); - return metatile_image; - } QList> palettes = Tileset::getBlockPalettes(primaryTileset, secondaryTileset, useTruePalettes); QPainter metatile_painter(&metatile_image); @@ -46,8 +57,8 @@ QImage getMetatileImage( for (int x = 0; x < 2; x++) { int l = layerOrder.size() >= numLayers ? layerOrder[layer] : layer; int bottomLayer = layerOrder.size() >= numLayers ? layerOrder[0] : 0; - Tile tile_ = metatile->tiles.value((y * 2) + x + (l * 4)); - QImage tile_image = getTileImage(tile_.tileId, primaryTileset, secondaryTileset); + Tile tile = metatile->tiles.value((y * 2) + x + (l * 4)); + QImage tile_image = getTileImage(tile.tileId, primaryTileset, secondaryTileset); if (tile_image.isNull()) { // Some metatiles specify tiles that are outside the valid range. // These are treated as completely transparent, so they can be skipped without @@ -60,13 +71,13 @@ QImage getMetatileImage( } // Colorize the metatile tiles with its palette. - if (tile_.palette < palettes.length()) { - QList palette = palettes.value(tile_.palette); + if (tile.palette < palettes.length()) { + QList palette = palettes.value(tile.palette); for (int j = 0; j < palette.length(); j++) { tile_image.setColor(j, palette.value(j)); } } else { - logWarn(QString("Tile '%1' is referring to invalid palette number: '%2'").arg(tile_.tileId).arg(tile_.palette)); + logWarn(QString("Tile '%1' is referring to invalid palette number: '%2'").arg(tile.tileId).arg(tile.palette)); } QPoint origin = QPoint(x*8, y*8); @@ -87,24 +98,24 @@ QImage getMetatileImage( tile_image.setColor(0, color.rgba()); } - metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip, tile_.yflip)); + metatile_painter.drawImage(origin, tile_image.mirrored(tile.xflip, tile.yflip)); } metatile_painter.end(); return metatile_image; } -QImage getTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset) { - Tileset *tileset = Tileset::getBlockTileset(tile, primaryTileset, secondaryTileset); - int local_index = Metatile::getBlockIndex(tile); +QImage getTileImage(uint16_t tileId, Tileset *primaryTileset, Tileset *secondaryTileset) { + Tileset *tileset = Tileset::getBlockTileset(tileId, primaryTileset, secondaryTileset); + int local_index = Metatile::getBlockIndex(tileId); if (!tileset) { return QImage(); } return tileset->tiles.value(local_index, QImage()); } -QImage getColoredTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset, QList palette) { - QImage tileImage = getTileImage(tile, primaryTileset, secondaryTileset); +QImage getColoredTileImage(uint16_t tileId, Tileset *primaryTileset, Tileset *secondaryTileset, QList palette) { + QImage tileImage = getTileImage(tileId, primaryTileset, secondaryTileset); if (tileImage.isNull()) { tileImage = QImage(16, 16, QImage::Format_RGBA8888); QPainter painter(&tileImage); @@ -118,11 +129,11 @@ QImage getColoredTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *seco return tileImage; } -QImage getPalettedTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset, int paletteId, bool useTruePalettes) { +QImage getPalettedTileImage(uint16_t tileId, Tileset *primaryTileset, Tileset *secondaryTileset, int paletteId, bool useTruePalettes) { QList palette = Tileset::getPalette(paletteId, primaryTileset, secondaryTileset, useTruePalettes); - return getColoredTileImage(tile, primaryTileset, secondaryTileset, palette); + return getColoredTileImage(tileId, primaryTileset, secondaryTileset, palette); } -QImage getGreyscaleTileImage(uint16_t tile, Tileset *primaryTileset, Tileset *secondaryTileset) { - return getColoredTileImage(tile, primaryTileset, secondaryTileset, greyscalePalette); +QImage getGreyscaleTileImage(uint16_t tileId, Tileset *primaryTileset, Tileset *secondaryTileset) { + return getColoredTileImage(tileId, primaryTileset, secondaryTileset, greyscalePalette); } diff --git a/src/ui/overlay.cpp b/src/ui/overlay.cpp index 7c7aeab3..058624a8 100644 --- a/src/ui/overlay.cpp +++ b/src/ui/overlay.cpp @@ -89,3 +89,12 @@ bool Overlay::addImage(int x, int y, QString filepath, int width, int height, un this->items.append(new OverlayImage(x, y, image)); return true; } + +bool Overlay::addImage(int x, int y, QImage image) { + if (image.isNull()) { + logError(QString("Failed to load custom image")); + return false; + } + this->items.append(new OverlayImage(x, y, image)); + return true; +}