mirror of
https://github.com/huderlem/porymap.git
synced 2026-09-12 10:55:38 -05:00
Fix ranges for metatile sheet images
This commit is contained in:
@@ -10,15 +10,35 @@ class Layout;
|
||||
|
||||
QImage getCollisionMetatileImage(Block);
|
||||
QImage getCollisionMetatileImage(int, int);
|
||||
|
||||
QImage getMetatileImage(uint16_t, Layout*, bool useTruePalettes = false);
|
||||
QImage getMetatileImage(Metatile*, Layout*, bool useTruePalettes = false);
|
||||
QImage getMetatileImage(uint16_t, Tileset*, Tileset*, const QList<int>&, const QList<float>& = {}, bool useTruePalettes = false);
|
||||
QImage getMetatileImage(Metatile*, Tileset*, Tileset*, const QList<int>&, const QList<float>& = {}, bool useTruePalettes = false);
|
||||
QImage getMetatileSheetImage(Layout *, int, bool useTruePalettes = false);
|
||||
QImage getMetatileSheetImage(Tileset *, Tileset *, uint16_t, int, int, const QList<int> &, const QList<float> & = {}, const QSize &size = Metatile::pixelSize(), bool useTruePalettes = false);
|
||||
|
||||
QImage getMetatileSheetImage(Layout *layout, int numMetatilesWIde, bool useTruePalettes = false);
|
||||
QImage getMetatileSheetImage(Tileset *primaryTileset,
|
||||
Tileset *secondaryTileset,
|
||||
uint16_t metatileIdStart,
|
||||
uint16_t metatileIdEnd,
|
||||
int numMetatilesWIde,
|
||||
const QList<int> &layerOrder,
|
||||
const QList<float> &layerOpacity = {},
|
||||
const QSize &metatileSize = Metatile::pixelSize(),
|
||||
bool useTruePalettes = false);
|
||||
QImage getMetatileSheetImage(Tileset *primaryTileset,
|
||||
Tileset *secondaryTileset,
|
||||
int numMetatilesWide,
|
||||
const QList<int> &layerOrder,
|
||||
const QList<float> &layerOpacity = {},
|
||||
const QSize &metatileSize = Metatile::pixelSize(),
|
||||
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);
|
||||
|
||||
void flattenTo4bppImage(QImage * image);
|
||||
|
||||
static QList<QRgb> greyscalePalette({
|
||||
|
||||
@@ -48,6 +48,12 @@ QImage getMetatileImage(
|
||||
useTruePalettes);
|
||||
}
|
||||
|
||||
// The color to use when we want to show some portion of the image request was invalid.
|
||||
// Normally this is Qt::magenta, but we'll use Qt::transparent if we think the image allows it.
|
||||
QColor getInvalidImageColor() {
|
||||
return (projectConfig.transparencyColor == QColor(Qt::transparent)) ? QColor(Qt::transparent) : QColor(Qt::magenta);
|
||||
}
|
||||
|
||||
QImage getMetatileImage(
|
||||
Metatile *metatile,
|
||||
Tileset *primaryTileset,
|
||||
@@ -58,7 +64,7 @@ QImage getMetatileImage(
|
||||
{
|
||||
QImage metatile_image(Metatile::pixelWidth(), Metatile::pixelHeight(), QImage::Format_RGBA8888);
|
||||
if (!metatile) {
|
||||
metatile_image.fill(projectConfig.transparencyColor == QColor(Qt::transparent) ? projectConfig.transparencyColor : QColor(Qt::magenta));
|
||||
metatile_image.fill(getInvalidImageColor());
|
||||
return metatile_image;
|
||||
}
|
||||
|
||||
@@ -192,56 +198,93 @@ void flattenTo4bppImage(QImage * image) {
|
||||
*pixel %= 16;
|
||||
}
|
||||
|
||||
QImage getMetatileSheetImage(Layout *layout, int numMetatilesWide, bool useTruePalettes) {
|
||||
return getMetatileSheetImage(layout->tileset_primary,
|
||||
layout->tileset_secondary,
|
||||
0,
|
||||
-1,
|
||||
numMetatilesWide,
|
||||
layout->metatileLayerOrder(),
|
||||
layout->metatileLayerOpacity(),
|
||||
Metatile::pixelSize(),
|
||||
useTruePalettes);
|
||||
}
|
||||
|
||||
// Constructs a grid image of the metatiles in the specified ID range.
|
||||
QImage getMetatileSheetImage(Tileset *primaryTileset,
|
||||
Tileset *secondaryTileset,
|
||||
uint16_t metatileIdStart,
|
||||
int numMetatilesToDraw,
|
||||
uint16_t metatileIdEnd,
|
||||
int numMetatilesWide,
|
||||
const QList<int> &layerOrder,
|
||||
const QList<float> &layerOpacity,
|
||||
const QSize &metatileSize,
|
||||
bool useTruePalettes)
|
||||
{
|
||||
// We round up the number of primary metatiles to keep the tilesets on separate rows.
|
||||
int numPrimary = Util::roundUpToMultiple(primaryTileset ? primaryTileset->numMetatiles() : 0, numMetatilesWide);
|
||||
int maxPrimary = Project::getNumMetatilesPrimary();
|
||||
bool includesPrimary = metatileIdStart < maxPrimary;
|
||||
if (metatileIdEnd < metatileIdStart || numMetatilesWide == 0)
|
||||
return QImage();
|
||||
|
||||
// Negative values are used to indicate 'draw all metatiles'
|
||||
if (numMetatilesToDraw < 0) {
|
||||
numMetatilesToDraw = numPrimary + (secondaryTileset ? secondaryTileset->numMetatiles() : 0) - metatileIdStart;
|
||||
}
|
||||
int numMetatilesToDraw = metatileIdEnd - metatileIdStart + 1;
|
||||
|
||||
// Round up height for incomplete last row
|
||||
int numMetatilesTall = ceil((double)numMetatilesToDraw / numMetatilesWide);
|
||||
// Round up image height for incomplete last row.
|
||||
int numMetatilesTall = Util::roundUpToMultiple(numMetatilesToDraw, numMetatilesWide) / numMetatilesWide;
|
||||
|
||||
QImage image(numMetatilesWide * metatileSize.width(), numMetatilesTall * metatileSize.height(), QImage::Format_RGBA8888);
|
||||
image.fill(projectConfig.transparencyColor == QColor(Qt::transparent) ? projectConfig.transparencyColor : QColor(Qt::magenta));
|
||||
image.fill(getInvalidImageColor());
|
||||
|
||||
QPainter painter(&image);
|
||||
for (int i = 0; i < numMetatilesToDraw; i++) {
|
||||
uint16_t metatileId = i + metatileIdStart;
|
||||
if (includesPrimary && metatileId >= numPrimary)
|
||||
metatileId += maxPrimary - numPrimary; // Skip over unused region of primary tileset
|
||||
QImage metatile_image = getMetatileImage(metatileId, primaryTileset, secondaryTileset, layerOrder, layerOpacity, useTruePalettes)
|
||||
.scaled(metatileSize.width(), metatileSize.height());
|
||||
int map_y = i / numMetatilesWide;
|
||||
int map_x = i % numMetatilesWide;
|
||||
QPoint metatile_origin = QPoint(map_x * metatileSize.width(), map_y * metatileSize.height());
|
||||
painter.drawImage(metatile_origin, metatile_image);
|
||||
QImage metatileImage = getMetatileImage(metatileId, primaryTileset, secondaryTileset, layerOrder, layerOpacity, useTruePalettes)
|
||||
.scaled(metatileSize);
|
||||
|
||||
int x = (i % numMetatilesWide) * metatileSize.width();
|
||||
int y = (i / numMetatilesWide) * metatileSize.height();
|
||||
painter.drawImage(x, y, metatileImage);
|
||||
}
|
||||
painter.end();
|
||||
return image;
|
||||
}
|
||||
|
||||
// Constructs a grid image of the metatiles in the primary and secondary tileset,
|
||||
// rounding as necessary to keep the two tilesets on separate rows.
|
||||
// The unused metatiles (if any) between the primary and secondary tilesets are skipped.
|
||||
QImage getMetatileSheetImage(Tileset *primaryTileset,
|
||||
Tileset *secondaryTileset,
|
||||
int numMetatilesWide,
|
||||
const QList<int> &layerOrder,
|
||||
const QList<float> &layerOpacity,
|
||||
const QSize &metatileSize,
|
||||
bool useTruePalettes)
|
||||
{
|
||||
QImage primaryImage = getMetatileSheetImage(primaryTileset,
|
||||
secondaryTileset,
|
||||
0,
|
||||
primaryTileset ? primaryTileset->numMetatiles()-1 : 0,
|
||||
numMetatilesWide,
|
||||
layerOrder,
|
||||
layerOpacity,
|
||||
metatileSize,
|
||||
useTruePalettes);
|
||||
|
||||
uint16_t secondaryMetatileIdStart = Project::getNumMetatilesPrimary();
|
||||
QImage secondaryImage = getMetatileSheetImage(primaryTileset,
|
||||
secondaryTileset,
|
||||
secondaryMetatileIdStart,
|
||||
secondaryMetatileIdStart + (secondaryTileset ? secondaryTileset->numMetatiles()-1 : 0),
|
||||
numMetatilesWide,
|
||||
layerOrder,
|
||||
layerOpacity,
|
||||
metatileSize,
|
||||
useTruePalettes);
|
||||
|
||||
QImage image(qMax(primaryImage.width(), secondaryImage.width()), primaryImage.height() + secondaryImage.height(), QImage::Format_RGBA8888);
|
||||
image.fill(getInvalidImageColor());
|
||||
|
||||
QPainter painter(&image);
|
||||
painter.drawImage(0, 0, primaryImage);
|
||||
painter.drawImage(0, primaryImage.height(), secondaryImage);
|
||||
painter.end();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
QImage getMetatileSheetImage(Layout *layout, int numMetatilesWide, bool useTruePalettes) {
|
||||
if (!layout)
|
||||
return QImage();
|
||||
return getMetatileSheetImage(layout->tileset_primary,
|
||||
layout->tileset_secondary,
|
||||
numMetatilesWide,
|
||||
layout->metatileLayerOrder(),
|
||||
layout->metatileLayerOpacity(),
|
||||
Metatile::pixelSize(),
|
||||
useTruePalettes);
|
||||
}
|
||||
|
||||
@@ -211,10 +211,6 @@ void MetatileImageExporter::tryUpdatePreview() {
|
||||
void MetatileImageExporter::updatePreview() {
|
||||
copyRenderSettings();
|
||||
|
||||
int numMetatilesWide = ui->spinBox_WidthMetatiles->value();
|
||||
int metatileStart = ui->spinBox_MetatileStart->value();
|
||||
int numMetatiles = Util::roundUpToMultiple(ui->spinBox_MetatileEnd->value() - metatileStart + 1, numMetatilesWide);
|
||||
|
||||
m_layerOrder.clear();
|
||||
for (int i = 0; i < ui->listWidget_Layers->count(); i++) {
|
||||
auto item = ui->listWidget_Layers->item(i);
|
||||
@@ -224,12 +220,22 @@ void MetatileImageExporter::updatePreview() {
|
||||
}
|
||||
}
|
||||
|
||||
QImage previewImage = getMetatileSheetImage(m_primaryTileset,
|
||||
m_secondaryTileset,
|
||||
metatileStart,
|
||||
numMetatiles,
|
||||
numMetatilesWide,
|
||||
m_layerOrder);
|
||||
QImage previewImage;
|
||||
if (ui->checkBox_PrimaryTileset->isChecked() && ui->checkBox_SecondaryTileset->isChecked()) {
|
||||
// Special behavior to combine the two tilesets while skipping the unused region between tilesets.
|
||||
previewImage = getMetatileSheetImage(m_primaryTileset,
|
||||
m_secondaryTileset,
|
||||
ui->spinBox_WidthMetatiles->value(),
|
||||
m_layerOrder);
|
||||
} else {
|
||||
previewImage = getMetatileSheetImage(m_primaryTileset,
|
||||
m_secondaryTileset,
|
||||
ui->spinBox_MetatileStart->value(),
|
||||
ui->spinBox_MetatileEnd->value(),
|
||||
ui->spinBox_WidthMetatiles->value(),
|
||||
m_layerOrder);
|
||||
}
|
||||
|
||||
m_preview->setPixmap(QPixmap::fromImage(previewImage));
|
||||
m_scene->setSceneRect(m_scene->itemsBoundingRect());
|
||||
m_previewUpdateQueued = false;
|
||||
@@ -255,7 +261,6 @@ uint16_t MetatileImageExporter::getExpectedMetatileStart() {
|
||||
return ui->spinBox_MetatileStart->value();
|
||||
}
|
||||
|
||||
// TODO: Combining tilesets is not rendering the correct range of metatiles
|
||||
uint16_t MetatileImageExporter::getExpectedMetatileEnd() {
|
||||
if (ui->checkBox_SecondaryTileset->isChecked()) return Project::getNumMetatilesPrimary() + (m_secondaryTileset ? (m_secondaryTileset->numMetatiles() - 1) : 0);
|
||||
if (ui->checkBox_PrimaryTileset->isChecked()) return m_primaryTileset ? (m_primaryTileset->numMetatiles() - 1) : 0;
|
||||
|
||||
@@ -57,8 +57,6 @@ void TilesetEditorMetatileSelector::drawSelectedMetatile() {
|
||||
void TilesetEditorMetatileSelector::updateBasePixmap() {
|
||||
this->baseImage = getMetatileSheetImage(this->primaryTileset,
|
||||
this->secondaryTileset,
|
||||
0,
|
||||
this->numPrimaryMetatilesRounded() + this->secondaryTileset->numMetatiles(),
|
||||
this->numMetatilesWide,
|
||||
this->layout->metatileLayerOrder(),
|
||||
this->layout->metatileLayerOpacity(),
|
||||
|
||||
Reference in New Issue
Block a user