Implement proper triple metatile layer support.

This commit is contained in:
ultima-soul 2020-06-24 22:32:42 -07:00 committed by huderlem
parent b58ec89854
commit debb1c66ac
9 changed files with 115 additions and 49 deletions

View file

@ -233,23 +233,23 @@
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QTabBar" name="mainTabBar" native="true"/>
</item>
<item>
<spacer name="horizontalSpacer_20">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
<item>
<widget class="QTabBar" name="mainTabBar" native="true"/>
</item>
<item>
<spacer name="horizontalSpacer_20">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QStackedWidget" name="mainStackedWidget">
@ -362,8 +362,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>543</width>
<height>600</height>
<width>508</width>
<height>665</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_8">
@ -890,8 +890,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>443</width>
<height>74</height>
<width>442</width>
<height>77</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
@ -1078,10 +1078,10 @@
</property>
<property name="geometry">
<rect>
<x>8</x>
<x>0</x>
<y>0</y>
<width>431</width>
<height>341</height>
<width>425</width>
<height>419</height>
</rect>
</property>
<property name="sizePolicy">
@ -1496,8 +1496,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>521</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
@ -1541,8 +1541,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>521</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
@ -1586,8 +1586,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>521</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
@ -1631,8 +1631,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>521</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
@ -1676,8 +1676,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>521</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
@ -1727,8 +1727,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>521</height>
<width>98</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
@ -2428,8 +2428,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>118</width>
<height>118</height>
<width>101</width>
<height>101</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_14">
@ -2690,7 +2690,7 @@
<x>0</x>
<y>0</y>
<width>1287</width>
<height>22</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -2755,6 +2755,7 @@
<addaction name="actionUse_Encounter_Json"/>
<addaction name="actionMonitor_Project_Files"/>
<addaction name="actionUse_Poryscript"/>
<addaction name="actionUse_Triple_Layer_Metatiles"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
@ -3028,6 +3029,14 @@
<string>Export Map Stitch Image...</string>
</property>
</action>
<action name="actionUse_Triple_Layer_Metatiles">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Use Triple Layer Metatiles</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@ -3040,6 +3049,7 @@
<class>AdjustingStackedWidget</class>
<extends>QStackedWidget</extends>
<header>adjustingstackedwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GraphicsView</class>

View file

@ -122,6 +122,7 @@ public:
this->enableHealLocationRespawnData = false;
this->enableObjectEventInConnection = false;
this->enableFloorNumber = false;
this->enableTripleLayerMetatiles = false;
this->customScripts.clear();
this->readKeys.clear();
}
@ -149,6 +150,8 @@ public:
bool getObjectEventInConnectionEnabled();
void setFloorNumberEnabled(bool enable);
bool getFloorNumberEnabled();
void setTripleLayerMetatilesEnabled(bool enable);
bool getTripleLayerMetatilesEnabled();
void setCustomScripts(QList<QString> scripts);
QList<QString> getCustomScripts();
protected:
@ -170,6 +173,7 @@ private:
bool enableHealLocationRespawnData;
bool enableObjectEventInConnection;
bool enableFloorNumber;
bool enableTripleLayerMetatiles;
QList<QString> customScripts;
QStringList readKeys;
};

View file

@ -148,6 +148,7 @@ private slots:
void on_actionUse_Encounter_Json_triggered(bool checked);
void on_actionMonitor_Project_Files_triggered(bool checked);
void on_actionUse_Poryscript_triggered(bool checked);
void on_actionUse_Triple_Layer_Metatiles_triggered(bool checked);
void on_mainTabBar_tabBarClicked(int index);

View file

@ -423,6 +423,12 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
if (!ok) {
logWarn(QString("Invalid config value for enable_floor_number: '%1'. Must be 0 or 1.").arg(value));
}
} else if (key == "enable_triple_layer_metatiles") {
bool ok;
this->enableTripleLayerMetatiles = value.toInt(&ok);
if (!ok) {
logWarn(QString("Invalid config value for enable_triple_layer_metatiles: '%1'. Must be 0 or 1.").arg(value));
}
} else if (key == "custom_scripts") {
this->customScripts.clear();
QList<QString> paths = value.split(",");
@ -464,6 +470,7 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
map.insert("enable_heal_location_respawn_data", QString::number(this->enableHealLocationRespawnData));
map.insert("enable_object_event_in_connection", QString::number(this->enableObjectEventInConnection));
map.insert("enable_floor_number", QString::number(this->enableFloorNumber));
map.insert("enable_triple_layer_metatiles", QString::number(this->enableTripleLayerMetatiles));
map.insert("custom_scripts", this->customScripts.join(","));
return map;
}
@ -505,6 +512,7 @@ void ProjectConfig::onNewConfigFileCreated() {
this->enableFloorNumber = isPokefirered;
this->useEncounterJson = true;
this->usePoryScript = false;
this->enableTripleLayerMetatiles = false;
this->customScripts.clear();
}
@ -615,6 +623,15 @@ bool ProjectConfig::getFloorNumberEnabled() {
return this->enableFloorNumber;
}
void ProjectConfig::setTripleLayerMetatilesEnabled(bool enable) {
this->enableTripleLayerMetatiles = enable;
this->save();
}
bool ProjectConfig::getTripleLayerMetatilesEnabled() {
return this->enableTripleLayerMetatiles;
}
void ProjectConfig::setCustomScripts(QList<QString> scripts) {
this->customScripts = scripts;
this->save();

View file

@ -165,6 +165,7 @@ void MainWindow::setProjectSpecificUIVisibility()
{
ui->actionUse_Encounter_Json->setChecked(projectConfig.getEncounterJsonActive());
ui->actionUse_Poryscript->setChecked(projectConfig.getUsePoryScript());
ui->actionUse_Triple_Layer_Metatiles->setChecked(projectConfig.getTripleLayerMetatilesEnabled());
ui->mainTabBar->setTabEnabled(4, projectConfig.getEncounterJsonActive());
@ -1328,6 +1329,15 @@ void MainWindow::on_actionUse_Poryscript_triggered(bool checked)
projectConfig.setUsePoryScript(checked);
}
void MainWindow::on_actionUse_Triple_Layer_Metatiles_triggered(bool checked)
{
QMessageBox warning(this);
warning.setText("You must reload the project for this setting to take effect.");
warning.setIcon(QMessageBox::Information);
warning.exec();
projectConfig.setTripleLayerMetatilesEnabled(checked);
}
void MainWindow::on_actionPencil_triggered()
{
on_toolButton_Paint_clicked();

View file

@ -1088,7 +1088,8 @@ void Project::saveTilesetMetatiles(Tileset *tileset) {
if (metatiles_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QByteArray data;
for (Metatile *metatile : *tileset->metatiles) {
for (int i = 0; i < 8; i++) {
int numTiles = projectConfig.getTripleLayerMetatilesEnabled() ? 12 : 8;
for (int i = 0; i < numTiles; i++) {
Tile tile = metatile->tiles->at(i);
uint16_t value = static_cast<uint16_t>((tile.tile & 0x3ff)
| ((tile.xflip & 1) << 10)
@ -1602,8 +1603,9 @@ void Project::loadTilesetMetatiles(Tileset* tileset) {
QFile metatiles_file(tileset->metatiles_path);
if (metatiles_file.open(QIODevice::ReadOnly)) {
QByteArray data = metatiles_file.readAll();
int num_metatiles = data.length() / 16;
int num_layers = 2;
int metatile_data_length = projectConfig.getTripleLayerMetatilesEnabled() ? 24 : 16;
int num_metatiles = data.length() / metatile_data_length;
int num_layers = projectConfig.getTripleLayerMetatilesEnabled() ? 3 : 2;
QList<Metatile*> *metatiles = new QList<Metatile*>;
for (int i = 0; i < num_metatiles; i++) {
Metatile *metatile = new Metatile;

View file

@ -1,3 +1,4 @@
#include "config.h"
#include "imageproviders.h"
#include "log.h"
#include <QPainter>
@ -30,7 +31,9 @@ QImage getMetatileImage(uint16_t tile, Tileset *primaryTileset, Tileset *seconda
QList<QList<QRgb>> palettes = Tileset::getBlockPalettes(primaryTileset, secondaryTileset, useTruePalettes);
QPainter metatile_painter(&metatile_image);
for (int layer = 0; layer < 2; layer++)
bool isTripleLayerMetatile = projectConfig.getTripleLayerMetatilesEnabled();
int numLayers = isTripleLayerMetatile ? 3: 2;
for (int layer = 0; layer < numLayers; layer++)
for (int y = 0; y < 2; y++)
for (int x = 0; x < 2; x++) {
Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));

View file

@ -1,3 +1,4 @@
#include "config.h"
#include "metatilelayersitem.h"
#include "imageproviders.h"
#include <QPainter>
@ -12,11 +13,18 @@ void MetatileLayersItem::draw() {
QPoint(48, 0),
QPoint(32, 16),
QPoint(48, 16),
QPoint(64, 0),
QPoint(80, 0),
QPoint(64, 16),
QPoint(80, 16),
};
QPixmap pixmap(64, 32);
bool isTripleLayerMetatile = projectConfig.getTripleLayerMetatilesEnabled();
int width = isTripleLayerMetatile ? 96 : 64;
QPixmap pixmap(width, 32);
QPainter painter(&pixmap);
for (int i = 0; i < 8; i++) {
int numTiles = isTripleLayerMetatile ? 12 : 8;
for (int i = 0; i < numTiles; i++) {
Tile tile = this->metatile->tiles->at(i);
QImage tileImage = getPalettedTileImage(tile.tile, this->primaryTileset, this->secondaryTileset, tile.palette, true)
.mirrored(tile.xflip, tile.yflip)
@ -92,10 +100,12 @@ void MetatileLayersItem::clearLastModifiedCoords() {
}
void MetatileLayersItem::getBoundedCoords(QPointF pos, int *x, int *y) {
bool isTripleLayerMetatile = projectConfig.getTripleLayerMetatilesEnabled();
int maxX = isTripleLayerMetatile ? 5 : 3;
*x = static_cast<int>(pos.x()) / 16;
*y = static_cast<int>(pos.y()) / 16;
if (*x < 0) *x = 0;
if (*y < 0) *y = 0;
if (*x > 3) *x = 3;
if (*x > maxX) *x = maxX;
if (*y > 1) *y = 1;
}

View file

@ -223,6 +223,7 @@ void TilesetEditor::onSelectedMetatileChanged(uint16_t metatileId) {
this->metatile = Tileset::getMetatile(metatileId, this->primaryTileset, this->secondaryTileset);
this->metatileLayersItem->setMetatile(metatile);
this->metatileLayersItem->draw();
this->ui->graphicsView_metatileLayers->setFixedSize(this->metatileLayersItem->pixmap().width() + 2, this->metatileLayersItem->pixmap().height() + 2);
this->ui->comboBox_metatileBehaviors->setCurrentIndex(this->ui->comboBox_metatileBehaviors->findData(this->metatile->behavior));
this->ui->lineEdit_metatileLabel->setText(this->metatile->label);
this->ui->comboBox_layerType->setCurrentIndex(this->ui->comboBox_layerType->findData(this->metatile->layerType));
@ -255,16 +256,22 @@ void TilesetEditor::onMetatileLayerTileChanged(int x, int y) {
QPoint(2, 0),
QPoint(3, 0),
QPoint(2, 1),
QPoint(3, 1)
QPoint(3, 1),
QPoint(4, 0),
QPoint(5, 0),
QPoint(4, 1),
QPoint(5, 1),
};
Metatile *prevMetatile = this->metatile->copy();
QPoint dimensions = this->tileSelector->getSelectionDimensions();
QList<Tile> tiles = this->tileSelector->getSelectedTiles();
int selectedTileIndex = 0;
bool isTripleLayerMetatile = projectConfig.getTripleLayerMetatilesEnabled();
int maxTileIndex = isTripleLayerMetatile ? 12: 8;
for (int j = 0; j < dimensions.y(); j++) {
for (int i = 0; i < dimensions.x(); i++) {
int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2);
if (tileIndex < 8
if (tileIndex < maxTileIndex
&& tileCoords.at(tileIndex).x() >= x
&& tileCoords.at(tileIndex).y() >= y){
Tile *tile = &(*this->metatile->tiles)[tileIndex];
@ -289,10 +296,12 @@ void TilesetEditor::onMetatileLayerSelectionChanged(QPoint selectionOrigin, int
QList<Tile> tiles;
int x = selectionOrigin.x();
int y = selectionOrigin.y();
bool isTripleLayerMetatile = projectConfig.getTripleLayerMetatilesEnabled();
int maxTileIndex = isTripleLayerMetatile ? 12: 8;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
int tileIndex = ((x + i) / 2 * 4) + ((y + j) * 2) + ((x + i) % 2);
if (tileIndex < 8) {
if (tileIndex < maxTileIndex) {
tiles.append(this->metatile->tiles->at(tileIndex));
}
}