Allow rendering individual metatile layers

This commit is contained in:
GriffinR
2025-07-01 17:53:07 -04:00
parent 17e4cbfa30
commit b2798e77d4
24 changed files with 272 additions and 147 deletions

View File

@@ -4,6 +4,7 @@
#include "editcommands.h"
#include "config.h"
#include "imageproviders.h"
#include "scriptutility.h"
// TODO: "tilesetNeedsRedraw" is used when redrawing the map after
// changing a metatile's tiles via script. It is unnecessarily
@@ -26,7 +27,7 @@ void MainWindow::tryRedrawMapArea(bool forceRedraw) {
if (this->tilesetEditor)
this->tilesetEditor->updateTilesets(this->editor->layout->tileset_primary_label, this->editor->layout->tileset_secondary_label);
if (this->editor->metatile_selector_item)
this->editor->metatile_selector_item->draw();
this->editor->metatile_selector_item->refresh();
if (this->editor->selected_border_metatiles_item)
this->editor->selected_border_metatiles_item->draw();
if (this->editor->current_metatile_selection_item)
@@ -332,7 +333,7 @@ void MainWindow::refreshAfterPaletteChange(Tileset *tileset) {
if (this->tilesetEditor) {
this->tilesetEditor->updateTilesets(this->editor->layout->tileset_primary_label, this->editor->layout->tileset_secondary_label);
}
this->editor->metatile_selector_item->draw();
this->editor->metatile_selector_item->refresh();
this->editor->selected_border_metatiles_item->draw();
this->editor->map_item->draw(true);
this->editor->updateMapBorder();
@@ -444,7 +445,7 @@ QJSValue MainWindow::getSecondaryTilesetPalettes() {
}
void MainWindow::refreshAfterPalettePreviewChange() {
this->editor->metatile_selector_item->draw();
this->editor->metatile_selector_item->refresh();
this->editor->selected_border_metatiles_item->draw();
this->editor->map_item->draw(true);
this->editor->updateMapBorder();
@@ -807,6 +808,32 @@ QJSValue MainWindow::getTilePixels(int tileId) {
return pixelArray;
}
QList<int> MainWindow::getMetatileLayerOrder() const {
if (!this->editor || !this->editor->layout)
return QList<int>();
return this->editor->layout->metatileLayerOrder();
}
void MainWindow::setMetatileLayerOrder(const QList<int> &order) {
if (!this->editor || !this->editor->layout || !ScriptUtility::validateMetatileLayerOrder(order))
return;
this->editor->layout->setMetatileLayerOrder(order);
this->refreshAfterPalettePreviewChange();
}
QList<float> MainWindow::getMetatileLayerOpacity() const {
if (!this->editor || !this->editor->layout)
return QList<float>();
return this->editor->layout->metatileLayerOpacity();
}
void MainWindow::setMetatileLayerOpacity(const QList<float> &opacities) {
if (!this->editor || !this->editor->layout)
return;
this->editor->layout->setMetatileLayerOpacity(opacities);
this->refreshAfterPalettePreviewChange();
}
//=====================
// Editing map header
//=====================

View File

@@ -294,11 +294,7 @@ void MapView::addTileImage(int x, int y, const Tile &tile, bool setTransparency,
void MapView::addMetatileImage(int x, int y, int metatileId, bool setTransparency, int layer) {
if (!this->editor || !this->editor->layout || !this->editor->layout->tileset_primary || !this->editor->layout->tileset_secondary)
return;
QImage image = getMetatileImage(static_cast<uint16_t>(metatileId),
this->editor->layout->tileset_primary,
this->editor->layout->tileset_secondary,
this->editor->layout->metatileLayerOrder,
this->editor->layout->metatileLayerOpacity);
QImage image = getMetatileImage(static_cast<uint16_t>(metatileId), this->editor->layout);
if (setTransparency)
image.setColor(0, qRgba(0, 0, 0, 0));
if (this->getOverlay(layer)->addImage(x, y, image))

View File

@@ -201,46 +201,36 @@ QList<QString> ScriptUtility::getCustomScripts() {
}
QList<int> ScriptUtility::getMetatileLayerOrder() {
if (!window || !window->editor || !window->editor->layout)
return QList<int>();
return window->editor->layout->metatileLayerOrder;
return Layout::defaultMetatileLayerOrder();
}
void ScriptUtility::setMetatileLayerOrder(QList<int> order) {
if (!window || !window->editor || !window->editor->layout)
return;
bool ScriptUtility::validateMetatileLayerOrder(const QList<int> &order) {
const int numLayers = 3;
int size = order.size();
if (size < numLayers) {
logError(QString("Metatile layer order has insufficient elements (%1), needs at least %2.").arg(size).arg(numLayers));
return;
}
bool invalid = false;
for (int i = 0; i < numLayers; i++) {
bool valid = true;
for (int i = 0; i < qMin(order.length(), numLayers); i++) {
int layer = order.at(i);
if (layer < 0 || layer >= numLayers) {
logError(QString("'%1' is not a valid metatile layer order value, must be in range 0-%2.").arg(layer).arg(numLayers - 1));
invalid = true;
valid = false;
}
}
if (invalid) return;
return valid;
}
window->editor->layout->metatileLayerOrder = order;
window->refreshAfterPalettePreviewChange();
void ScriptUtility::setMetatileLayerOrder(const QList<int> &order) {
if (!validateMetatileLayerOrder(order))
return;
Layout::setDefaultMetatileLayerOrder(order);
if (window) window->refreshAfterPalettePreviewChange();
}
QList<float> ScriptUtility::getMetatileLayerOpacity() {
if (!window || !window->editor || !window->editor->layout)
return QList<float>();
return window->editor->layout->metatileLayerOpacity;
return Layout::defaultMetatileLayerOpacity();
}
void ScriptUtility::setMetatileLayerOpacity(QList<float> order) {
if (!window || !window->editor || !window->editor->layout)
return;
window->editor->layout->metatileLayerOpacity = order;
window->refreshAfterPalettePreviewChange();
void ScriptUtility::setMetatileLayerOpacity(const QList<float> &opacities) {
Layout::setDefaultMetatileLayerOpacity(opacities);
if (window) window->refreshAfterPalettePreviewChange();
}
QList<QString> ScriptUtility::getMapNames() {

View File

@@ -16,7 +16,7 @@ const QMap<CallbackType, QString> callbackFunctions = {
{OnMapResized, "onMapResized"},
{OnBorderResized, "onBorderResized"},
{OnMapShifted, "onMapShifted"},
{OnTilesetUpdated, "onTilesetUpdated"},
{OnTilesetsChanged, "onTilesetsChanged"},
{OnMainTabChanged, "onMainTabChanged"},
{OnMapViewTabChanged, "onMapViewTabChanged"},
{OnBorderVisibilityToggled, "onBorderVisibilityToggled"},
@@ -301,13 +301,14 @@ void Scripting::cb_MapShifted(int xDelta, int yDelta) {
instance->invokeCallback(OnMapShifted, args);
}
void Scripting::cb_TilesetUpdated(QString tilesetName) {
void Scripting::cb_TilesetsChanged(const QString &primaryTilesetName, const QString &secondaryTilesetName) {
if (!instance) return;
QJSValueList args {
tilesetName,
primaryTilesetName,
secondaryTilesetName
};
instance->invokeCallback(OnTilesetUpdated, args);
instance->invokeCallback(OnTilesetsChanged, args);
}
void Scripting::cb_MainTabChanged(int oldTab, int newTab) {