This commit is contained in:
garak 2019-04-06 18:12:21 -04:00
commit fe22a2fbbc
16 changed files with 555 additions and 58 deletions

View file

@ -7,7 +7,10 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp
The **"Breaking Changes"** listed below are changes that have been made in the decompilation projects (e.g. pokeemerald), which porymap requires in order to work properly. If porymap is used on a project that is not up-to-date with the breaking changes, then porymap will likely break or behave improperly. The **"Breaking Changes"** listed below are changes that have been made in the decompilation projects (e.g. pokeemerald), which porymap requires in order to work properly. If porymap is used on a project that is not up-to-date with the breaking changes, then porymap will likely break or behave improperly.
## [Unreleased] ## [Unreleased]
- None ### Fixed
- Fix bug in zoomed metatile selector where a large selection rectangle was being rendered.
- Fix bug where edited map icons were not rendered properly.
- Fix bug where right-click copying a tile from the tileset editor's metatile layers wouldn't copy the x/y flip status.
## [1.2.1] - 2019-02-16 ## [1.2.1] - 2019-02-16
### Added ### Added
@ -77,7 +80,7 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
## [1.0.0] - 2018-10-26 ## [1.0.0] - 2018-10-26
This was the initial release. This was the initial release.
[Unreleased]: https://github.com/huderlem/porymap/compare/1.2.0...HEAD [Unreleased]: https://github.com/huderlem/porymap/compare/1.2.1...HEAD
[1.2.1]: https://github.com/huderlem/porymap/compare/1.2.0...1.2.1 [1.2.1]: https://github.com/huderlem/porymap/compare/1.2.0...1.2.1
[1.2.0]: https://github.com/huderlem/porymap/compare/1.1.0...1.2.0 [1.2.0]: https://github.com/huderlem/porymap/compare/1.1.0...1.2.0
[1.1.0]: https://github.com/huderlem/porymap/compare/1.0.0...1.1.0 [1.1.0]: https://github.com/huderlem/porymap/compare/1.0.0...1.1.0

View file

@ -561,8 +561,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>545</width> <width>522</width>
<height>587</height> <height>601</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_8"> <layout class="QGridLayout" name="gridLayout_8">
@ -876,8 +876,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>256</width> <width>259</width>
<height>74</height> <height>70</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_7"> <layout class="QHBoxLayout" name="horizontalLayout_7">
@ -1064,10 +1064,10 @@
</property> </property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>8</x> <x>0</x>
<y>0</y> <y>0</y>
<width>222</width> <width>263</width>
<height>353</height> <height>338</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1166,7 +1166,7 @@
<number>10</number> <number>10</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>100</number> <number>90</number>
</property> </property>
<property name="value"> <property name="value">
<number>30</number> <number>30</number>
@ -1344,8 +1344,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>371</width> <width>385</width>
<height>643</height> <height>652</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_7"> <layout class="QGridLayout" name="gridLayout_7">
@ -1617,8 +1617,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>430</width> <width>432</width>
<height>534</height> <height>554</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -2531,8 +2531,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>818</width> <width>829</width>
<height>539</height> <height>543</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_14"> <layout class="QGridLayout" name="gridLayout_14">
@ -2748,6 +2748,7 @@
<addaction name="actionMap_Shift"/> <addaction name="actionMap_Shift"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_NewMap"/> <addaction name="action_NewMap"/>
<addaction name="actionNew_Tileset"/>
<addaction name="actionTileset_Editor"/> <addaction name="actionTileset_Editor"/>
<addaction name="actionRegion_Map_Editor"/> <addaction name="actionRegion_Map_Editor"/>
</widget> </widget>
@ -2798,7 +2799,7 @@
</action> </action>
<action name="action_NewMap"> <action name="action_NewMap">
<property name="text"> <property name="text">
<string>New Map</string> <string>New Map...</string>
</property> </property>
<property name="shortcut"> <property name="shortcut">
<string>Ctrl+N</string> <string>Ctrl+N</string>
@ -2982,6 +2983,14 @@
<string>Region Map Editor</string> <string>Region Map Editor</string>
</property> </property>
</action> </action>
<action name="actionNew_Tileset">
<property name="text">
<string>New Tileset...</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+N</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

222
forms/newtilesetdialog.ui Normal file
View file

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewTilesetDialog</class>
<widget class="QDialog" name="NewTilesetDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>190</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Add new Tileset</string>
</property>
<widget class="QWidget" name="gridWidget" native="true">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>190</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>380</width>
<height>135</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>380</width>
<height>129</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="nameLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="typeLabel">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="typeComboBox">
<item>
<property name="text">
<string>Primary</string>
</property>
</item>
<item>
<property name="text">
<string>Secondary</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="pathLabel">
<property name="text">
<string>Path</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="pathLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="symbolNameLabel">
<property name="text">
<string>Symbol Name</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="symbolNameLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="4" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>NewTilesetDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>NewTilesetDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -35,6 +35,10 @@ public:
static Metatile* getMetatile(int, Tileset*, Tileset*); static Metatile* getMetatile(int, Tileset*, Tileset*);
static QList<QList<QRgb>> getBlockPalettes(Tileset*, Tileset*); static QList<QList<QRgb>> getBlockPalettes(Tileset*, Tileset*);
static QList<QRgb> getPalette(int, Tileset*, Tileset*); static QList<QRgb> getPalette(int, Tileset*, Tileset*);
bool appendToHeaders(QString headerFile, QString friendlyName);
bool appendToGraphics(QString graphicsFile, QString friendlyName, bool primary);
bool appendToMetatiles(QString metatileFile, QString friendlyName, bool primary);
}; };
#endif // TILESET_H #endif // TILESET_H

View file

@ -18,6 +18,7 @@
#include "regionmapeditor.h" #include "regionmapeditor.h"
#include "filterchildrenproxymodel.h" #include "filterchildrenproxymodel.h"
#include "newmappopup.h" #include "newmappopup.h"
#include "newtilesetdialog.h"
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
@ -53,6 +54,7 @@ private slots:
void onNewMapCreated(); void onNewMapCreated();
void on_action_NewMap_triggered(); void on_action_NewMap_triggered();
void on_actionNew_Tileset_triggered();
void on_action_Save_triggered(); void on_action_Save_triggered();
void on_tabWidget_2_currentChanged(int index); void on_tabWidget_2_currentChanged(int index);
void on_action_Exit_triggered(); void on_action_Exit_triggered();
@ -175,6 +177,7 @@ private:
Editor *editor = nullptr; Editor *editor = nullptr;
QIcon* mapIcon; QIcon* mapIcon;
QIcon* mapEditedIcon; QIcon* mapEditedIcon;
QIcon* mapOpenedIcon;
QWidget *eventTabObjectWidget; QWidget *eventTabObjectWidget;
QWidget *eventTabWarpWidget; QWidget *eventTabWarpWidget;
@ -204,8 +207,7 @@ private:
void setRecentMap(QString map_name); void setRecentMap(QString map_name);
QStandardItem* createMapItem(QString mapName, int groupNum, int inGroupNum); QStandardItem* createMapItem(QString mapName, int groupNum, int inGroupNum);
void markAllEdited(QAbstractItemModel *model); void drawMapListIcons(QAbstractItemModel *model);
void markEdited(QModelIndex index);
void updateMapList(); void updateMapList();
void displayMapProperties(); void displayMapProperties();

View file

@ -92,11 +92,15 @@ public:
void saveMapConstantsHeader(); void saveMapConstantsHeader();
void saveHealLocationStruct(Map*); void saveHealLocationStruct(Map*);
void saveTilesets(Tileset*, Tileset*); void saveTilesets(Tileset*, Tileset*);
void saveTilesetMetatileAttributes(Tileset*);
void saveTilesetMetatiles(Tileset*);
void saveTilesetTilesImage(Tileset*);
void saveTilesetPalettes(Tileset*, bool);
QList<QStringList>* parseAsm(QString text); QList<QStringList>* parseAsm(QString text);
QStringList getSongNames(); QStringList getSongNames();
QStringList getVisibilities(); QStringList getVisibilities();
QMap<QString, QStringList> getTilesets(); QMap<QString, QStringList> getTilesetLabels();
void readTilesetProperties(); void readTilesetProperties();
void readRegionMapSections(); void readRegionMapSections();
void readItemNames(); void readItemNames();
@ -131,10 +135,6 @@ public:
static int getNumPalettesPrimary(); static int getNumPalettesPrimary();
static int getNumPalettesTotal(); static int getNumPalettesTotal();
private: private:
void saveTilesetMetatileAttributes(Tileset*);
void saveTilesetMetatiles(Tileset*);
void saveTilesetTilesImage(Tileset*);
void saveTilesetPalettes(Tileset*, bool);
void updateMapLayout(Map*); void updateMapLayout(Map*);
void readCDefinesSorted(QString, QStringList, QStringList*); void readCDefinesSorted(QString, QStringList, QStringList*);
void readCDefinesSorted(QString, QStringList, QStringList*, QString, int); void readCDefinesSorted(QString, QStringList, QStringList*, QString, int);

View file

@ -0,0 +1,32 @@
#ifndef NEWTILESETDIALOG_H
#define NEWTILESETDIALOG_H
#include <QDialog>
#include "project.h"
namespace Ui {
class NewTilesetDialog;
}
class NewTilesetDialog : public QDialog
{
Q_OBJECT
public:
explicit NewTilesetDialog(Project *project, QWidget *parent = nullptr);
~NewTilesetDialog();
QString path;
QString fullSymbolName;
QString friendlyName;
bool isSecondary;
private slots:
void NameOrSecondaryChanged();
void SecondaryChanged();
private:
Ui::NewTilesetDialog *ui;
Project *project = nullptr;
};
#endif // NEWTILESETDIALOG_H

View file

@ -66,7 +66,8 @@ SOURCES += src/core/block.cpp \
src/mainwindow.cpp \ src/mainwindow.cpp \
src/project.cpp \ src/project.cpp \
src/settings.cpp \ src/settings.cpp \
src/log.cpp src/log.cpp \
src/ui/newtilesetdialog.cpp
HEADERS += include/core/block.h \ HEADERS += include/core/block.h \
include/core/blockdata.h \ include/core/blockdata.h \
@ -121,7 +122,8 @@ HEADERS += include/core/block.h \
include/mainwindow.h \ include/mainwindow.h \
include/project.h \ include/project.h \
include/settings.h \ include/settings.h \
include/log.h include/log.h \
include/ui/newtilesetdialog.h
FORMS += forms/mainwindow.ui \ FORMS += forms/mainwindow.ui \
forms/eventpropertiesframe.ui \ forms/eventpropertiesframe.ui \
@ -129,7 +131,8 @@ FORMS += forms/mainwindow.ui \
forms/paletteeditor.ui \ forms/paletteeditor.ui \
forms/regionmapeditor.ui \ forms/regionmapeditor.ui \
forms/newmappopup.ui \ forms/newmappopup.ui \
forms/aboutporymap.ui forms/aboutporymap.ui \
forms/newtilesetdialog.ui
RESOURCES += \ RESOURCES += \
resources/images.qrc resources/images.qrc

View file

@ -30,5 +30,6 @@
<file>icons/sort_number.ico</file> <file>icons/sort_number.ico</file>
<file>icons/collapse_all.ico</file> <file>icons/collapse_all.ico</file>
<file>icons/expand_all.ico</file> <file>icons/expand_all.ico</file>
<file>images/blank_tileset.png</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

View file

@ -1,6 +1,7 @@
#include "tileset.h" #include "tileset.h"
#include "metatile.h" #include "metatile.h"
#include "project.h" #include "project.h"
#include "log.h"
#include <QPainter> #include <QPainter>
#include <QImage> #include <QImage>
@ -86,3 +87,68 @@ QList<QRgb> Tileset::getPalette(int paletteId, Tileset *primaryTileset, Tileset
} }
return paletteTable; return paletteTable;
} }
bool Tileset::appendToHeaders(QString headerFile, QString friendlyName){
QFile file(headerFile);
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
logError(QString("Could not write to file \"%1\"").arg(headerFile));
return false;
}
QString dataString = "\n\t.align 2\n";
dataString.append(QString("%1::\n").arg(this->name));
dataString.append(QString("\t.byte %1 @ is compressed\n").arg(this->is_compressed));
dataString.append(QString("\t.byte %1 @ is secondary\n").arg(this->is_secondary));
dataString.append(QString("\t.2byte %1\n").arg(this->padding));
dataString.append(QString("\t.4byte gTilesetTiles_%1\n").arg(friendlyName));
dataString.append(QString("\t.4byte gTilesetPalettes_%1\n").arg(friendlyName));
dataString.append(QString("\t.4byte gMetatiles_%1\n").arg(friendlyName));
dataString.append(QString("\t.4byte gMetatileAttributes_%1\n").arg(friendlyName));
dataString.append("\t.4byte NULL\n");
file.write(dataString.toUtf8());
file.flush();
file.close();
return true;
}
bool Tileset::appendToGraphics(QString graphicsFile, QString friendlyName, bool primary) {
QString primaryString = primary ? "primary" : "secondary";
QFile file(graphicsFile);
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
logError(QString("Could not write to file \"%1\"").arg(graphicsFile));
return false;
}
QString dataString = "\n\t.align 2\n";
dataString.append(QString("gTilesetPalettes_%1::\n").arg(friendlyName));
for(int i = 0; i < Project::getNumPalettesTotal(); ++i) {
QString paletteString;
paletteString.sprintf("%02d.gbapal", i);
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/palettes/%3\"\n").arg(primaryString, friendlyName.toLower(), paletteString));
}
dataString.append("\n\t.align 2\n");
dataString.append(QString("gTilesetTiles_%1::\n").arg(friendlyName));
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/tiles.4bpp.lz\"\n").arg(primaryString, friendlyName.toLower()));
file.write(dataString.toUtf8());
file.flush();
file.close();
return true;
}
bool Tileset::appendToMetatiles(QString metatileFile, QString friendlyName, bool primary) {
QString primaryString = primary ? "primary" : "secondary";
QFile file(metatileFile);
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
logError(QString("Could not write to file \"%1\"").arg(metatileFile));
return false;
}
QString dataString = "\n\t.align 1\n";
dataString.append(QString("gMetatiles_%1::\n").arg(friendlyName));
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/metatiles.bin\"\n").arg(primaryString, friendlyName.toLower()));
dataString.append(QString("\n\t.align 1\n"));
dataString.append(QString("gMetatileAttributes_%1::\n").arg(friendlyName));
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/metatile_attributes.bin\"").arg(primaryString, friendlyName.toLower()));
file.write(dataString.toUtf8());
file.flush();
file.close();
return true;
}

View file

@ -10,6 +10,7 @@
#include "currentselectedmetatilespixmapitem.h" #include "currentselectedmetatilespixmapitem.h"
#include "customattributestable.h" #include "customattributestable.h"
#include <QFileDialog> #include <QFileDialog>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QShortcut> #include <QShortcut>
@ -101,13 +102,9 @@ void MainWindow::initEditor() {
} }
void MainWindow::initMiscHeapObjects() { void MainWindow::initMiscHeapObjects() {
mapIcon = new QIcon; mapIcon = new QIcon(QStringLiteral(":/icons/map.ico"));
mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off); mapEditedIcon = new QIcon(QStringLiteral(":/icons/map_edited.ico"));
mapIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal, QIcon::On); mapOpenedIcon = new QIcon(QStringLiteral(":/icons/map_opened.ico"));
mapEditedIcon = new QIcon;
mapEditedIcon->addFile(QStringLiteral(":/icons/map_edited.ico"), QSize(), QIcon::Normal, QIcon::Off);
mapEditedIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal , QIcon::On);
mapListModel = new QStandardItemModel; mapListModel = new QStandardItemModel;
mapGroupItemsList = new QList<QStandardItem*>; mapGroupItemsList = new QList<QStandardItem*>;
@ -472,7 +469,7 @@ void MainWindow::displayMapProperties() {
ui->comboBox_Location->addItems(project->mapSectionValueToName.values()); ui->comboBox_Location->addItems(project->mapSectionValueToName.values());
ui->comboBox_Location->setCurrentText(map->location); ui->comboBox_Location->setCurrentText(map->location);
QMap<QString, QStringList> tilesets = project->getTilesets(); QMap<QString, QStringList> tilesets = project->getTilesetLabels();
ui->comboBox_PrimaryTileset->addItems(tilesets.value("primary")); ui->comboBox_PrimaryTileset->addItems(tilesets.value("primary"));
ui->comboBox_PrimaryTileset->setCurrentText(map->layout->tileset_primary_label); ui->comboBox_PrimaryTileset->setCurrentText(map->layout->tileset_primary_label);
ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary")); ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary"));
@ -856,6 +853,116 @@ void MainWindow::on_action_NewMap_triggered() {
openNewMapPopupWindow(MapSortOrder::Group, 0); openNewMapPopupWindow(MapSortOrder::Group, 0);
} }
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;
}
QMap<QString, QStringList> tilesets = this->editor->project->getTilesetLabels();
if(tilesets.value("primary").contains(createTilesetDialog->fullSymbolName) || tilesets.value("secondary").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 = new Tileset();
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 ? "TRUE" : "FALSE";
int numMetaTiles = createTilesetDialog->isSecondary ? (Project::getNumTilesTotal() - Project::getNumTilesPrimary()) : Project::getNumTilesPrimary();
QImage *tilesImage = new QImage(":/images/blank_tileset.png");
editor->project->loadTilesetTiles(newSet, *tilesImage);
newSet->metatiles = new QList<Metatile*>();
for(int i = 0; i < numMetaTiles; ++i) {
Metatile *mt = new Metatile();
for(int j = 0; j < 8; ++j){
Tile *tile = new Tile();
//Create a checkerboard-style dummy tileset
if(((i / 8) % 2) == 0)
tile->tile = ((i % 2) == 0) ? 1 : 2;
else
tile->tile = ((i % 2) == 1) ? 1 : 2;
tile->xflip = false;
tile->yflip = false;
tile->palette = 0;
mt->tiles->append(*tile);
}
mt->behavior = 0;
mt->layerType = 0;
newSet->metatiles->append(mt);
}
newSet->palettes = new QList<QList<QRgb>>();
newSet->palettePaths = *new QList<QString>();
for(int i = 0; i < 16; ++i) {
QList<QRgb> *currentPal = new QList<QRgb>();
for(int i = 0; i < 16;++i) {
currentPal->append(qRgb(0,0,0));
}
newSet->palettes->append(*currentPal);
QString fileName;
fileName.sprintf("%02d.pal", i);
newSet->palettePaths.append(fullDirectoryPath+"/palettes/" + fileName);
}
(*newSet->palettes)[0][1] = qRgb(255,0,255);
newSet->is_compressed = "TRUE";
newSet->padding = "0";
editor->project->saveTilesetTilesImage(newSet);
editor->project->saveTilesetMetatiles(newSet);
editor->project->saveTilesetMetatileAttributes(newSet);
editor->project->saveTilesetPalettes(newSet, !createTilesetDialog->isSecondary);
//append to tileset specific files
newSet->appendToHeaders(editor->project->root + "/data/tilesets/headers.inc", createTilesetDialog->friendlyName);
newSet->appendToGraphics(editor->project->root + "/data/tilesets/graphics.inc", createTilesetDialog->friendlyName, !createTilesetDialog->isSecondary);
newSet->appendToMetatiles(editor->project->root + "/data/tilesets/metatiles.inc", createTilesetDialog->friendlyName, !createTilesetDialog->isSecondary);
if(!createTilesetDialog->isSecondary) {
this->ui->comboBox_PrimaryTileset->addItem(createTilesetDialog->fullSymbolName);
} else {
this->ui->comboBox_SecondaryTileset->addItem(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();
}
}
void MainWindow::onTilesetChanged(QString mapName) void MainWindow::onTilesetChanged(QString mapName)
{ {
setMap(mapName); setMap(mapName);
@ -869,13 +976,15 @@ void MainWindow::updateTilesetEditor() {
void MainWindow::currentMetatilesSelectionChanged() void MainWindow::currentMetatilesSelectionChanged()
{ {
ui->graphicsView_currentMetatileSelection->setFixedSize(editor->scene_current_metatile_selection_item->pixmap().width() + 2, editor->scene_current_metatile_selection_item->pixmap().height() + 2); double scale = pow(3.0, static_cast<double>(porymapConfig.getMetatilesZoom() - 30) / 30.0);
ui->graphicsView_currentMetatileSelection->setSceneRect(0, 0, editor->scene_current_metatile_selection_item->pixmap().width(), editor->scene_current_metatile_selection_item->pixmap().height()); ui->graphicsView_currentMetatileSelection->setFixedSize(editor->scene_current_metatile_selection_item->pixmap().width() * scale + 2, editor->scene_current_metatile_selection_item->pixmap().height() * scale + 2);
ui->graphicsView_currentMetatileSelection->setSceneRect(0, 0, editor->scene_current_metatile_selection_item->pixmap().width() * scale, editor->scene_current_metatile_selection_item->pixmap().height() * scale);
QPoint size = editor->metatile_selector_item->getSelectionDimensions(); QPoint size = editor->metatile_selector_item->getSelectionDimensions();
if (size.x() == 1 && size.y() == 1) { if (size.x() == 1 && size.y() == 1) {
QPoint pos = editor->metatile_selector_item->getMetatileIdCoordsOnWidget(editor->metatile_selector_item->getSelectedMetatiles()->at(0)); QPoint pos = editor->metatile_selector_item->getMetatileIdCoordsOnWidget(editor->metatile_selector_item->getSelectedMetatiles()->at(0));
ui->scrollArea_2->ensureVisible(pos.x(), pos.y(), 8, 8); pos *= scale;
ui->scrollArea_2->ensureVisible(pos.x(), pos.y(), 8 * scale, 8 * scale);
} }
} }
@ -887,7 +996,7 @@ void MainWindow::on_mapList_activated(const QModelIndex &index)
} }
} }
void MainWindow::markAllEdited(QAbstractItemModel *model) { void MainWindow::drawMapListIcons(QAbstractItemModel *model) {
QList<QModelIndex> list; QList<QModelIndex> list;
list.append(QModelIndex()); list.append(QModelIndex());
while (list.length()) { while (list.length()) {
@ -897,19 +1006,18 @@ void MainWindow::markAllEdited(QAbstractItemModel *model) {
if (model->hasChildren(index)) { if (model->hasChildren(index)) {
list.append(index); list.append(index);
} }
markEdited(index); QVariant data = index.data(Qt::UserRole);
} if (!data.isNull()) {
} QString map_name = data.toString();
} if (editor->project && editor->project->map_cache->contains(map_name)) {
QStandardItem *map = mapListModel->itemFromIndex(mapListIndexes.value(map_name));
void MainWindow::markEdited(QModelIndex index) { map->setIcon(*mapIcon);
QVariant data = index.data(Qt::UserRole); if (editor->project->map_cache->value(map_name)->hasUnsavedChanges()) {
if (!data.isNull()) { map->setIcon(*mapEditedIcon);
QString map_name = data.toString(); }
if (editor->project) { if (editor->map->name == map_name) {
if (editor->project->map_cache->contains(map_name)) { map->setIcon(*mapOpenedIcon);
if (editor->project->map_cache->value(map_name)->hasUnsavedChanges()) { }
mapListModel->itemFromIndex(mapListIndexes.value(map_name))->setIcon(*mapEditedIcon);
} }
} }
} }
@ -918,7 +1026,7 @@ void MainWindow::markEdited(QModelIndex index) {
void MainWindow::updateMapList() { void MainWindow::updateMapList() {
QAbstractItemModel *model = ui->mapList->model(); QAbstractItemModel *model = ui->mapList->model();
markAllEdited(model); drawMapListIcons(model);
} }
void MainWindow::on_action_Save_Project_triggered() void MainWindow::on_action_Save_Project_triggered()
@ -1977,6 +2085,13 @@ void MainWindow::on_horizontalSlider_MetatileZoom_valueChanged(int value) {
ui->graphicsView_Metatiles->setResizeAnchor(QGraphicsView::NoAnchor); ui->graphicsView_Metatiles->setResizeAnchor(QGraphicsView::NoAnchor);
ui->graphicsView_Metatiles->setMatrix(matrix); ui->graphicsView_Metatiles->setMatrix(matrix);
ui->graphicsView_Metatiles->setFixedSize(size.width() + 2, size.height() + 2); ui->graphicsView_Metatiles->setFixedSize(size.width() + 2, size.height() + 2);
ui->graphicsView_BorderMetatile->setMatrix(matrix);
ui->graphicsView_BorderMetatile->setFixedSize(ceil(static_cast<double>(editor->selected_border_metatiles_item->pixmap().width()) * scale) + 2,
ceil(static_cast<double>(editor->selected_border_metatiles_item->pixmap().height()) * scale) + 2);
ui->graphicsView_currentMetatileSelection->setMatrix(matrix);
currentMetatilesSelectionChanged();
} }
void MainWindow::on_actionRegion_Map_Editor_triggered() { void MainWindow::on_actionRegion_Map_Editor_triggered() {

View file

@ -720,9 +720,7 @@ void Project::saveTilesetTilesImage(Tileset *tileset) {
} }
void Project::saveTilesetPalettes(Tileset *tileset, bool primary) { void Project::saveTilesetPalettes(Tileset *tileset, bool primary) {
int startPaletteId = primary ? 0 : Project::getNumPalettesPrimary(); for (int i = 0; i < Project::getNumPalettesTotal(); i++) {
int endPaletteId = primary ? Project::getNumPalettesPrimary() : Project::getNumPalettesTotal();
for (int i = startPaletteId; i < endPaletteId; i++) {
QString filepath = tileset->palettePaths.at(i); QString filepath = tileset->palettePaths.at(i);
QString content = "JASC-PAL\r\n"; QString content = "JASC-PAL\r\n";
content += "0100\r\n"; content += "0100\r\n";
@ -1408,7 +1406,7 @@ QStringList Project::getVisibilities() {
return names; return names;
} }
QMap<QString, QStringList> Project::getTilesets() { QMap<QString, QStringList> Project::getTilesetLabels() {
QMap<QString, QStringList> allTilesets; QMap<QString, QStringList> allTilesets;
QStringList primaryTilesets; QStringList primaryTilesets;
QStringList secondaryTilesets; QStringList secondaryTilesets;

View file

@ -48,7 +48,7 @@ void NewMapPopup::useLayout(QString layoutId) {
void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) { void NewMapPopup::setDefaultValues(int groupNum, QString mapSec) {
ui->lineEdit_NewMap_Name->setText(project->getNewMapName()); ui->lineEdit_NewMap_Name->setText(project->getNewMapName());
QMap<QString, QStringList> tilesets = project->getTilesets(); QMap<QString, QStringList> tilesets = project->getTilesetLabels();
ui->comboBox_NewMap_Primary_Tileset->addItems(tilesets.value("primary")); ui->comboBox_NewMap_Primary_Tileset->addItems(tilesets.value("primary"));
ui->comboBox_NewMap_Secondary_Tileset->addItems(tilesets.value("secondary")); ui->comboBox_NewMap_Secondary_Tileset->addItems(tilesets.value("secondary"));

View file

@ -0,0 +1,40 @@
#include "newtilesetdialog.h"
#include "ui_newtilesetdialog.h"
#include <QFileDialog>
#include "project.h"
NewTilesetDialog::NewTilesetDialog(Project* project, QWidget *parent) :
QDialog(parent),
ui(new Ui::NewTilesetDialog)
{
ui->setupUi(this);
this->setFixedSize(this->width(), this->height());
this->project = project;
//only allow characters valid for a symbol
QRegExp expression("[-_.A-Za-z0-9]+$");
QRegExpValidator *validator = new QRegExpValidator(expression);
this->ui->nameLineEdit->setValidator(validator);
connect(this->ui->nameLineEdit, &QLineEdit::textChanged, this, &NewTilesetDialog::NameOrSecondaryChanged);
connect(this->ui->typeComboBox, &QComboBox::currentTextChanged, this, &NewTilesetDialog::SecondaryChanged);
//connect(this->ui->toolButton, &QToolButton::clicked, this, &NewTilesetDialog::ChangeFilePath);
this->SecondaryChanged();
}
NewTilesetDialog::~NewTilesetDialog()
{
delete ui;
}
void NewTilesetDialog::SecondaryChanged(){
this->isSecondary = (this->ui->typeComboBox->currentIndex() == 1);
NameOrSecondaryChanged();
}
void NewTilesetDialog::NameOrSecondaryChanged() {
this->friendlyName = this->ui->nameLineEdit->text();
this->fullSymbolName = "gTileset_" + this->friendlyName;
this->ui->symbolNameLineEdit->setText(this->fullSymbolName);
this->path = QString("/data/tilesets/") + (this->isSecondary ? "secondary/" : "primary/") + this->friendlyName.toLower();
this->ui->pathLineEdit->setText(this->path);
}

View file

@ -253,6 +253,8 @@ void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int
if (width == 1 && height == 1) { if (width == 1 && height == 1) {
this->tileSelector->select(static_cast<uint16_t>(tiles[0].tile)); this->tileSelector->select(static_cast<uint16_t>(tiles[0].tile));
ui->spinBox_paletteSelector->setValue(tiles[0].palette); ui->spinBox_paletteSelector->setValue(tiles[0].palette);
ui->checkBox_xFlip->setChecked(tiles[0].xflip);
ui->checkBox_yFlip->setChecked(tiles[0].yflip);
QPoint pos = tileSelector->getTileCoordsOnWidget(static_cast<uint16_t>(tiles[0].tile)); QPoint pos = tileSelector->getTileCoordsOnWidget(static_cast<uint16_t>(tiles[0].tile));
ui->scrollArea_Tiles->ensureVisible(pos.x(), pos.y()); ui->scrollArea_Tiles->ensureVisible(pos.x(), pos.y());
} }