Add tile/metatile to image functions to API, more tile->tileId/metatileId

This commit is contained in:
GriffinR 2021-12-01 16:06:14 -05:00 committed by huderlem
parent 6a5e4fe247
commit b5bdac8d36
6 changed files with 104 additions and 24 deletions

View file

@ -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<QList<int>> colors);
Q_INVOKABLE void setPrimaryTilesetPalette(int paletteIndex, QList<QList<int>> colors);

View file

@ -9,6 +9,7 @@
QImage getCollisionMetatileImage(Block);
QImage getCollisionMetatileImage(int, int);
QImage getMetatileImage(uint16_t, Tileset*, Tileset*, QList<int>, QList<float>, bool useTruePalettes = false);
QImage getMetatileImage(Metatile*, Tileset*, Tileset*, QList<int>, QList<float>, 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);

View file

@ -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<OverlayItem*> items;
bool hidden;

View file

@ -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<uint16_t>(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);

View file

@ -15,7 +15,25 @@ QImage getCollisionMetatileImage(int collision, int elevation) {
}
QImage getMetatileImage(
uint16_t tile,
uint16_t metatileId,
Tileset *primaryTileset,
Tileset *secondaryTileset,
QList<int> layerOrder,
QList<float> 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<int> 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<QList<QRgb>> 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<QRgb> palette = palettes.value(tile_.palette);
if (tile.palette < palettes.length()) {
QList<QRgb> 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<QRgb> palette) {
QImage tileImage = getTileImage(tile, primaryTileset, secondaryTileset);
QImage getColoredTileImage(uint16_t tileId, Tileset *primaryTileset, Tileset *secondaryTileset, QList<QRgb> 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<QRgb> 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);
}

View file

@ -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;
}