diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui
index c431d469..602ff620 100644
--- a/forms/mainwindow.ui
+++ b/forms/mainwindow.ui
@@ -2928,6 +2928,7 @@
+
diff --git a/forms/newtilesetdialog.ui b/forms/newtilesetdialog.ui
index c582eba0..1fed2558 100644
--- a/forms/newtilesetdialog.ui
+++ b/forms/newtilesetdialog.ui
@@ -6,238 +6,152 @@
0
0
- 400
- 216
+ 450
+ 209
-
-
- 0
- 0
-
-
Add new Tileset
-
-
-
- 0
- 0
- 400
- 216
-
-
-
-
- 0
- 0
-
-
-
-
- 10
-
-
- 10
-
-
- 10
-
-
- 10
-
-
- 6
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 380
- 161
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
- 0
- 0
- 380
- 155
-
-
-
-
- 6
+
+
-
+
+
+ QFrame::Shape::StyledPanel
+
+
+ QFrame::Shadow::Raised
+
+
+
-
+
+
+ Name
-
- 10
+
+
+ -
+
+
+ true
-
- 10
+
+
+ -
+
+
+ false
-
- 10
+
+ color: rgb(255, 0, 0)
-
-
-
-
- Name
-
-
+
+
+
+
+
+ -
+
+
+ Symbol Name
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Type
+
+
+
+ -
+
+
+ false
+
+
-
+
+ Primary
+
- -
-
-
- true
-
-
+
-
+
+ Secondary
+
- -
-
-
- Type
-
-
-
- -
-
-
-
-
- Primary
-
-
- -
-
- Secondary
-
-
-
-
- -
-
-
- Path
-
-
-
- -
-
-
- false
-
-
- true
-
-
-
- -
-
-
- Symbol Name
-
-
-
- -
-
-
- false
-
-
- true
-
-
-
- -
-
-
- Checkerboard Fill
-
-
-
- -
-
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
- false
-
-
-
-
-
+
+
+ -
+
+
+ Checkerboard Fill
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 1
+
+
+
+
+
+
+
+ -
+
+
+ false
+
+
+ color: rgb(255, 0, 0)
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Orientation::Horizontal
+
+
+ QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok
+
+
+ false
+
+
+
+
+
+
+ NoScrollComboBox
+ QComboBox
+
+
+
-
-
- buttonBox
- accepted()
- NewTilesetDialog
- accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
-
-
- buttonBox
- rejected()
- NewTilesetDialog
- reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
-
-
+
diff --git a/include/core/tileset.h b/include/core/tileset.h
index bb7631d7..999e731d 100644
--- a/include/core/tileset.h
+++ b/include/core/tileset.h
@@ -38,8 +38,6 @@ public:
QList> palettes;
QList> palettePreviews;
- bool hasUnsavedTilesImage;
-
static Tileset* getMetatileTileset(int, Tileset*, Tileset*);
static Tileset* getTileTileset(int, Tileset*, Tileset*);
static Metatile* getMetatile(int, Tileset*, Tileset*);
@@ -56,10 +54,25 @@ public:
static QHash getHeaderMemberMap(bool usingAsm);
static QString getExpectedDir(QString tilesetName, bool isSecondary);
QString getExpectedDir();
+
+ void load();
+ void loadMetatiles();
+ void loadMetatileAttributes();
+ void loadTilesImage(QImage *importedImage = nullptr);
+ void loadPalettes();
+
+ void save();
+ void saveMetatileAttributes();
+ void saveMetatiles();
+ void saveTilesImage();
+ void savePalettes();
+
bool appendToHeaders(QString root, QString friendlyName, bool usingAsm);
bool appendToGraphics(QString root, QString friendlyName, bool usingAsm);
bool appendToMetatiles(QString root, QString friendlyName, bool usingAsm);
+ void setTilesImage(const QImage &image);
+
void setMetatiles(const QList &metatiles);
void addMetatile(Metatile* metatile);
@@ -72,6 +85,7 @@ public:
private:
QList m_metatiles;
+ bool m_hasUnsavedTilesImage = false;
};
#endif // TILESET_H
diff --git a/include/mainwindow.h b/include/mainwindow.h
index 22f64a81..c51b10cf 100644
--- a/include/mainwindow.h
+++ b/include/mainwindow.h
@@ -22,7 +22,6 @@
#include "mapimageexporter.h"
#include "filterchildrenproxymodel.h"
#include "maplistmodels.h"
-#include "newtilesetdialog.h"
#include "shortcutseditor.h"
#include "preferenceeditor.h"
#include "projectsettingseditor.h"
@@ -191,6 +190,7 @@ private slots:
void onNewMapGroupCreated(const QString &groupName);
void onNewMapSectionCreated(const QString &idName);
void onNewLayoutCreated(Layout *layout);
+ void onNewTilesetCreated(Tileset *tileset);
void onMapLoaded(Map *map);
void onMapRulerStatusChanged(const QString &);
void applyUserShortcuts();
@@ -412,7 +412,6 @@ private:
QObjectList shortcutableObjects() const;
void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false);
- int insertTilesetLabel(QStringList * list, QString label);
void checkForUpdates(bool requestedByUser);
void setDivingMapsVisible(bool visible);
diff --git a/include/project.h b/include/project.h
index 2b84d8d4..8a08cef6 100644
--- a/include/project.h
+++ b/include/project.h
@@ -139,6 +139,7 @@ public:
Map *createNewMap(const Project::NewMapSettings &mapSettings, const Map* toDuplicate = nullptr);
Layout *createNewLayout(const Layout::Settings &layoutSettings, const Layout* toDuplicate = nullptr);
+ Tileset *createNewTileset(const QString &friendlyName, bool secondary, bool checkerboardFill);
bool isIdentifierUnique(const QString &identifier) const;
QString getProjectTitle();
@@ -167,10 +168,7 @@ public:
bool loadMapLayout(Map*);
bool loadLayoutTilesets(Layout *);
void loadTilesetAssets(Tileset*);
- void loadTilesetTiles(Tileset*, QImage);
- void loadTilesetMetatiles(Tileset*);
void loadTilesetMetatileLabels(Tileset*);
- void loadTilesetPalettes(Tileset*);
void readTilesetPaths(Tileset* tileset);
void saveLayout(Layout *);
@@ -188,10 +186,6 @@ public:
void saveHealLocations(Map*);
void saveTilesets(Tileset*, Tileset*);
void saveTilesetMetatileLabels(Tileset*, Tileset*);
- void saveTilesetMetatileAttributes(Tileset*);
- void saveTilesetMetatiles(Tileset*);
- void saveTilesetTilesImage(Tileset*);
- void saveTilesetPalettes(Tileset*);
void appendTilesetLabel(const QString &label, const QString &isSecondaryStr);
bool readTilesetLabels();
bool readTilesetMetatileLabels();
@@ -282,6 +276,7 @@ signals:
void mapLoaded(Map *map);
void mapCreated(Map *newMap, const QString &groupName);
void layoutCreated(Layout *newLayout);
+ void tilesetCreated(Tileset *newTileset);
void mapGroupAdded(const QString &groupName);
void mapSectionAdded(const QString &idName);
void mapSectionIdNamesChanged(const QStringList &idNames);
diff --git a/include/ui/newlayoutdialog.h b/include/ui/newlayoutdialog.h
index 5fdb780f..b1a2c47b 100644
--- a/include/ui/newlayoutdialog.h
+++ b/include/ui/newlayoutdialog.h
@@ -39,7 +39,6 @@ private:
void refresh();
void saveSettings();
- bool isExistingLayout() const;
private slots:
void dialogButtonClicked(QAbstractButton *button);
diff --git a/include/ui/newtilesetdialog.h b/include/ui/newtilesetdialog.h
index c2563f21..06012708 100644
--- a/include/ui/newtilesetdialog.h
+++ b/include/ui/newtilesetdialog.h
@@ -2,7 +2,10 @@
#define NEWTILESETDIALOG_H
#include
-#include "project.h"
+#include
+
+class Project;
+class Tileset;
namespace Ui {
class NewTilesetDialog;
@@ -15,20 +18,17 @@ class NewTilesetDialog : public QDialog
public:
explicit NewTilesetDialog(Project *project, QWidget *parent = nullptr);
~NewTilesetDialog();
- QString path;
- QString fullSymbolName;
- QString friendlyName;
- bool isSecondary;
- bool checkerboardFill;
-private slots:
- void NameOrSecondaryChanged();
- void SecondaryChanged();
- void FillChanged();
+ virtual void accept() override;
private:
Ui::NewTilesetDialog *ui;
Project *project = nullptr;
+ const QString symbolPrefix;
+
+ bool validateName(bool allowEmpty = false);
+ void onFriendlyNameChanged(const QString &friendlyName);
+ void dialogButtonClicked(QAbstractButton *button);
};
#endif // NEWTILESETDIALOG_H
diff --git a/src/core/tileset.cpp b/src/core/tileset.cpp
index be3a04d4..cf21a675 100644
--- a/src/core/tileset.cpp
+++ b/src/core/tileset.cpp
@@ -3,6 +3,7 @@
#include "project.h"
#include "log.h"
#include "config.h"
+#include "imageproviders.h"
#include
#include
@@ -23,7 +24,7 @@ Tileset::Tileset(const Tileset &other)
metatileLabels(other.metatileLabels),
palettes(other.palettes),
palettePreviews(other.palettePreviews),
- hasUnsavedTilesImage(false)
+ m_hasUnsavedTilesImage(other.m_hasUnsavedTilesImage)
{
for (auto tile : other.tiles) {
tiles.append(tile.copy());
@@ -397,3 +398,184 @@ QHash Tileset::getHeaderMemberMap(bool usingAsm)
map.insert(metatileAttrPosition, "metatileAttributes");
return map;
}
+
+void Tileset::loadMetatiles() {
+ clearMetatiles();
+
+ QFile metatiles_file(this->metatiles_path);
+ if (!metatiles_file.open(QIODevice::ReadOnly)) {
+ logError(QString("Could not open '%1' for reading.").arg(this->metatiles_path));
+ return;
+ }
+
+ QByteArray data = metatiles_file.readAll();
+ int tilesPerMetatile = projectConfig.getNumTilesInMetatile();
+ int bytesPerMetatile = 2 * tilesPerMetatile;
+ int num_metatiles = data.length() / bytesPerMetatile;
+ for (int i = 0; i < num_metatiles; i++) {
+ auto metatile = new Metatile;
+ int index = i * bytesPerMetatile;
+ for (int j = 0; j < tilesPerMetatile; j++) {
+ uint16_t tileRaw = static_cast(data[index++]);
+ tileRaw |= static_cast(data[index++]) << 8;
+ metatile->tiles.append(Tile(tileRaw));
+ }
+ m_metatiles.append(metatile);
+ }
+}
+
+void Tileset::saveMetatiles() {
+ QFile metatiles_file(this->metatiles_path);
+ if (!metatiles_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ logError(QString("Could not open '%1' for writing.").arg(this->metatiles_path));
+ return;
+ }
+
+ QByteArray data;
+ int numTiles = projectConfig.getNumTilesInMetatile();
+ for (const auto &metatile : m_metatiles) {
+ for (int i = 0; i < numTiles; i++) {
+ uint16_t tile = metatile->tiles.at(i).rawValue();
+ data.append(static_cast(tile));
+ data.append(static_cast(tile >> 8));
+ }
+ }
+ metatiles_file.write(data);
+}
+
+void Tileset::loadMetatileAttributes() {
+ QFile attrs_file(this->metatile_attrs_path);
+ if (!attrs_file.open(QIODevice::ReadOnly)) {
+ logError(QString("Could not open '%1' for reading.").arg(this->metatile_attrs_path));
+ return;
+ }
+
+ QByteArray data = attrs_file.readAll();
+ int attrSize = projectConfig.metatileAttributesSize;
+ int numMetatiles = m_metatiles.length();
+ int numMetatileAttrs = data.length() / attrSize;
+ if (numMetatiles != numMetatileAttrs) {
+ logWarn(QString("Metatile count %1 does not match metatile attribute count %2 in %3").arg(numMetatiles).arg(numMetatileAttrs).arg(this->name));
+ }
+
+ for (int i = 0; i < qMin(numMetatiles, numMetatileAttrs); i++) {
+ uint32_t attributes = 0;
+ for (int j = 0; j < attrSize; j++)
+ attributes |= static_cast(data.at(i * attrSize + j)) << (8 * j);
+ m_metatiles.at(i)->setAttributes(attributes);
+ }
+}
+
+void Tileset::saveMetatileAttributes() {
+ QFile attrs_file(this->metatile_attrs_path);
+ if (!attrs_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ logError(QString("Could not open '%1' for writing.").arg(this->metatile_attrs_path));
+ return;
+ }
+
+ QByteArray data;
+ for (const auto &metatile : m_metatiles) {
+ uint32_t attributes = metatile->getAttributes();
+ for (int i = 0; i < projectConfig.metatileAttributesSize; i++)
+ data.append(static_cast(attributes >> (8 * i)));
+ }
+ attrs_file.write(data);
+}
+
+void Tileset::loadTilesImage(QImage *importedImage) {
+ QImage image;
+ if (importedImage) {
+ image = *importedImage;
+ m_hasUnsavedTilesImage = true;
+ } else if (QFile::exists(this->tilesImagePath)) {
+ // No image provided, load from file path.
+ image = QImage(this->tilesImagePath).convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither);
+ } else {
+ // Use default image
+ image = QImage(8, 8, QImage::Format_Indexed8);
+ }
+
+ // Validate image contains 16 colors.
+ int colorCount = image.colorCount();
+ if (colorCount > 16) {
+ flattenTo4bppImage(&image);
+ } else if (colorCount < 16) {
+ QVector colorTable = image.colorTable();
+ for (int i = colorTable.length(); i < 16; i++) {
+ colorTable.append(Qt::black);
+ }
+ image.setColorTable(colorTable);
+ }
+
+ QList tiles;
+ int w = 8;
+ int h = 8;
+ for (int y = 0; y < image.height(); y += h)
+ for (int x = 0; x < image.width(); x += w) {
+ QImage tile = image.copy(x, y, w, h);
+ tiles.append(tile);
+ }
+ this->tilesImage = image;
+ this->tiles = tiles;
+}
+
+void Tileset::saveTilesImage() {
+ // Only write the tiles image if it was changed.
+ // Porymap will only ever change an existing tiles image by importing a new one.
+ if (!m_hasUnsavedTilesImage)
+ return;
+
+ if (!this->tilesImage.save(this->tilesImagePath, "PNG")) {
+ logError(QString("Failed to save tiles image '%1'").arg(this->tilesImagePath));
+ return;
+ }
+
+ m_hasUnsavedTilesImage = false;
+}
+
+void Tileset::loadPalettes() {
+ this->palettes.clear();
+ this->palettePreviews.clear();
+
+ for (int i = 0; i < Project::getNumPalettesTotal(); i++) {
+ QList palette;
+ QString path = this->palettePaths.value(i);
+ if (!path.isEmpty()) {
+ bool error = false;
+ palette = PaletteUtil::parse(path, &error);
+ if (error) palette.clear();
+ }
+ if (palette.isEmpty()) {
+ // Either the palette failed to load, or no palette exists.
+ // We expect tilesets to have a certain number of palettes,
+ // so fill this palette with dummy colors.
+ for (int j = 0; j < 16; j++) {
+ palette.append(qRgb(j * 16, j * 16, j * 16));
+ }
+ }
+ this->palettes.append(palette);
+ this->palettePreviews.append(palette);
+ }
+}
+
+void Tileset::savePalettes() {
+ int numPalettes = qMin(this->palettePaths.length(), this->palettes.length());
+ for (int i = 0; i < numPalettes; i++) {
+ PaletteUtil::writeJASC(this->palettePaths.at(i), this->palettes.at(i).toVector(), 0, 16);
+ }
+}
+
+void Tileset::load() {
+ loadMetatiles();
+ loadMetatileAttributes();
+ loadTilesImage();
+ loadPalettes();
+}
+
+// Because metatile labels are global (and handled by the project) we don't save them here.
+void Tileset::save() {
+ saveMetatiles();
+ saveMetatileAttributes();
+ saveTilesImage();
+ savePalettes();
+}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index ff39fef7..3c16b0f4 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -25,6 +25,7 @@
#include "filedialog.h"
#include "newmapdialog.h"
#include "newlayoutdialog.h"
+#include "newtilesetdialog.h"
#include
#include
@@ -407,8 +408,8 @@ void MainWindow::initMapList() {
layout->setContentsMargins(0, 0, 0, 0);
// Create add map/layout button
- // TODO: Tool tip
QPushButton *buttonAdd = new QPushButton(QIcon(":/icons/add.ico"), "");
+ buttonAdd->setToolTip("Create New Map");
connect(buttonAdd, &QPushButton::clicked, this, &MainWindow::openNewMapDialog);
layout->addWidget(buttonAdd);
@@ -623,6 +624,7 @@ bool MainWindow::openProject(QString dir, bool initial) {
connect(project, &Project::mapLoaded, this, &MainWindow::onMapLoaded);
connect(project, &Project::mapCreated, this, &MainWindow::onNewMapCreated);
connect(project, &Project::layoutCreated, this, &MainWindow::onNewLayoutCreated);
+ connect(project, &Project::tilesetCreated, this, &MainWindow::onNewTilesetCreated);
connect(project, &Project::mapGroupAdded, this, &MainWindow::onNewMapGroupCreated);
connect(project, &Project::mapSectionAdded, this, &MainWindow::onNewMapSectionCreated);
connect(project, &Project::mapSectionIdNamesChanged, this->mapHeaderForm, &MapHeaderForm::setLocations);
@@ -925,7 +927,6 @@ void MainWindow::setLayoutOnlyMode(bool layoutOnly) {
// setLayout, but with a visible error message in case of failure.
// Use when the user is specifically requesting a layout to open.
-// TODO: Update the various functions taking layout IDs to take layout names (to mirror the equivalent map functions, this discrepancy is confusing atm)
bool MainWindow::userSetLayout(QString layoutId) {
if (!setLayout(layoutId)) {
QMessageBox msgBox(this);
@@ -1439,6 +1440,21 @@ void MainWindow::onNewMapSectionCreated(const QString &idName) {
// TODO: Refresh Region Map Editor's map section dropdown, if it's open
}
+void MainWindow::onNewTilesetCreated(Tileset *tileset) {
+ QString message = QString("Created a new tileset named %1.").arg(tileset->name);
+ logInfo(message);
+ statusBar()->showMessage(message);
+
+ // Refresh tileset combo boxes
+ if (!tileset->is_secondary) {
+ int index = this->editor->project->primaryTilesetLabels.indexOf(tileset->name);
+ ui->comboBox_PrimaryTileset->insertItem(index, tileset->name);
+ } else {
+ int index = this->editor->project->secondaryTilesetLabels.indexOf(tileset->name);
+ ui->comboBox_SecondaryTileset->insertItem(index, tileset->name);
+ }
+}
+
void MainWindow::openNewMapDialog() {
auto dialog = new NewMapDialog(this->editor->project, this);
dialog->open();
@@ -1450,119 +1466,9 @@ void MainWindow::openNewLayoutDialog() {
dialog->open();
}
-// Insert label for newly-created tileset into sorted list of existing labels
-int MainWindow::insertTilesetLabel(QStringList * list, QString label) {
- int i = 0;
- for (; i < list->length(); i++)
- if (list->at(i) > label) break;
- list->insert(i, label);
- return i;
-}
-
void MainWindow::on_actionNew_Tileset_triggered() {
- NewTilesetDialog *createTilesetDialog = new NewTilesetDialog(editor->project, this);
- if(createTilesetDialog->exec() == QDialog::Accepted){
- if(createTilesetDialog->friendlyName.isEmpty()) {
- logError(QString("Tried to create a directory with an empty name."));
- QMessageBox msgBox(this);
- msgBox.setText("Failed to add new tileset.");
- QString message = QString("The given name was empty.");
- msgBox.setInformativeText(message);
- msgBox.setDefaultButton(QMessageBox::Ok);
- msgBox.setIcon(QMessageBox::Icon::Critical);
- msgBox.exec();
- return;
- }
- QString fullDirectoryPath = editor->project->root + "/" + createTilesetDialog->path;
- QDir directory;
- if(directory.exists(fullDirectoryPath)) {
- logError(QString("Could not create tileset \"%1\", the folder \"%2\" already exists.").arg(createTilesetDialog->friendlyName, fullDirectoryPath));
- QMessageBox msgBox(this);
- msgBox.setText("Failed to add new tileset.");
- QString message = QString("The folder for tileset \"%1\" already exists. View porymap.log for specific errors.").arg(createTilesetDialog->friendlyName);
- msgBox.setInformativeText(message);
- msgBox.setDefaultButton(QMessageBox::Ok);
- msgBox.setIcon(QMessageBox::Icon::Critical);
- msgBox.exec();
- return;
- }
- if (editor->project->tilesetLabelsOrdered.contains(createTilesetDialog->fullSymbolName)) {
- logError(QString("Could not create tileset \"%1\", the symbol \"%2\" already exists.").arg(createTilesetDialog->friendlyName, createTilesetDialog->fullSymbolName));
- QMessageBox msgBox(this);
- msgBox.setText("Failed to add new tileset.");
- QString message = QString("The symbol for tileset \"%1\" (\"%2\") already exists.").arg(createTilesetDialog->friendlyName, createTilesetDialog->fullSymbolName);
- msgBox.setInformativeText(message);
- msgBox.setDefaultButton(QMessageBox::Ok);
- msgBox.setIcon(QMessageBox::Icon::Critical);
- msgBox.exec();
- return;
- }
- directory.mkdir(fullDirectoryPath);
- directory.mkdir(fullDirectoryPath + "/palettes");
- Tileset newSet;
- newSet.name = createTilesetDialog->fullSymbolName;
- newSet.tilesImagePath = fullDirectoryPath + "/tiles.png";
- newSet.metatiles_path = fullDirectoryPath + "/metatiles.bin";
- newSet.metatile_attrs_path = fullDirectoryPath + "/metatile_attributes.bin";
- newSet.is_secondary = createTilesetDialog->isSecondary;
- int numMetatiles = createTilesetDialog->isSecondary ? (Project::getNumMetatilesTotal() - Project::getNumMetatilesPrimary()) : Project::getNumMetatilesPrimary();
- QImage tilesImage(":/images/blank_tileset.png");
- editor->project->loadTilesetTiles(&newSet, tilesImage);
- int tilesPerMetatile = projectConfig.getNumTilesInMetatile();
- for(int i = 0; i < numMetatiles; ++i) {
- Metatile *mt = new Metatile();
- for(int j = 0; j < tilesPerMetatile; ++j){
- Tile tile = Tile();
- if (createTilesetDialog->checkerboardFill) {
- // Create a checkerboard-style dummy tileset
- if (((i / 8) % 2) == 0)
- tile.tileId = ((i % 2) == 0) ? 1 : 2;
- else
- tile.tileId = ((i % 2) == 1) ? 1 : 2;
- }
- mt->tiles.append(tile);
- }
- newSet.addMetatile(mt);
- }
- for(int i = 0; i < 16; ++i) {
- QList currentPal;
- for(int i = 0; i < 16;++i) {
- currentPal.append(qRgb(0,0,0));
- }
- newSet.palettes.append(currentPal);
- newSet.palettePreviews.append(currentPal);
- QString fileName = QString("%1.pal").arg(i, 2, 10, QLatin1Char('0'));
- newSet.palettePaths.append(fullDirectoryPath+"/palettes/" + fileName);
- }
- newSet.palettes[0][1] = qRgb(255,0,255);
- newSet.palettePreviews[0][1] = qRgb(255,0,255);
- exportIndexed4BPPPng(newSet.tilesImage, newSet.tilesImagePath);
- editor->project->saveTilesetMetatiles(&newSet);
- editor->project->saveTilesetMetatileAttributes(&newSet);
- editor->project->saveTilesetPalettes(&newSet);
-
- //append to tileset specific files
- newSet.appendToHeaders(editor->project->root, createTilesetDialog->friendlyName, editor->project->usingAsmTilesets);
- newSet.appendToGraphics(editor->project->root, createTilesetDialog->friendlyName, editor->project->usingAsmTilesets);
- newSet.appendToMetatiles(editor->project->root, createTilesetDialog->friendlyName, editor->project->usingAsmTilesets);
-
- if (!createTilesetDialog->isSecondary) {
- int index = insertTilesetLabel(&editor->project->primaryTilesetLabels, createTilesetDialog->fullSymbolName);
- this->ui->comboBox_PrimaryTileset->insertItem(index, createTilesetDialog->fullSymbolName);
- } else {
- int index = insertTilesetLabel(&editor->project->secondaryTilesetLabels, createTilesetDialog->fullSymbolName);
- this->ui->comboBox_SecondaryTileset->insertItem(index, createTilesetDialog->fullSymbolName);
- }
- editor->project->tilesetLabelsOrdered.append(createTilesetDialog->fullSymbolName);
-
- QMessageBox msgBox(this);
- msgBox.setText("Successfully created tileset.");
- QString message = QString("Tileset \"%1\" was created successfully.").arg(createTilesetDialog->friendlyName);
- msgBox.setInformativeText(message);
- msgBox.setDefaultButton(QMessageBox::Ok);
- msgBox.setIcon(QMessageBox::Icon::Information);
- msgBox.exec();
- }
+ auto dialog = new NewTilesetDialog(editor->project, this);
+ dialog->open();
}
void MainWindow::updateTilesetEditor() {
diff --git a/src/project.cpp b/src/project.cpp
index 22e1924e..e7fc3ab2 100644
--- a/src/project.cpp
+++ b/src/project.cpp
@@ -122,19 +122,13 @@ QString Project::getProjectTitle() {
}
void Project::clearMapCache() {
- for (auto *map : mapCache.values()) {
- if (map)
- delete map;
- }
- mapCache.clear();
+ qDeleteAll(this->mapCache);
+ this->mapCache.clear();
}
void Project::clearTilesetCache() {
- for (auto *tileset : tilesetCache.values()) {
- if (tileset)
- delete tileset;
- }
- tilesetCache.clear();
+ qDeleteAll(this->tilesetCache);
+ this->tilesetCache.clear();
}
Map* Project::loadMap(QString mapName) {
@@ -1005,25 +999,21 @@ void Project::saveHealLocationsConstants() {
void Project::saveTilesets(Tileset *primaryTileset, Tileset *secondaryTileset) {
saveTilesetMetatileLabels(primaryTileset, secondaryTileset);
- saveTilesetMetatileAttributes(primaryTileset);
- saveTilesetMetatileAttributes(secondaryTileset);
- saveTilesetMetatiles(primaryTileset);
- saveTilesetMetatiles(secondaryTileset);
- saveTilesetTilesImage(primaryTileset);
- saveTilesetTilesImage(secondaryTileset);
- saveTilesetPalettes(primaryTileset);
- saveTilesetPalettes(secondaryTileset);
+ if (primaryTileset)
+ primaryTileset->save();
+ if (secondaryTileset)
+ secondaryTileset->save();
}
void Project::updateTilesetMetatileLabels(Tileset *tileset) {
// Erase old labels, then repopulate with new labels
const QString prefix = tileset->getMetatileLabelPrefix();
- metatileLabelsMap[tileset->name].clear();
+ this->metatileLabelsMap[tileset->name].clear();
for (int metatileId : tileset->metatileLabels.keys()) {
if (tileset->metatileLabels[metatileId].isEmpty())
continue;
QString label = prefix + tileset->metatileLabels[metatileId];
- metatileLabelsMap[tileset->name][label] = metatileId;
+ this->metatileLabelsMap[tileset->name][label] = metatileId;
}
}
@@ -1082,59 +1072,6 @@ void Project::saveTilesetMetatileLabels(Tileset *primaryTileset, Tileset *second
saveTextFile(root + "/" + filename, outputText);
}
-void Project::saveTilesetMetatileAttributes(Tileset *tileset) {
- QFile attrs_file(tileset->metatile_attrs_path);
- if (attrs_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- QByteArray data;
- for (const auto &metatile : tileset->metatiles()) {
- uint32_t attributes = metatile->getAttributes();
- for (int i = 0; i < projectConfig.metatileAttributesSize; i++)
- data.append(static_cast(attributes >> (8 * i)));
- }
- attrs_file.write(data);
- } else {
- logError(QString("Could not save tileset metatile attributes file '%1'").arg(tileset->metatile_attrs_path));
- }
-}
-
-void Project::saveTilesetMetatiles(Tileset *tileset) {
- QFile metatiles_file(tileset->metatiles_path);
- if (metatiles_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- QByteArray data;
- int numTiles = projectConfig.getNumTilesInMetatile();
- for (const auto &metatile : tileset->metatiles()) {
- for (int i = 0; i < numTiles; i++) {
- uint16_t tile = metatile->tiles.at(i).rawValue();
- data.append(static_cast(tile));
- data.append(static_cast(tile >> 8));
- }
- }
- metatiles_file.write(data);
- } else {
- tileset->clearMetatiles();
- logError(QString("Could not open tileset metatiles file '%1'").arg(tileset->metatiles_path));
- }
-}
-
-void Project::saveTilesetTilesImage(Tileset *tileset) {
- // Only write the tiles image if it was changed.
- // Porymap will only ever change an existing tiles image by importing a new one.
- if (tileset->hasUnsavedTilesImage) {
- if (!tileset->tilesImage.save(tileset->tilesImagePath, "PNG")) {
- logError(QString("Failed to save tiles image '%1'").arg(tileset->tilesImagePath));
- return;
- }
- tileset->hasUnsavedTilesImage = false;
- }
-}
-
-void Project::saveTilesetPalettes(Tileset *tileset) {
- for (int i = 0; i < Project::getNumPalettesTotal(); i++) {
- QString filepath = tileset->palettePaths.at(i);
- PaletteUtil::writeJASC(filepath, tileset->palettes.at(i).toVector(), 0, 16);
- }
-}
-
bool Project::loadLayoutTilesets(Layout *layout) {
layout->tileset_primary = getTileset(layout->tileset_primary_label);
if (!layout->tileset_primary) {
@@ -1465,18 +1402,9 @@ void Project::loadTilesetAssets(Tileset* tileset) {
if (tileset->name.isNull()) {
return;
}
- this->readTilesetPaths(tileset);
- QImage image;
- if (QFile::exists(tileset->tilesImagePath)) {
- image = QImage(tileset->tilesImagePath).convertToFormat(QImage::Format_Indexed8, Qt::ThresholdDither);
- flattenTo4bppImage(&image);
- } else {
- image = QImage(8, 8, QImage::Format_Indexed8);
- }
- this->loadTilesetTiles(tileset, image);
- this->loadTilesetMetatiles(tileset);
- this->loadTilesetMetatileLabels(tileset);
- this->loadTilesetPalettes(tileset);
+ readTilesetPaths(tileset);
+ loadTilesetMetatileLabels(tileset);
+ tileset->load();
}
void Project::readTilesetPaths(Tileset* tileset) {
@@ -1536,84 +1464,89 @@ void Project::readTilesetPaths(Tileset* tileset) {
}
}
-void Project::loadTilesetPalettes(Tileset* tileset) {
- QList> palettes;
- QList> palettePreviews;
- for (int i = 0; i < tileset->palettePaths.length(); i++) {
- QString path = tileset->palettePaths.value(i);
- bool error = false;
- QList palette = PaletteUtil::parse(path, &error);
- if (error) {
- for (int j = 0; j < 16; j++) {
- palette.append(qRgb(j * 16, j * 16, j * 16));
+Tileset *Project::createNewTileset(const QString &friendlyName, bool secondary, bool checkerboardFill) {
+ auto tileset = new Tileset();
+ tileset->name = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix) + friendlyName;
+ tileset->is_secondary = secondary;
+
+ // Create tileset directories
+ const QString fullDirectoryPath = QString("%1/%2").arg(this->root).arg(tileset->getExpectedDir());
+ QDir directory;
+ if (!directory.mkpath(fullDirectoryPath)) {
+ logError(QString("Failed to create directory '%1' for new tileset '%2'").arg(fullDirectoryPath).arg(tileset->name));
+ delete tileset;
+ return nullptr;
+ }
+ const QString palettesPath = fullDirectoryPath + "/palettes";
+ if (!directory.mkpath(palettesPath)) {
+ logError(QString("Failed to create palettes directory '%1' for new tileset '%2'").arg(palettesPath).arg(tileset->name));
+ delete tileset;
+ return nullptr;
+ }
+
+ tileset->tilesImagePath = fullDirectoryPath + "/tiles.png";
+ tileset->metatiles_path = fullDirectoryPath + "/metatiles.bin";
+ tileset->metatile_attrs_path = fullDirectoryPath + "/metatile_attributes.bin";
+
+ // Set default tiles image
+ QImage tilesImage(":/images/blank_tileset.png");
+ tileset->loadTilesImage(&tilesImage);
+ //exportIndexed4BPPPng(tileset->tilesImage, tileset->tilesImagePath); // TODO: Make sure we can now properly handle the 8bpp images that get written without this.
+
+ // Create default metatiles
+ const int numMetatiles = tileset->is_secondary ? (Project::getNumMetatilesTotal() - Project::getNumMetatilesPrimary()) : Project::getNumMetatilesPrimary();
+ const int tilesPerMetatile = projectConfig.getNumTilesInMetatile();
+ for (int i = 0; i < numMetatiles; ++i) {
+ auto metatile = new Metatile();
+ for(int j = 0; j < tilesPerMetatile; ++j){
+ Tile tile = Tile();
+ if (checkerboardFill) {
+ // Create a checkerboard-style dummy tileset
+ if (((i / 8) % 2) == 0)
+ tile.tileId = ((i % 2) == 0) ? 1 : 2;
+ else
+ tile.tileId = ((i % 2) == 1) ? 1 : 2;
}
+ metatile->tiles.append(tile);
}
-
- palettes.append(palette);
- palettePreviews.append(palette);
- }
- tileset->palettes = palettes;
- tileset->palettePreviews = palettePreviews;
-}
-
-void Project::loadTilesetTiles(Tileset *tileset, QImage image) {
- QList tiles;
- int w = 8;
- int h = 8;
- for (int y = 0; y < image.height(); y += h)
- for (int x = 0; x < image.width(); x += w) {
- QImage tile = image.copy(x, y, w, h);
- tiles.append(tile);
- }
- tileset->tilesImage = image;
- tileset->tiles = tiles;
-}
-
-void Project::loadTilesetMetatiles(Tileset* tileset) {
- QFile metatiles_file(tileset->metatiles_path);
- if (metatiles_file.open(QIODevice::ReadOnly)) {
- QByteArray data = metatiles_file.readAll();
- int tilesPerMetatile = projectConfig.getNumTilesInMetatile();
- int bytesPerMetatile = 2 * tilesPerMetatile;
- int num_metatiles = data.length() / bytesPerMetatile;
- QList metatiles;
- for (int i = 0; i < num_metatiles; i++) {
- Metatile *metatile = new Metatile;
- int index = i * bytesPerMetatile;
- for (int j = 0; j < tilesPerMetatile; j++) {
- uint16_t tileRaw = static_cast(data[index++]);
- tileRaw |= static_cast(data[index++]) << 8;
- metatile->tiles.append(Tile(tileRaw));
- }
- metatiles.append(metatile);
- }
- tileset->setMetatiles(metatiles);
- } else {
- tileset->clearMetatiles();
- logError(QString("Could not open tileset metatiles file '%1'").arg(tileset->metatiles_path));
+ tileset->addMetatile(metatile);
}
- QFile attrs_file(tileset->metatile_attrs_path);
- if (attrs_file.open(QIODevice::ReadOnly)) {
- QByteArray data = attrs_file.readAll();
- int num_metatiles = tileset->numMetatiles();
- int attrSize = projectConfig.metatileAttributesSize;
- int num_metatileAttrs = data.length() / attrSize;
- if (num_metatiles != num_metatileAttrs) {
- logWarn(QString("Metatile count %1 does not match metatile attribute count %2 in %3").arg(num_metatiles).arg(num_metatileAttrs).arg(tileset->name));
- if (num_metatileAttrs > num_metatiles)
- num_metatileAttrs = num_metatiles;
+ // Create default palettes
+ for(int i = 0; i < 16; ++i) {
+ QList currentPal;
+ for(int i = 0; i < 16;++i) {
+ currentPal.append(qRgb(0,0,0));
}
-
- for (int i = 0; i < num_metatileAttrs; i++) {
- uint32_t attributes = 0;
- for (int j = 0; j < attrSize; j++)
- attributes |= static_cast(data.at(i * attrSize + j)) << (8 * j);
- tileset->metatileAt(i)->setAttributes(attributes);
- }
- } else {
- logError(QString("Could not open tileset metatile attributes file '%1'").arg(tileset->metatile_attrs_path));
+ tileset->palettes.append(currentPal);
+ tileset->palettePreviews.append(currentPal);
+ tileset->palettePaths.append(QString("%1/%2.pal").arg(palettesPath).arg(i, 2, 10, QLatin1Char('0')));
}
+ tileset->palettes[0][1] = qRgb(255,0,255);
+ tileset->palettePreviews[0][1] = qRgb(255,0,255);
+
+ // Update tileset label arrays
+ QStringList *labelList = tileset->is_secondary ? &this->secondaryTilesetLabels : &this->primaryTilesetLabels;
+ for (int i = 0; i < labelList->length(); i++) {
+ if (labelList->at(i) > tileset->name) {
+ labelList->insert(i, tileset->name);
+ break;
+ }
+ }
+ this->tilesetLabelsOrdered.append(tileset->name);
+
+ // TODO: Ideally we wouldn't save new Tilesets immediately
+ // Append to tileset specific files
+ tileset->appendToHeaders(this->root, friendlyName, this->usingAsmTilesets);
+ tileset->appendToGraphics(this->root, friendlyName, this->usingAsmTilesets);
+ tileset->appendToMetatiles(this->root, friendlyName, this->usingAsmTilesets);
+
+ tileset->save();
+
+ this->tilesetCache.insert(tileset->name, tileset);
+
+ emit tilesetCreated(tileset);
+ return tileset;
}
QString Project::findMetatileLabelsTileset(QString label) {
@@ -1658,9 +1591,9 @@ void Project::loadTilesetMetatileLabels(Tileset* tileset) {
QString metatileLabelPrefix = tileset->getMetatileLabelPrefix();
// Reverse map for faster lookup by metatile id
- for (QString labelName : metatileLabelsMap[tileset->name].keys()) {
- auto metatileId = metatileLabelsMap[tileset->name][labelName];
- tileset->metatileLabels[metatileId] = labelName.replace(metatileLabelPrefix, "");
+ for (auto it = this->metatileLabelsMap[tileset->name].constBegin(); it != this->metatileLabelsMap[tileset->name].constEnd(); it++) {
+ QString labelName = it.key();
+ tileset->metatileLabels[it.value()] = labelName.replace(metatileLabelPrefix, "");
}
}
diff --git a/src/scriptapi/apimap.cpp b/src/scriptapi/apimap.cpp
index f041b7b1..91cc4e67 100644
--- a/src/scriptapi/apimap.cpp
+++ b/src/scriptapi/apimap.cpp
@@ -337,7 +337,7 @@ void MainWindow::refreshAfterPaletteChange(Tileset *tileset) {
this->editor->map_item->draw(true);
this->editor->updateMapBorder();
this->editor->updateMapConnections();
- this->editor->project->saveTilesetPalettes(tileset);
+ tileset->savePalettes();
}
void MainWindow::setTilesetPalette(Tileset *tileset, int paletteIndex, QList> colors) {
@@ -576,14 +576,14 @@ void MainWindow::setSecondaryTileset(QString tileset) {
void MainWindow::saveMetatilesByMetatileId(int metatileId) {
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
- if (this->editor->project && tileset)
- this->editor->project->saveTilesetMetatiles(tileset);
+ if (tileset)
+ tileset->saveMetatiles();
}
void MainWindow::saveMetatileAttributesByMetatileId(int metatileId) {
Tileset * tileset = Tileset::getMetatileTileset(metatileId, this->editor->layout->tileset_primary, this->editor->layout->tileset_secondary);
- if (this->editor->project && tileset)
- this->editor->project->saveTilesetMetatileAttributes(tileset);
+ if (tileset)
+ tileset->saveMetatileAttributes();
// If the tileset editor is open it needs to be refreshed with the new changes.
// Rather than do a full refresh (which is costly) we tell the editor it will need
@@ -811,9 +811,6 @@ QJSValue MainWindow::getTilePixels(int tileId) {
// Editing map header
//=====================
-// TODO: Connect signals from new function calls to update UI
-// TODO: Is the error-checking for known constant names still reasonable / needed? (you can type anything after all)
-
QString MainWindow::getSong() {
if (!this->editor || !this->editor->map)
return QString();
@@ -823,10 +820,6 @@ QString MainWindow::getSong() {
void MainWindow::setSong(QString song) {
if (!this->editor || !this->editor->map || !this->editor->project)
return;
- if (!this->editor->project->songNames.contains(song)) {
- logError(QString("Unknown song '%1'").arg(song));
- return;
- }
this->editor->map->header()->setSong(song);
}
@@ -867,10 +860,6 @@ QString MainWindow::getWeather() {
void MainWindow::setWeather(QString weather) {
if (!this->editor || !this->editor->map || !this->editor->project)
return;
- if (!this->editor->project->weatherNames.contains(weather)) {
- logError(QString("Unknown weather '%1'").arg(weather));
- return;
- }
this->editor->map->header()->setWeather(weather);
}
@@ -883,10 +872,6 @@ QString MainWindow::getType() {
void MainWindow::setType(QString type) {
if (!this->editor || !this->editor->map || !this->editor->project)
return;
- if (!this->editor->project->mapTypes.contains(type)) {
- logError(QString("Unknown map type '%1'").arg(type));
- return;
- }
this->editor->map->header()->setType(type);
}
@@ -899,10 +884,6 @@ QString MainWindow::getBattleScene() {
void MainWindow::setBattleScene(QString battleScene) {
if (!this->editor || !this->editor->map || !this->editor->project)
return;
- if (!this->editor->project->mapBattleScenes.contains(battleScene)) {
- logError(QString("Unknown battle scene '%1'").arg(battleScene));
- return;
- }
this->editor->map->header()->setBattleScene(battleScene);
}
diff --git a/src/ui/newtilesetdialog.cpp b/src/ui/newtilesetdialog.cpp
index 8cb4c5f9..1ddd975d 100644
--- a/src/ui/newtilesetdialog.cpp
+++ b/src/ui/newtilesetdialog.cpp
@@ -1,50 +1,87 @@
#include "newtilesetdialog.h"
#include "ui_newtilesetdialog.h"
#include "project.h"
+#include "imageexport.h"
+
+const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
NewTilesetDialog::NewTilesetDialog(Project* project, QWidget *parent) :
QDialog(parent),
- ui(new Ui::NewTilesetDialog)
+ ui(new Ui::NewTilesetDialog),
+ symbolPrefix(projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix))
{
+ setAttribute(Qt::WA_DeleteOnClose);
+ setModal(true);
ui->setupUi(this);
- this->setFixedSize(this->width(), this->height());
this->project = project;
+
+ ui->checkBox_CheckerboardFill->setChecked(porymapConfig.tilesetCheckerboardFill);
+ ui->label_SymbolNameDisplay->setText(this->symbolPrefix);
+ ui->comboBox_Type->setMinimumContentsLength(12);
+
//only allow characters valid for a symbol
- static const QRegularExpression expression("[_A-Za-z0-9]+$"); // TODO: Incorrect, allows digits at beginning
- QRegularExpressionValidator *validator = new QRegularExpressionValidator(expression);
- this->ui->nameLineEdit->setValidator(validator);
+ static const QRegularExpression expression("[A-Za-z_]+[\\w]*");
+ QRegularExpressionValidator *validator = new QRegularExpressionValidator(expression, this);
+ ui->lineEdit_FriendlyName->setValidator(validator);
- bool checkerboard = porymapConfig.tilesetCheckerboardFill;
- this->ui->fillCheckBox->setChecked(checkerboard);
- this->checkerboardFill = checkerboard;
+ connect(ui->lineEdit_FriendlyName, &QLineEdit::textChanged, this, &NewTilesetDialog::onFriendlyNameChanged);
+ connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewTilesetDialog::dialogButtonClicked);
- connect(this->ui->nameLineEdit, &QLineEdit::textChanged, this, &NewTilesetDialog::NameOrSecondaryChanged);
- connect(this->ui->typeComboBox, &QComboBox::currentTextChanged, this, &NewTilesetDialog::SecondaryChanged);
- connect(this->ui->fillCheckBox, &QCheckBox::stateChanged, this, &NewTilesetDialog::FillChanged);
- //connect(this->ui->toolButton, &QToolButton::clicked, this, &NewTilesetDialog::ChangeFilePath);
- this->SecondaryChanged();
+ adjustSize();
}
NewTilesetDialog::~NewTilesetDialog()
{
+ porymapConfig.tilesetCheckerboardFill = ui->checkBox_CheckerboardFill->isChecked();
delete ui;
}
-void NewTilesetDialog::SecondaryChanged(){
- this->isSecondary = (this->ui->typeComboBox->currentIndex() == 1);
- NameOrSecondaryChanged();
+void NewTilesetDialog::onFriendlyNameChanged(const QString &friendlyName) {
+ // When the tileset name is changed, update this label to display the full symbol name.
+ ui->label_SymbolNameDisplay->setText(this->symbolPrefix + friendlyName);
+
+ validateName(true);
}
-// TODO: No validation
-void NewTilesetDialog::NameOrSecondaryChanged() {
- this->friendlyName = this->ui->nameLineEdit->text();
- this->fullSymbolName = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix) + this->friendlyName;
- this->ui->symbolNameLineEdit->setText(this->fullSymbolName);
- this->path = Tileset::getExpectedDir(this->fullSymbolName, this->isSecondary);
- this->ui->pathLineEdit->setText(this->path);
+bool NewTilesetDialog::validateName(bool allowEmpty) {
+ const QString friendlyName = ui->lineEdit_FriendlyName->text();
+ const QString symbolName = ui->label_SymbolNameDisplay->text();
+
+ QString errorText;
+ if (friendlyName.isEmpty()) {
+ if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_FriendlyName->text());
+ } else if (!this->project->isIdentifierUnique(symbolName)) {
+ errorText = QString("%1 '%2' is not unique.").arg(ui->label_SymbolName->text()).arg(symbolName);
+ }
+
+ bool isValid = errorText.isEmpty();
+ ui->label_NameError->setText(errorText);
+ ui->label_NameError->setVisible(!isValid);
+ ui->lineEdit_FriendlyName->setStyleSheet(!isValid ? lineEdit_ErrorStylesheet : "");
+ return isValid;
}
-void NewTilesetDialog::FillChanged() {
- this->checkerboardFill = this->ui->fillCheckBox->isChecked();
- porymapConfig.tilesetCheckerboardFill = this->checkerboardFill;
+void NewTilesetDialog::dialogButtonClicked(QAbstractButton *button) {
+ auto role = ui->buttonBox->buttonRole(button);
+ if (role == QDialogButtonBox::RejectRole){
+ reject();
+ } else if (role == QDialogButtonBox::AcceptRole) {
+ accept();
+ }
+}
+
+void NewTilesetDialog::accept() {
+ if (!validateName())
+ return;
+
+ bool secondary = ui->comboBox_Type->currentIndex() == 1;
+ Tileset *tileset = this->project->createNewTileset(ui->lineEdit_FriendlyName->text(), secondary, ui->checkBox_CheckerboardFill->isChecked());
+ if (!tileset) {
+ ui->label_GenericError->setText(QString("Failed to create tileset. See %1 for details.").arg(getLogPath()));
+ ui->label_GenericError->setVisible(true);
+ return;
+ }
+ ui->label_GenericError->setVisible(false);
+
+ QDialog::accept();
}
diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp
index 940761ad..f3c4a1c9 100644
--- a/src/ui/tileseteditor.cpp
+++ b/src/ui/tileseteditor.cpp
@@ -716,22 +716,9 @@ void TilesetEditor::importTilesetTiles(Tileset *tileset, bool primary) {
image = image.convertToFormat(QImage::Format::Format_Indexed8, colorTable);
}
- // Validate image is properly indexed to 16 colors.
- int colorCount = image.colorCount();
- if (colorCount > 16) {
- flattenTo4bppImage(&image);
- } else if (colorCount < 16) {
- QVector colorTable = image.colorTable();
- for (int i = colorTable.length(); i < 16; i++) {
- colorTable.append(Qt::black);
- }
- image.setColorTable(colorTable);
- }
-
- this->project->loadTilesetTiles(tileset, image);
+ tileset->loadTilesImage(&image);
this->refresh();
this->hasUnsavedChanges = true;
- tileset->hasUnsavedTilesImage = true;
}
void TilesetEditor::closeEvent(QCloseEvent *event)