From 5bd88e6fef9c8ba784601744f8ea0c319d1ef5a0 Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Sat, 7 Jul 2018 17:32:54 -0500 Subject: [PATCH] Add ability to change map border --- editor.cpp | 51 +++++++++++++++++++++++ editor.h | 20 +++++++++ mainwindow.cpp | 3 ++ mainwindow.ui | 98 ++++++++++++++++++++++++++++++++++++++++---- map.cpp | 107 ++----------------------------------------------- map.h | 7 ---- metatile.cpp | 6 --- metatile.h | 16 -------- pretmap.pro | 2 - project.cpp | 1 - tileset.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ tileset.h | 20 ++++++++- 12 files changed, 294 insertions(+), 143 deletions(-) delete mode 100755 metatile.cpp delete mode 100755 metatile.h diff --git a/editor.cpp b/editor.cpp index cd8f9d37..e29bb667 100755 --- a/editor.cpp +++ b/editor.cpp @@ -301,6 +301,10 @@ void Editor::onConnectionDirectionChanged(QString newDirection) { ui->comboBox_ConnectionDirection->blockSignals(false); } +void Editor::onBorderMetatilesChanged() { + displayMapBorder(); +} + void Editor::setConnectionsVisibility(bool visible) { for (QGraphicsPixmapItem* item : map->connection_items) { item->setVisible(visible); @@ -383,6 +387,7 @@ void Editor::displayMap() { ); displayMetatiles(); + displayBorderMetatiles(); displayCollisionMetatiles(); displayElevationMetatiles(); displayMapEvents(); @@ -398,6 +403,15 @@ void Editor::displayMetatiles() { scene_metatiles->addItem(metatiles_item); } +void Editor::displayBorderMetatiles() { + scene_selected_border_metatiles = new QGraphicsScene; + selected_border_metatiles_item = new BorderMetatilesPixmapItem(map); + selected_border_metatiles_item->draw(); + scene_selected_border_metatiles->addItem(selected_border_metatiles_item); + + connect(selected_border_metatiles_item, SIGNAL(borderMetatilesChanged()), this, SLOT(onBorderMetatilesChanged())); +} + void Editor::displayCollisionMetatiles() { scene_collision_metatiles = new QGraphicsScene; collision_metatiles_item = new CollisionMetatilesPixmapItem(map); @@ -792,6 +806,43 @@ void MetatilesPixmapItem::updateSelection(QPointF pos, Qt::MouseButton button) { } } +void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { + QPointF pos = event->pos(); + int x = ((int)pos.x()) / 16; + int y = ((int)pos.y()) / 16; + + for (int i = 0; i < map->paint_tile_width && (i + x) < 2; i++) { + for (int j = 0; j < map->paint_tile_height && (j + y) < 2; j++) { + int blockIndex = (j + y) * 2 + (i + x); + int tile = map->getSelectedBlockIndex(map->paint_tile_index + i + (j * 8)); + (*map->layout->border->blocks)[blockIndex].tile = tile; + } + } + + draw(); + emit borderMetatilesChanged(); +} + +void BorderMetatilesPixmapItem::draw() { + QImage image(32, 32, QImage::Format_RGBA8888); + QPainter painter(&image); + QList *blocks = map->layout->border->blocks; + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + { + int x = i * 16; + int y = j * 16; + int index = j * 2 + i; + QImage metatile_image = Metatile::getMetatileImage(blocks->value(index).tile, map->layout->tileset_primary, map->layout->tileset_secondary); + QPoint metatile_origin = QPoint(x, y); + painter.drawImage(metatile_origin, metatile_image); + } + + painter.end(); + setPixmap(QPixmap::fromImage(image)); +} + void MovementPermissionsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent* event) { QPointF pos = event->pos(); int x = ((int)pos.x()) / 16; diff --git a/editor.h b/editor.h index 7564e196..d2ec601b 100755 --- a/editor.h +++ b/editor.h @@ -16,6 +16,7 @@ class MapPixmapItem; class CollisionPixmapItem; class ConnectionPixmapItem; class MetatilesPixmapItem; +class BorderMetatilesPixmapItem; class CollisionMetatilesPixmapItem; class ElevationMetatilesPixmapItem; @@ -36,6 +37,7 @@ public: void setMap(QString map_name); void displayMap(); void displayMetatiles(); + void displayBorderMetatiles(); void displayCollisionMetatiles(); void displayElevationMetatiles(); void displayMapEvents(); @@ -78,9 +80,11 @@ public: QList borderItems; QGraphicsScene *scene_metatiles = NULL; + QGraphicsScene *scene_selected_border_metatiles = NULL; QGraphicsScene *scene_collision_metatiles = NULL; QGraphicsScene *scene_elevation_metatiles = NULL; MetatilesPixmapItem *metatiles_item = NULL; + BorderMetatilesPixmapItem *selected_border_metatiles_item = NULL; CollisionMetatilesPixmapItem *collision_metatiles_item = NULL; ElevationMetatilesPixmapItem *elevation_metatiles_item = NULL; @@ -123,6 +127,7 @@ private slots: void onConnectionItemSelected(ConnectionPixmapItem* connectionItem); void onConnectionItemDoubleClicked(ConnectionPixmapItem* connectionItem); void onConnectionDirectionChanged(QString newDirection); + void onBorderMetatilesChanged(); signals: void objectsChanged(); @@ -351,6 +356,21 @@ protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent*); }; +class BorderMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem { + Q_OBJECT +public: + BorderMetatilesPixmapItem(Map *map_) { + map = map_; + setAcceptHoverEvents(true); + } + Map* map = NULL; + virtual void draw(); +signals: + void borderMetatilesChanged(); +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); +}; + class MovementPermissionsPixmapItem : public MetatilesPixmapItem { Q_OBJECT public: diff --git a/mainwindow.cpp b/mainwindow.cpp index 58f0e684..ea3a571c 100755 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -166,6 +166,9 @@ void MainWindow::setMap(QString map_name) { //ui->graphicsView_Metatiles->setSceneRect(editor->scene_metatiles->sceneRect()); ui->graphicsView_Metatiles->setFixedSize(editor->metatiles_item->pixmap().width() + 2, editor->metatiles_item->pixmap().height() + 2); + ui->graphicsView_BorderMetatile->setScene(editor->scene_selected_border_metatiles); + ui->graphicsView_BorderMetatile->setFixedSize(editor->selected_border_metatiles_item->pixmap().width() + 2, editor->selected_border_metatiles_item->pixmap().height() + 2); + ui->graphicsView_Collision->setScene(editor->scene_collision_metatiles); //ui->graphicsView_Collision->setSceneRect(editor->scene_collision_metatiles->sceneRect()); ui->graphicsView_Collision->setFixedSize(editor->collision_metatiles_item->pixmap().width() + 2, editor->collision_metatiles_item->pixmap().height() + 2); diff --git a/mainwindow.ui b/mainwindow.ui index 9fc8cb5a..8714f10d 100755 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -60,7 +60,7 @@ - 1 + 0 false @@ -290,7 +290,7 @@ 0 0 - 614 + 475 621 @@ -478,8 +478,8 @@ 0 0 - 180 - 629 + 358 + 612 @@ -488,7 +488,10 @@ 0 - + + + QLayout::SetDefaultConstraint + 0 @@ -501,16 +504,97 @@ 0 - + 0 + + 8 + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + Border + + + + + + + + 0 + 0 + + + + + 16777215 + 48 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + Qt::ScrollBarAsNeeded + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + true - + 0 0 diff --git a/map.cpp b/map.cpp index 6cacb134..2c1189c3 100755 --- a/map.cpp +++ b/map.cpp @@ -59,35 +59,6 @@ int Map::getHeight() { return layout->height.toInt(nullptr, 0); } -Tileset* Map::getBlockTileset(int metatile_index) { - int primary_size = 0x200; - if (metatile_index < primary_size) { - return layout->tileset_primary; - } else { - return layout->tileset_secondary; - } -} - -QList> Map::getBlockPalettes(int metatile_index) { - QList> palettes; - for (int i = 0; i < 6; i++) { - palettes.append(layout->tileset_primary->palettes->at(i)); - } - for (int i = 6; i < layout->tileset_secondary->palettes->length(); i++) { - palettes.append(layout->tileset_secondary->palettes->at(i)); - } - return palettes; -} - -int Map::getBlockIndex(int index) { - int primary_size = 0x200; - if (index < primary_size) { - return index; - } else { - return index - primary_size; - } -} - int Map::getSelectedBlockIndex(int index) { if (index < layout->tileset_primary->metatiles->length()) { return index; @@ -104,25 +75,6 @@ int Map::getDisplayedBlockIndex(int index) { } } -QImage Map::getMetatileTile(int tile) { - Tileset *tileset = getBlockTileset(tile); - int local_index = getBlockIndex(tile); - if (!tileset || !tileset->tiles) { - return QImage(); - } - return tileset->tiles->value(local_index, QImage()); -} - -Metatile* Map::getMetatile(int index) { - Tileset *tileset = getBlockTileset(index); - int local_index = getBlockIndex(index); - if (!tileset || !tileset->metatiles) { - return NULL; - } - Metatile *metatile = tileset->metatiles->value(local_index, NULL); - return metatile; -} - QImage Map::getCollisionMetatileImage(Block block) { return getCollisionMetatileImage(block.collision); } @@ -166,57 +118,6 @@ QImage Map::getElevationMetatileImage(int elevation) { return metatile_image; } -QImage Map::getMetatileImage(int tile) { - - QImage metatile_image(16, 16, QImage::Format_RGBA8888); - - Metatile* metatile = getMetatile(tile); - if (!metatile || !metatile->tiles) { - metatile_image.fill(0xffffffff); - return metatile_image; - } - - Tileset* blockTileset = getBlockTileset(tile); - if (!blockTileset) { - metatile_image.fill(0xffffffff); - return metatile_image; - } - QList> palettes = getBlockPalettes(tile); - - QPainter metatile_painter(&metatile_image); - for (int layer = 0; layer < 2; 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)); - QImage tile_image = getMetatileTile(tile_.tile); - if (tile_image.isNull()) { - // Some metatiles specify tiles that are outside the valid range. - // These are treated as completely transparent, so they can be skipped without - // being drawn. - continue; - } - - // Colorize the metatile tiles with its palette. - QList palette = palettes.value(tile_.palette); - for (int j = 0; j < palette.length(); j++) { - tile_image.setColor(j, palette.value(j)); - } - - // The top layer of the metatile has its last color displayed at transparent. - if (layer > 0) { - QColor color(tile_image.color(15)); - color.setAlpha(0); - tile_image.setColor(15, color.rgba()); - } - - QPoint origin = QPoint(x*8, y*8); - metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1)); - } - metatile_painter.end(); - - return metatile_image; -} - bool Map::blockChanged(int i, Blockdata *cache) { if (cache == NULL || cache == nullptr) { return true; @@ -295,7 +196,7 @@ QPixmap Map::renderCollision(bool ignoreCache) { } changed_any = true; Block block = layout->blockdata->blocks->value(i); - QImage metatile_image = getMetatileImage(block.tile); + QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary); QImage collision_metatile_image = getCollisionMetatileImage(block); QImage elevation_metatile_image = getElevationMetatileImage(block); int map_y = width_ ? i / width_ : 0; @@ -364,7 +265,7 @@ QPixmap Map::render(bool ignoreCache = false) { } changed_any = true; Block block = layout->blockdata->blocks->value(i); - QImage metatile_image = getMetatileImage(block.tile); + QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary); int map_y = width_ ? i / width_ : 0; int map_x = width_ ? i % width_ : 0; QPoint metatile_origin = QPoint(map_x * 16, map_y * 16); @@ -397,7 +298,7 @@ QPixmap Map::renderBorder() { } changed_any = true; Block block = layout->border->blocks->value(i); - QImage metatile_image = getMetatileImage(block.tile); + QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary); int map_y = i / width_; int map_x = i % width_; painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image); @@ -513,7 +414,7 @@ QPixmap Map::renderMetatiles() { if (i >= primary_length) { tile += 0x200 - primary_length; } - QImage metatile_image = getMetatileImage(tile); + QImage metatile_image = Metatile::getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary); int map_y = i / width_; int map_x = i % width_; QPoint metatile_origin = QPoint(map_x * 16, map_y * 16); diff --git a/map.h b/map.h index ad935ade..43f57e06 100755 --- a/map.h +++ b/map.h @@ -135,13 +135,8 @@ public: static QString bgEventsLabelFromName(QString mapName); int getWidth(); int getHeight(); - Tileset* getBlockTileset(int); - int getBlockIndex(int); int getSelectedBlockIndex(int); int getDisplayedBlockIndex(int); - Metatile* getMetatile(int); - QImage getMetatileImage(int); - QImage getMetatileTile(int); QPixmap render(bool ignoreCache); QPixmap renderMetatiles(); @@ -214,8 +209,6 @@ public: void hoveredElevationTileChanged(int elevation); void clearHoveredElevationTile(); - QList > getBlockPalettes(int metatile_index); - signals: void paintTileChanged(Map *map); void paintCollisionChanged(Map *map); diff --git a/metatile.cpp b/metatile.cpp deleted file mode 100755 index 93d435fa..00000000 --- a/metatile.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "metatile.h" - -Metatile::Metatile() -{ - tiles = new QList; -} diff --git a/metatile.h b/metatile.h deleted file mode 100755 index 2712602d..00000000 --- a/metatile.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef METATILE_H -#define METATILE_H - -#include "tile.h" -#include - -class Metatile -{ -public: - Metatile(); -public: - QList *tiles = NULL; - int attr; -}; - -#endif // METATILE_H diff --git a/pretmap.pro b/pretmap.pro index 387e2627..5e722c11 100755 --- a/pretmap.pro +++ b/pretmap.pro @@ -19,7 +19,6 @@ SOURCES += main.cpp\ blockdata.cpp \ block.cpp \ tileset.cpp \ - metatile.cpp \ tile.cpp \ event.cpp \ editor.cpp \ @@ -34,7 +33,6 @@ HEADERS += mainwindow.h \ blockdata.h \ block.h \ tileset.h \ - metatile.h \ tile.h \ event.h \ editor.h \ diff --git a/project.cpp b/project.cpp index 5d8843c3..5422e0a2 100755 --- a/project.cpp +++ b/project.cpp @@ -2,7 +2,6 @@ #include "project.h" #include "tile.h" #include "tileset.h" -#include "metatile.h" #include "event.h" #include diff --git a/tileset.cpp b/tileset.cpp index cb781cc6..4fac3f4f 100755 --- a/tileset.cpp +++ b/tileset.cpp @@ -1,6 +1,112 @@ #include "tileset.h" +#include +#include + Tileset::Tileset() { } + +Metatile::Metatile() +{ + tiles = new QList; +} + +QImage Metatile::getMetatileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) { + QImage metatile_image(16, 16, QImage::Format_RGBA8888); + + Metatile* metatile = Metatile::getMetatile(tile, primaryTileset, secondaryTileset); + if (!metatile || !metatile->tiles) { + metatile_image.fill(0xffffffff); + return metatile_image; + } + + Tileset* blockTileset = Metatile::getBlockTileset(tile, primaryTileset, secondaryTileset); + if (!blockTileset) { + metatile_image.fill(0xffffffff); + return metatile_image; + } + QList> palettes = Metatile::getBlockPalettes(primaryTileset, secondaryTileset); + + QPainter metatile_painter(&metatile_image); + for (int layer = 0; layer < 2; 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)); + QImage tile_image = Metatile::getMetatileTile(tile_.tile, primaryTileset, secondaryTileset); + if (tile_image.isNull()) { + // Some metatiles specify tiles that are outside the valid range. + // These are treated as completely transparent, so they can be skipped without + // being drawn. + continue; + } + + // Colorize the metatile tiles with its palette. + QList palette = palettes.value(tile_.palette); + for (int j = 0; j < palette.length(); j++) { + tile_image.setColor(j, palette.value(j)); + } + + // The top layer of the metatile has its last color displayed at transparent. + if (layer > 0) { + QColor color(tile_image.color(15)); + color.setAlpha(0); + tile_image.setColor(15, color.rgba()); + } + + QPoint origin = QPoint(x*8, y*8); + metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1)); + } + metatile_painter.end(); + + return metatile_image; +} + +Metatile* Metatile::getMetatile(int index, Tileset *primaryTileset, Tileset *secondaryTileset) { + Tileset *tileset = Metatile::getBlockTileset(index, primaryTileset, secondaryTileset); + int local_index = Metatile::getBlockIndex(index); + if (!tileset || !tileset->metatiles) { + return NULL; + } + Metatile *metatile = tileset->metatiles->value(local_index, NULL); + return metatile; +} + +QImage Metatile::getMetatileTile(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) { + Tileset *tileset = Metatile::getBlockTileset(tile, primaryTileset, secondaryTileset); + int local_index = Metatile::getBlockIndex(tile); + if (!tileset || !tileset->tiles) { + return QImage(); + } + return tileset->tiles->value(local_index, QImage()); +} + +Tileset* Metatile::getBlockTileset(int metatile_index, Tileset *primaryTileset, Tileset *secondaryTileset) { + int primary_size = 0x200; + if (metatile_index < primary_size) { + return primaryTileset; + } else { + return secondaryTileset; + } +} + +int Metatile::getBlockIndex(int index) { + int primary_size = 0x200; + if (index < primary_size) { + return index; + } else { + return index - primary_size; + } +} + +QList> Metatile::getBlockPalettes(Tileset *primaryTileset, Tileset *secondaryTileset) { + QList> palettes; + for (int i = 0; i < 6; i++) { + palettes.append(primaryTileset->palettes->at(i)); + } + for (int i = 6; i < secondaryTileset->palettes->length(); i++) { + palettes.append(secondaryTileset->palettes->at(i)); + } + return palettes; +} diff --git a/tileset.h b/tileset.h index 78d7b856..f831857b 100755 --- a/tileset.h +++ b/tileset.h @@ -1,9 +1,11 @@ #ifndef TILESET_H #define TILESET_H -#include "metatile.h" +#include "tile.h" #include +class Metatile; + class Tileset { public: @@ -24,4 +26,20 @@ public: QList> *palettes = NULL; }; +class Metatile +{ +public: + Metatile(); +public: + QList *tiles = NULL; + int attr; + + static QImage getMetatileImage(int, Tileset*, Tileset*); + static Metatile* getMetatile(int, Tileset*, Tileset*); + static QImage getMetatileTile(int, Tileset*, Tileset*); + static Tileset* getBlockTileset(int, Tileset*, Tileset*); + static int getBlockIndex(int); + static QList> getBlockPalettes(Tileset*, Tileset*); +}; + #endif // TILESET_H