diff --git a/block.cpp b/core/block.cpp old mode 100755 new mode 100644 similarity index 93% rename from block.cpp rename to core/block.cpp index ceff25da..27747f00 --- a/block.cpp +++ b/core/block.cpp @@ -1,32 +1,32 @@ -#include "block.h" - -Block::Block() { -} - -Block::Block(uint16_t word) -{ - tile = word & 0x3ff; - collision = (word >> 10) & 0x3; - elevation = (word >> 12) & 0xf; -} - -Block::Block(const Block &block) { - tile = block.tile; - collision = block.collision; - elevation = block.elevation; -} - -uint16_t Block::rawValue() { - return static_cast( - (tile & 0x3ff) + - ((collision & 0x3) << 10) + - ((elevation & 0xf) << 12)); -} - -bool Block::operator ==(Block other) { - return (tile == other.tile) && (collision == other.collision) && (elevation == other.elevation); -} - -bool Block::operator !=(Block other) { - return !(operator ==(other)); -} +#include "core/block.h" + +Block::Block() { +} + +Block::Block(uint16_t word) +{ + tile = word & 0x3ff; + collision = (word >> 10) & 0x3; + elevation = (word >> 12) & 0xf; +} + +Block::Block(const Block &block) { + tile = block.tile; + collision = block.collision; + elevation = block.elevation; +} + +uint16_t Block::rawValue() { + return static_cast( + (tile & 0x3ff) + + ((collision & 0x3) << 10) + + ((elevation & 0xf) << 12)); +} + +bool Block::operator ==(Block other) { + return (tile == other.tile) && (collision == other.collision) && (elevation == other.elevation); +} + +bool Block::operator !=(Block other) { + return !(operator ==(other)); +} diff --git a/block.h b/core/block.h old mode 100755 new mode 100644 similarity index 93% rename from block.h rename to core/block.h index 8b3943d5..b31f18b4 --- a/block.h +++ b/core/block.h @@ -1,20 +1,20 @@ -#ifndef BLOCK_H -#define BLOCK_H - -#include - -class Block -{ -public: - Block(); - Block(uint16_t); - Block(const Block&); - bool operator ==(Block); - bool operator !=(Block); - uint16_t tile:10; - uint16_t collision:2; - uint16_t elevation:4; - uint16_t rawValue(); -}; - -#endif // BLOCK_H +#ifndef BLOCK_H +#define BLOCK_H + +#include + +class Block +{ +public: + Block(); + Block(uint16_t); + Block(const Block&); + bool operator ==(Block); + bool operator !=(Block); + uint16_t tile:10; + uint16_t collision:2; + uint16_t elevation:4; + uint16_t rawValue(); +}; + +#endif // BLOCK_H diff --git a/blockdata.cpp b/core/blockdata.cpp old mode 100755 new mode 100644 similarity index 92% rename from blockdata.cpp rename to core/blockdata.cpp index 10901741..e9285201 --- a/blockdata.cpp +++ b/core/blockdata.cpp @@ -1,55 +1,54 @@ -#include "blockdata.h" -#include - -Blockdata::Blockdata(QObject *parent) : QObject(parent) -{ - blocks = new QList; -} - -void Blockdata::addBlock(uint16_t word) { - Block block(word); - blocks->append(block); -} - -void Blockdata::addBlock(Block block) { - blocks->append(block); -} - -QByteArray Blockdata::serialize() { - QByteArray data; - for (int i = 0; i < blocks->length(); i++) { - Block block = blocks->value(i); - uint16_t word = block.rawValue(); - data.append(static_cast(word & 0xff)); - data.append(static_cast((word >> 8) & 0xff)); - } - return data; -} - -void Blockdata::copyFrom(Blockdata* other) { - blocks->clear(); - for (int i = 0; i < other->blocks->length(); i++) { - addBlock(other->blocks->value(i)); - } -} - -Blockdata* Blockdata::copy() { - Blockdata* blockdata = new Blockdata; - blockdata->copyFrom(this); - return blockdata; -} - -bool Blockdata::equals(Blockdata *other) { - if (!other) { - return false; - } - if (blocks->length() != other->blocks->length()) { - return false; - } - for (int i = 0; i < blocks->length(); i++) { - if (blocks->value(i) != other->blocks->value(i)) { - return false; - } - } - return true; -} +#include "core/blockdata.h" + +Blockdata::Blockdata(QObject *parent) : QObject(parent) +{ + blocks = new QList; +} + +void Blockdata::addBlock(uint16_t word) { + Block block(word); + blocks->append(block); +} + +void Blockdata::addBlock(Block block) { + blocks->append(block); +} + +QByteArray Blockdata::serialize() { + QByteArray data; + for (int i = 0; i < blocks->length(); i++) { + Block block = blocks->value(i); + uint16_t word = block.rawValue(); + data.append(static_cast(word & 0xff)); + data.append(static_cast((word >> 8) & 0xff)); + } + return data; +} + +void Blockdata::copyFrom(Blockdata* other) { + blocks->clear(); + for (int i = 0; i < other->blocks->length(); i++) { + addBlock(other->blocks->value(i)); + } +} + +Blockdata* Blockdata::copy() { + Blockdata* blockdata = new Blockdata; + blockdata->copyFrom(this); + return blockdata; +} + +bool Blockdata::equals(Blockdata *other) { + if (!other) { + return false; + } + if (blocks->length() != other->blocks->length()) { + return false; + } + for (int i = 0; i < blocks->length(); i++) { + if (blocks->value(i) != other->blocks->value(i)) { + return false; + } + } + return true; +} diff --git a/blockdata.h b/core/blockdata.h old mode 100755 new mode 100644 similarity index 94% rename from blockdata.h rename to core/blockdata.h index 8d87eaa4..0bb6a7b6 --- a/blockdata.h +++ b/core/blockdata.h @@ -1,32 +1,32 @@ -#ifndef BLOCKDATA_H -#define BLOCKDATA_H - -#include "block.h" - -#include -#include - -class Blockdata : public QObject -{ - Q_OBJECT -public: - explicit Blockdata(QObject *parent = nullptr); - ~Blockdata() { - if (blocks) delete blocks; - } - -public: - QList *blocks = nullptr; - void addBlock(uint16_t); - void addBlock(Block); - QByteArray serialize(); - void copyFrom(Blockdata*); - Blockdata* copy(); - bool equals(Blockdata *); - -signals: - -public slots: -}; - -#endif // BLOCKDATA_H +#ifndef BLOCKDATA_H +#define BLOCKDATA_H + +#include "block.h" + +#include +#include + +class Blockdata : public QObject +{ + Q_OBJECT +public: + explicit Blockdata(QObject *parent = nullptr); + ~Blockdata() { + if (blocks) delete blocks; + } + +public: + QList *blocks = nullptr; + void addBlock(uint16_t); + void addBlock(Block); + QByteArray serialize(); + void copyFrom(Blockdata*); + Blockdata* copy(); + bool equals(Blockdata *); + +signals: + +public slots: +}; + +#endif // BLOCKDATA_H diff --git a/heallocation.cpp b/core/heallocation.cpp similarity index 100% rename from heallocation.cpp rename to core/heallocation.cpp diff --git a/heallocation.h b/core/heallocation.h similarity index 100% rename from heallocation.h rename to core/heallocation.h diff --git a/core/metatile.cpp b/core/metatile.cpp new file mode 100644 index 00000000..41ae927f --- /dev/null +++ b/core/metatile.cpp @@ -0,0 +1,16 @@ +#include "core/metatile.h" +#include "project.h" +#include "core/tileset.h" + +Metatile::Metatile() +{ + tiles = new QList; +} + +int Metatile::getBlockIndex(int index) { + if (index < Project::getNumMetatilesPrimary()) { + return index; + } else { + return index - Project::getNumMetatilesPrimary(); + } +} diff --git a/core/metatile.h b/core/metatile.h new file mode 100644 index 00000000..b5cb19d5 --- /dev/null +++ b/core/metatile.h @@ -0,0 +1,17 @@ +#ifndef METATILE_H +#define METATILE_H + +#include "tile.h" +#include + +class Metatile +{ +public: + Metatile(); +public: + QList *tiles = nullptr; + + static int getBlockIndex(int); +}; + +#endif // METATILE_H diff --git a/core/tile.cpp b/core/tile.cpp new file mode 100644 index 00000000..3f404907 --- /dev/null +++ b/core/tile.cpp @@ -0,0 +1,6 @@ +#include "core/tile.h" + +Tile::Tile() +{ + +} diff --git a/tile.h b/core/tile.h old mode 100755 new mode 100644 similarity index 90% rename from tile.h rename to core/tile.h index f511a7cb..d1c231cc --- a/tile.h +++ b/core/tile.h @@ -1,16 +1,16 @@ -#ifndef TILE_H -#define TILE_H - - -class Tile -{ -public: - Tile(); -public: - int tile; - int xflip; - int yflip; - int palette; -}; - -#endif // TILE_H +#ifndef TILE_H +#define TILE_H + + +class Tile +{ +public: + Tile(); +public: + int tile; + int xflip; + int yflip; + int palette; +}; + +#endif // TILE_H diff --git a/tileset.cpp b/core/tileset.cpp old mode 100755 new mode 100644 similarity index 66% rename from tileset.cpp rename to core/tileset.cpp index 55fa6258..608dcb9a --- a/tileset.cpp +++ b/core/tileset.cpp @@ -1,116 +1,104 @@ -#include "tileset.h" -#include "project.h" - -#include -#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. - if (tile_.palette < palettes.length()) { - QList palette = palettes.value(tile_.palette); - for (int j = 0; j < palette.length(); j++) { - tile_image.setColor(j, palette.value(j)); - } - } else { - qDebug() << "Tile is referring to invalid palette number: " << tile_.palette; - } - - // The top layer of the metatile has its first color displayed at transparent. - if (layer > 0) { - QColor color(tile_image.color(0)); - color.setAlpha(0); - tile_image.setColor(0, 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 nullptr; - } - Metatile *metatile = tileset->metatiles->value(local_index, nullptr); - 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) { - if (metatile_index < Project::getNumMetatilesPrimary()) { - return primaryTileset; - } else { - return secondaryTileset; - } -} - -int Metatile::getBlockIndex(int index) { - if (index < Project::getNumMetatilesPrimary()) { - return index; - } else { - return index - Project::getNumMetatilesPrimary(); - } -} - -QList> Metatile::getBlockPalettes(Tileset *primaryTileset, Tileset *secondaryTileset) { - QList> palettes; - for (int i = 0; i < Project::getNumPalettesPrimary(); i++) { - palettes.append(primaryTileset->palettes->at(i)); - } - for (int i = Project::getNumPalettesPrimary(); i < Project::getNumPalettesTotal(); i++) { - palettes.append(secondaryTileset->palettes->at(i)); - } - return palettes; -} +#include "core/tileset.h" +#include "core/metatile.h" +#include "project.h" + +#include +#include +#include + +Tileset::Tileset() +{ + +} + +Tileset* Tileset::getBlockTileset(int metatile_index, Tileset *primaryTileset, Tileset *secondaryTileset) { + if (metatile_index < Project::getNumMetatilesPrimary()) { + return primaryTileset; + } else { + return secondaryTileset; + } +} + +QImage Tileset::getMetatileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) { + QImage metatile_image(16, 16, QImage::Format_RGBA8888); + + Metatile* metatile = Tileset::getMetatile(tile, primaryTileset, secondaryTileset); + if (!metatile || !metatile->tiles) { + metatile_image.fill(0xffffffff); + return metatile_image; + } + + Tileset* blockTileset = Tileset::getBlockTileset(tile, primaryTileset, secondaryTileset); + if (!blockTileset) { + metatile_image.fill(0xffffffff); + return metatile_image; + } + QList> palettes = Tileset::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 = Tileset::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. + if (tile_.palette < palettes.length()) { + QList palette = palettes.value(tile_.palette); + for (int j = 0; j < palette.length(); j++) { + tile_image.setColor(j, palette.value(j)); + } + } else { + qDebug() << "Tile is referring to invalid palette number: " << tile_.palette; + } + + // The top layer of the metatile has its first color displayed at transparent. + if (layer > 0) { + QColor color(tile_image.color(0)); + color.setAlpha(0); + tile_image.setColor(0, 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* Tileset::getMetatile(int index, Tileset *primaryTileset, Tileset *secondaryTileset) { + Tileset *tileset = Tileset::getBlockTileset(index, primaryTileset, secondaryTileset); + int local_index = Metatile::getBlockIndex(index); + if (!tileset || !tileset->metatiles) { + return nullptr; + } + Metatile *metatile = tileset->metatiles->value(local_index, nullptr); + return metatile; +} + +QImage Tileset::getMetatileTile(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) { + Tileset *tileset = Tileset::getBlockTileset(tile, primaryTileset, secondaryTileset); + int local_index = Metatile::getBlockIndex(tile); + if (!tileset || !tileset->tiles) { + return QImage(); + } + return tileset->tiles->value(local_index, QImage()); +} + +QList> Tileset::getBlockPalettes(Tileset *primaryTileset, Tileset *secondaryTileset) { + QList> palettes; + for (int i = 0; i < Project::getNumPalettesPrimary(); i++) { + palettes.append(primaryTileset->palettes->at(i)); + } + for (int i = Project::getNumPalettesPrimary(); i < Project::getNumPalettesTotal(); i++) { + palettes.append(secondaryTileset->palettes->at(i)); + } + return palettes; +} diff --git a/tileset.h b/core/tileset.h old mode 100755 new mode 100644 similarity index 78% rename from tileset.h rename to core/tileset.h index 5cd22daa..ce6233ed --- a/tileset.h +++ b/core/tileset.h @@ -1,45 +1,34 @@ -#ifndef TILESET_H -#define TILESET_H - -#include "tile.h" -#include - -class Metatile; - -class Tileset -{ -public: - Tileset(); -public: - QString name; - QString is_compressed; - QString is_secondary; - QString padding; - QString tiles_label; - QString palettes_label; - QString metatiles_label; - QString callback_label; - QString metatile_attrs_label; - - QList *tiles = nullptr; - QList *metatiles = nullptr; - QList> *palettes = nullptr; -}; - -class Metatile -{ -public: - Metatile(); -public: - QList *tiles = nullptr; - 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 +#ifndef TILESET_H +#define TILESET_H + +#include "core/metatile.h" +#include "core/tile.h" +#include + +class Tileset +{ +public: + Tileset(); +public: + QString name; + QString is_compressed; + QString is_secondary; + QString padding; + QString tiles_label; + QString palettes_label; + QString metatiles_label; + QString callback_label; + QString metatile_attrs_label; + + QList *tiles = nullptr; + QList *metatiles = nullptr; + QList> *palettes = nullptr; + + static Tileset* getBlockTileset(int, Tileset*, Tileset*); + static QImage getMetatileImage(int, Tileset*, Tileset*); + static Metatile* getMetatile(int, Tileset*, Tileset*); + static QImage getMetatileTile(int, Tileset*, Tileset*); + static QList> getBlockPalettes(Tileset*, Tileset*); +}; + +#endif // TILESET_H diff --git a/editor.cpp b/editor.cpp index cc550aaa..66e1a516 100755 --- a/editor.cpp +++ b/editor.cpp @@ -314,6 +314,14 @@ void Editor::onBorderMetatilesChanged() { displayMapBorder(); } +void Editor::onHoveredMovementPermissionChanged(uint16_t collision, uint16_t elevation) { + map->hoveredMovementPermissionTileChanged(collision, elevation); +} + +void Editor::onHoveredMovementPermissionCleared() { + map->clearHoveredMovementPermissionTile(); +} + void Editor::setConnectionsVisibility(bool visible) { for (QGraphicsPixmapItem* item : connection_items) { item->setVisible(visible); @@ -500,15 +508,20 @@ void Editor::redrawCurrentMetatilesSelection() { } void Editor::displayCollisionMetatiles() { - if (collision_metatiles_item && collision_metatiles_item->scene()) { - collision_metatiles_item->scene()->removeItem(collision_metatiles_item); - delete collision_metatiles_item; + if (movement_permissions_selector_item && movement_permissions_selector_item->scene()) { + movement_permissions_selector_item->scene()->removeItem(movement_permissions_selector_item); + delete movement_permissions_selector_item; } scene_collision_metatiles = new QGraphicsScene; - collision_metatiles_item = new MovementPermissionsPixmapItem(map); - collision_metatiles_item->draw(); - scene_collision_metatiles->addItem(collision_metatiles_item); + movement_permissions_selector_item = new MovementPermissionsSelector(); + connect(movement_permissions_selector_item, SIGNAL(hoveredMovementPermissionChanged(uint16_t, uint16_t)), + this, SLOT(onHoveredMovementPermissionChanged(uint16_t, uint16_t))); + connect(movement_permissions_selector_item, SIGNAL(hoveredMovementPermissionCleared()), + this, SLOT(onHoveredMovementPermissionCleared())); + movement_permissions_selector_item->select(0, 3); + movement_permissions_selector_item->draw(); + scene_collision_metatiles->addItem(movement_permissions_selector_item); } void Editor::displayMapEvents() { @@ -975,7 +988,7 @@ void BorderMetatilesPixmapItem::draw() { 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); + QImage metatile_image = Tileset::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); } @@ -996,7 +1009,7 @@ void CurrentSelectedMetatilesPixmapItem::draw() { int x = i * 16; int y = j * 16; int index = j * map->selected_metatiles_width + i; - QImage metatile_image = Metatile::getMetatileImage(map->selected_metatiles->at(index), map->layout->tileset_primary, map->layout->tileset_secondary); + QImage metatile_image = Tileset::getMetatileImage(map->selected_metatiles->at(index), map->layout->tileset_primary, map->layout->tileset_secondary); QPoint metatile_origin = QPoint(x, y); painter.drawImage(metatile_origin, metatile_image); } @@ -1005,42 +1018,6 @@ void CurrentSelectedMetatilesPixmapItem::draw() { setPixmap(QPixmap::fromImage(image)); } -void MovementPermissionsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent* event) { - QPointF pos = event->pos(); - int x = static_cast(pos.x()) / 32; - int y = static_cast(pos.y()) / 32; - int width = pixmap().width() / 32; - int height = pixmap().height() / 32; - - // Snap to a valid position inside the selection area. - if (x < 0) x = 0; - if (x >= width) x = width - 1; - if (y < 0) y = 0; - if (y >= height) y = height - 1; - pick(static_cast(x), static_cast(y)); -} -void MovementPermissionsPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { - updateCurHoveredMetatile(event->pos()); - mousePressEvent(event); -} -void MovementPermissionsPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { - mousePressEvent(event); -} - -void MovementPermissionsPixmapItem::updateCurHoveredMetatile(QPointF pos) { - int x = static_cast(pos.x()) / 32; - int y = static_cast(pos.y()) / 32; - int width = pixmap().width() / 32; - int height = pixmap().height() / 32; - - // Snap to a valid position inside the selection area. - if (x < 0) x = 0; - if (x >= width) x = width - 1; - if (y < 0) y = 0; - if (y >= height) y = height - 1; - map->hoveredMovementPermissionTileChanged(x, y); -} - int ConnectionPixmapItem::getMinOffset() { if (connection->direction == "up" || connection->direction == "down") return 1 - (this->pixmap().width() / 16); @@ -1608,8 +1585,8 @@ void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) { int y = static_cast(pos.y()) / 16; Block *block = map->getBlock(x, y); if (block) { - block->collision = map->paint_collision; - block->elevation = map->paint_elevation; + block->collision = editor->movement_permissions_selector_item->getSelectedCollision(); + block->elevation = editor->movement_permissions_selector_item->getSelectedElevation(); map->_setBlock(x, y, *block); } if (event->type() == QEvent::GraphicsSceneMouseRelease) { @@ -1624,7 +1601,9 @@ void CollisionPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) { QPointF pos = event->pos(); int x = static_cast(pos.x()) / 16; int y = static_cast(pos.y()) / 16; - map->floodFillCollisionElevation(x, y, map->paint_collision, map->paint_elevation); + uint16_t collision = editor->movement_permissions_selector_item->getSelectedCollision(); + uint16_t elevation = editor->movement_permissions_selector_item->getSelectedElevation(); + map->floodFillCollisionElevation(x, y, collision, elevation); draw(); } } @@ -1635,8 +1614,7 @@ void CollisionPixmapItem::pick(QGraphicsSceneMouseEvent *event) { int y = static_cast(pos.y()) / 16; Block *block = map->getBlock(x, y); if (block) { - map->paint_collision = block->collision; - map->paint_elevation = block->elevation; + editor->movement_permissions_selector_item->select(block->collision, block->elevation); emit map->paintCollisionChanged(map); } } @@ -1653,9 +1631,8 @@ void CollisionPixmapItem::updateMovementPermissionSelection(QGraphicsSceneMouseE if (y >= map->getHeight()) y = map->getHeight() - 1; Block *block = map->getBlock(x, y); - map->paint_collision = block->collision; - map->paint_elevation = block->elevation; - editor->collision_metatiles_item->draw(); + editor->movement_permissions_selector_item->select(block->collision, block->elevation); + editor->movement_permissions_selector_item->draw(); } void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { diff --git a/editor.h b/editor.h index eca36d5e..7b8eb677 100755 --- a/editor.h +++ b/editor.h @@ -9,6 +9,7 @@ #include #include +#include "ui/movementpermissionsselector.h" #include "project.h" #include "ui_mainwindow.h" @@ -19,7 +20,6 @@ class ConnectionPixmapItem; class MetatilesPixmapItem; class BorderMetatilesPixmapItem; class CurrentSelectedMetatilesPixmapItem; -class MovementPermissionsPixmapItem; #define SWAP(a, b) do { if (a != b) { a ^= b; b ^= a; a ^= b; } } while (0) @@ -99,7 +99,7 @@ public: BorderMetatilesPixmapItem *selected_border_metatiles_item = nullptr; CurrentSelectedMetatilesPixmapItem *scene_current_metatile_selection_item = nullptr; - MovementPermissionsPixmapItem *collision_metatiles_item = nullptr; + MovementPermissionsSelector *movement_permissions_selector_item = nullptr; QList *events = nullptr; QList *selected_events = nullptr; @@ -149,6 +149,8 @@ private slots: void onConnectionItemDoubleClicked(ConnectionPixmapItem* connectionItem); void onConnectionDirectionChanged(QString newDirection); void onBorderMetatilesChanged(); + void onHoveredMovementPermissionChanged(uint16_t, uint16_t); + void onHoveredMovementPermissionCleared(); signals: void objectsChanged(); @@ -409,29 +411,4 @@ public: virtual void draw(); }; -class MovementPermissionsPixmapItem : public MetatilesPixmapItem { - Q_OBJECT -public: - MovementPermissionsPixmapItem(Map *map_): MetatilesPixmapItem(map_) { - connect(map, SIGNAL(paintCollisionChanged(Map*)), this, SLOT(paintCollisionChanged(Map *))); - } - virtual void pick(uint16_t collision, uint16_t elevation) { - map->paint_collision = collision; - map->paint_elevation = elevation; - draw(); - } - virtual void draw() { - setPixmap(map->renderCollisionMetatiles()); - } -protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); - virtual void updateCurHoveredMetatile(QPointF pos); -private slots: - void paintCollisionChanged(Map *) { - draw(); - } -}; - #endif // EDITOR_H diff --git a/event.h b/event.h index fcb54d24..0c3293a1 100755 --- a/event.h +++ b/event.h @@ -1,7 +1,7 @@ #ifndef EVENT_H #define EVENT_H -#include "heallocation.h" +#include "core/heallocation.h" #include #include #include diff --git a/mainwindow.cpp b/mainwindow.cpp index c5c90f65..8c0c45b9 100755 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -205,7 +205,7 @@ void MainWindow::redrawMapScene() 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); + ui->graphicsView_Collision->setFixedSize(editor->movement_permissions_selector_item->pixmap().width() + 2, editor->movement_permissions_selector_item->pixmap().height() + 2); } void MainWindow::openWarpMap(QString map_name, QString warp_num) { diff --git a/map.cpp b/map.cpp index 54298a5c..d21bec1a 100755 --- a/map.cpp +++ b/map.cpp @@ -11,8 +11,6 @@ Map::Map(QObject *parent) : QObject(parent) { paint_tile_index = 1; - paint_collision = 0; - paint_elevation = 3; selected_metatiles_width = 1; selected_metatiles_height = 1; selected_metatiles = new QList; @@ -165,7 +163,7 @@ QPixmap Map::renderCollision(bool ignoreCache) { } changed_any = true; Block block = layout->blockdata->blocks->value(i); - QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary); + QImage metatile_image = Tileset::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary); QImage collision_metatile_image = getCollisionMetatileImage(block); int map_y = width_ ? i / width_ : 0; int map_x = width_ ? i % width_ : 0; @@ -209,7 +207,7 @@ QPixmap Map::render(bool ignoreCache = false) { } changed_any = true; Block block = layout->blockdata->blocks->value(i); - QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary); + QImage metatile_image = Tileset::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); @@ -243,7 +241,7 @@ QPixmap Map::renderBorder() { } changed_any = true; Block block = layout->border->blocks->value(i); - QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary); + QImage metatile_image = Tileset::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); @@ -291,23 +289,6 @@ QPixmap Map::renderConnection(Connection connection) { return QPixmap::fromImage(connection_image); } -QPixmap Map::renderCollisionMetatiles() { - int width_ = 2; - int height_ = 16; - QImage image(width_ * 32, height_ * 32, QImage::Format_RGBA8888); - QPainter painter(&image); - for (int i = 0; i < width_; i++) { - for (int j = 0; j < height_; j++) { - QPoint origin(i * 32, j * 32); - QImage metatile_image = getCollisionMetatileImage(i, j).scaled(32, 32); - painter.drawImage(origin, metatile_image); - } - } - drawSelection(paint_collision + paint_elevation * width_, width_, 1, 1, &painter, 32); - painter.end(); - return QPixmap::fromImage(image); -} - void Map::drawSelection(int i, int w, int selectionWidth, int selectionHeight, QPainter *painter, int gridWidth) { int x = i % w; int y = i / w; @@ -340,7 +321,7 @@ QPixmap Map::renderMetatiles() { if (i >= primary_length) { tile += Project::getNumMetatilesPrimary() - primary_length; } - QImage metatile_image = Metatile::getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary); + QImage metatile_image = Tileset::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 b7c36b2e..60909193 100755 --- a/map.h +++ b/map.h @@ -1,8 +1,8 @@ #ifndef MAP_H #define MAP_H -#include "tileset.h" -#include "blockdata.h" +#include "core/tileset.h" +#include "core/blockdata.h" #include "event.h" #include @@ -165,7 +165,6 @@ public: QPixmap collision_pixmap; QImage getCollisionMetatileImage(Block); QImage getCollisionMetatileImage(int, int); - QPixmap renderCollisionMetatiles(); void drawSelection(int i, int w, int selectionWidth, int selectionHeight, QPainter *painter, int gridWidth); @@ -186,8 +185,6 @@ public: int selected_metatiles_width; int selected_metatiles_height; QList *selected_metatiles = nullptr; - uint16_t paint_collision; - uint16_t paint_elevation; Block *getBlock(int x, int y); void setBlock(int x, int y, Block block); @@ -219,7 +216,6 @@ public: void clearHoveredTile(); void hoveredMetatileChanged(int block); void clearHoveredMetatile(); - void hoveredMovementPermissionTileChanged(int collision, int elevation); void clearHoveredMovementPermissionTile(); void setSelectedMetatilesFromTilePicker(); @@ -231,6 +227,7 @@ signals: void statusBarMessage(QString); public slots: + void hoveredMovementPermissionTileChanged(int collision, int elevation); }; #endif // MAP_H diff --git a/parseutil.h b/parseutil.h index 23e095fc..b8dbdea4 100755 --- a/parseutil.h +++ b/parseutil.h @@ -1,7 +1,7 @@ #ifndef PARSEUTIL_H #define PARSEUTIL_H -#include "heallocation.h" +#include "core/heallocation.h" #include #include diff --git a/porymap.pro b/porymap.pro index f1d68efb..214b60bd 100755 --- a/porymap.pro +++ b/porymap.pro @@ -14,40 +14,46 @@ RC_ICONS = resources/icons/porymap-icon-1.ico ICON = resources/icons/porymap-icon-1.ico -SOURCES += main.cpp\ - mainwindow.cpp \ - project.cpp \ - map.cpp \ - blockdata.cpp \ - block.cpp \ - tileset.cpp \ - tile.cpp \ - event.cpp \ +SOURCES += core/block.cpp \ + core/blockdata.cpp \ + core/heallocation.cpp \ + core/metatile.cpp \ + core/tile.cpp \ + core/tileset.cpp \ + ui/movementpermissionsselector.cpp \ + ui/selectablepixmapitem.cpp \ editor.cpp \ - objectpropertiesframe.cpp \ + event.cpp \ graphicsview.cpp \ - parseutil.cpp \ + main.cpp \ + mainwindow.cpp \ + map.cpp \ neweventtoolbutton.cpp \ noscrollcombobox.cpp \ noscrollspinbox.cpp \ - heallocation.cpp + objectpropertiesframe.cpp \ + parseutil.cpp \ + project.cpp -HEADERS += mainwindow.h \ - project.h \ - map.h \ - blockdata.h \ - block.h \ - tileset.h \ - tile.h \ - event.h \ +HEADERS += core/block.h \ + core/blockdata.h \ + core/heallocation.h \ + core/metatile.h \ + core/tile.h \ + core/tileset.h \ + ui/movementpermissionsselector.h \ + ui/selectablepixmapitem.h \ editor.h \ - objectpropertiesframe.h \ + event.h \ graphicsview.h \ - parseutil.h \ + mainwindow.h \ + map.h \ neweventtoolbutton.h \ noscrollcombobox.h \ noscrollspinbox.h \ - heallocation.h + objectpropertiesframe.h \ + parseutil.h \ + project.h FORMS += mainwindow.ui \ objectpropertiesframe.ui diff --git a/project.cpp b/project.cpp index 9cce7bbb..c68bdc5e 100755 --- a/project.cpp +++ b/project.cpp @@ -1,7 +1,7 @@ #include "parseutil.h" #include "project.h" -#include "tile.h" -#include "tileset.h" +#include "core/tile.h" +#include "core/tileset.h" #include "event.h" #include @@ -849,11 +849,6 @@ void Project::loadTilesetAssets(Tileset* tileset) { if (num_metatiles > num_metatileAttrs) num_metatiles = num_metatileAttrs; } - for (int i = 0; i < num_metatiles; i++) { - uint16_t word = data[i*2] & 0xff; - word += (data[i*2 + 1] & 0xff) << 8; - tileset->metatiles->value(i)->attr = word; - } } else { qDebug() << QString("Could not open '%1'").arg(metatile_attrs_path); } diff --git a/project.h b/project.h index cb1a10ee..4db52a89 100755 --- a/project.h +++ b/project.h @@ -2,8 +2,8 @@ #define PROJECT_H #include "map.h" -#include "blockdata.h" -#include "heallocation.h" +#include "core/blockdata.h" +#include "core/heallocation.h" #include #include diff --git a/tile.cpp b/tile.cpp deleted file mode 100755 index fd0f42f3..00000000 --- a/tile.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "tile.h" - -Tile::Tile() -{ - -} diff --git a/ui/movementpermissionsselector.cpp b/ui/movementpermissionsselector.cpp new file mode 100644 index 00000000..d0df030b --- /dev/null +++ b/ui/movementpermissionsselector.cpp @@ -0,0 +1,59 @@ +#include "movementpermissionsselector.h" +#include + +void MovementPermissionsSelector::draw() { + QPixmap pixmap(":/images/collisions.png"); + this->setPixmap(pixmap.scaled(64, 512)); + this->drawSelection(); +} + +uint16_t MovementPermissionsSelector::getSelectedCollision() { + return static_cast(this->selectionInitialX); +} + +uint16_t MovementPermissionsSelector::getSelectedElevation() { + return static_cast(this->selectionInitialY); +} + +void MovementPermissionsSelector::select(uint16_t collision, uint16_t elevation) { + SelectablePixmapItem::select(collision, elevation, 0, 0); +} + +void MovementPermissionsSelector::mousePressEvent(QGraphicsSceneMouseEvent* event) { + SelectablePixmapItem::mousePressEvent(event); + this->setSelectedMovementPermissions(event->pos()); +} + +void MovementPermissionsSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { + SelectablePixmapItem::mouseMoveEvent(event); + this->setSelectedMovementPermissions(event->pos()); +} + +void MovementPermissionsSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { + SelectablePixmapItem::mouseReleaseEvent(event); + this->setSelectedMovementPermissions(event->pos()); +} + +void MovementPermissionsSelector::setSelectedMovementPermissions(QPointF pos) { + int x = static_cast(pos.x()) / 32; + int y = static_cast(pos.y()) / 32; + int width = this->pixmap().width() / 32; + int height = this->pixmap().height() / 32; + + // Snap to a valid position inside the selection area. + if (x < 0) x = 0; + if (x >= width) x = width - 1; + if (y < 0) y = 0; + if (y >= height) y = height - 1; +} + +void MovementPermissionsSelector::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { + QPoint pos = this->getCellPos(event->pos()); + uint16_t collision = static_cast(pos.x()); + uint16_t elevation = static_cast(pos.y()); + emit this->hoveredMovementPermissionChanged(collision, elevation); +} + +void MovementPermissionsSelector::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { + emit this->hoveredMovementPermissionCleared(); +} diff --git a/ui/movementpermissionsselector.h b/ui/movementpermissionsselector.h new file mode 100644 index 00000000..e7f03bf8 --- /dev/null +++ b/ui/movementpermissionsselector.h @@ -0,0 +1,32 @@ +#ifndef MOVEMENTPERMISSIONSSELECTOR_H +#define MOVEMENTPERMISSIONSSELECTOR_H + +#include "selectablepixmapitem.h" + +class MovementPermissionsSelector: public SelectablePixmapItem { + Q_OBJECT +public: + MovementPermissionsSelector(): SelectablePixmapItem(32, 32, 1, 1) { + setAcceptHoverEvents(true); + } + void draw(); + uint16_t getSelectedCollision(); + uint16_t getSelectedElevation(); + void select(uint16_t collision, uint16_t elevation); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + void hoverMoveEvent(QGraphicsSceneHoverEvent*); + void hoverLeaveEvent(QGraphicsSceneHoverEvent*); + +private: + void setSelectedMovementPermissions(QPointF); + +signals: + void hoveredMovementPermissionChanged(uint16_t, uint16_t); + void hoveredMovementPermissionCleared(); +}; + +#endif // MOVEMENTPERMISSIONSSELECTOR_H diff --git a/ui/selectablepixmapitem.cpp b/ui/selectablepixmapitem.cpp new file mode 100644 index 00000000..c120c325 --- /dev/null +++ b/ui/selectablepixmapitem.cpp @@ -0,0 +1,100 @@ +#include "selectablepixmapitem.h" +#include + +QPoint SelectablePixmapItem::getSelectionDimensions() +{ + return QPoint(abs(this->selectionOffsetX) + 1, abs(this->selectionOffsetY) + 1); +} + +QPoint SelectablePixmapItem::getSelectionStart() +{ + return QPoint(this->selectionInitialX + this->selectionOffsetX, + this->selectionInitialY + this->selectionOffsetY); +} + +void SelectablePixmapItem::select(int x, int y, int width, int height) +{ + this->selectionInitialX = x; + this->selectionInitialY = y; + this->selectionOffsetX = qMax(0, qMin(width, this->maxSelectionWidth)); + this->selectionOffsetY = qMax(0, qMin(height, this->maxSelectionHeight)); +} + +void SelectablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QPoint pos = this->getCellPos(event->pos()); + this->selectionInitialX = pos.x(); + this->selectionInitialY = pos.y(); + this->selectionOffsetX = 0; + this->selectionOffsetY = 0; + this->updateSelection(pos.x(), pos.y()); +} + +void SelectablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + QPoint pos = this->getCellPos(event->pos()); + this->updateSelection(pos.x(), pos.y()); +} + +void SelectablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QPoint pos = this->getCellPos(event->pos()); + this->updateSelection(pos.x(), pos.y()); +} + +void SelectablePixmapItem::updateSelection(int x, int y) +{ + // Snap to a valid position inside the selection area. + int width = pixmap().width() / this->cellWidth; + int height = pixmap().height() / this->cellHeight; + if (x < 0) x = 0; + if (x >= width) x = width - 1; + if (y < 0) y = 0; + if (y >= height) y = height - 1; + + this->selectionOffsetX = x - this->selectionInitialX; + this->selectionOffsetY = y - this->selectionInitialY; + + // Respect max selection dimensions by moving the selection's origin. + if (this->selectionOffsetX >= this->maxSelectionWidth) { + this->selectionInitialX += this->selectionOffsetX - this->maxSelectionWidth + 1; + this->selectionOffsetX = this->maxSelectionWidth - 1; + } else if (this->selectionOffsetX <= -this->maxSelectionWidth) { + this->selectionInitialX += this->selectionOffsetX + this->maxSelectionWidth - 1; + this->selectionOffsetX = -this->maxSelectionWidth + 1; + } + if (this->selectionOffsetY >= this->maxSelectionHeight) { + this->selectionInitialY += this->selectionOffsetY - this->maxSelectionHeight + 1; + this->selectionOffsetY = this->maxSelectionHeight - 1; + } else if (this->selectionOffsetY <= -this->maxSelectionHeight) { + this->selectionInitialY += this->selectionOffsetY + this->maxSelectionHeight - 1; + this->selectionOffsetY = -this->maxSelectionHeight + 1; + } + + this->draw(); +} + +QPoint SelectablePixmapItem::getCellPos(QPointF pos) +{ + return QPoint(static_cast(pos.x()) / this->cellWidth, + static_cast(pos.y()) / this->cellHeight); +} + +void SelectablePixmapItem::drawSelection() +{ + QPixmap pixmap = this->pixmap(); + QPainter painter(&pixmap); + QPoint origin = this->getSelectionStart(); + QPoint dimensions = this->getSelectionDimensions(); + + int rectWidth = dimensions.x() * this->cellWidth; + int rectHeight = dimensions.y() * this->cellHeight; + + painter.setPen(QColor(0xff, 0xff, 0xff)); + painter.drawRect(origin.x() * this->cellWidth, origin.y() * this->cellHeight, rectWidth - 1, rectHeight -1); + painter.setPen(QColor(0, 0, 0)); + painter.drawRect(origin.x() * this->cellWidth - 1, origin.y() * this->cellHeight - 1, rectWidth + 1, rectHeight + 1); + painter.drawRect(origin.x() * this->cellWidth + 1, origin.y() * this->cellHeight + 1, rectWidth - 3, rectHeight - 3); + + this->setPixmap(pixmap); +} diff --git a/ui/selectablepixmapitem.h b/ui/selectablepixmapitem.h new file mode 100644 index 00000000..293ac659 --- /dev/null +++ b/ui/selectablepixmapitem.h @@ -0,0 +1,39 @@ +#ifndef SELECTABLEPIXMAPITEM_H +#define SELECTABLEPIXMAPITEM_H + +#include +#include + +class SelectablePixmapItem : public QObject, public QGraphicsPixmapItem { + Q_OBJECT +public: + SelectablePixmapItem(int cellWidth, int cellHeight, int maxSelectionWidth, int maxSelectionHeight) { + this->cellWidth = cellWidth; + this->cellHeight = cellHeight; + this->maxSelectionWidth = maxSelectionWidth; + this->maxSelectionHeight = maxSelectionHeight; + } + QPoint getSelectionDimensions(); + QPoint getSelectionStart(); + virtual void draw() = 0; + +protected: + int cellWidth; + int cellHeight; + int maxSelectionWidth; + int maxSelectionHeight; + int selectionInitialX; + int selectionInitialY; + int selectionOffsetX; + int selectionOffsetY; + + void select(int, int, int, int); + void updateSelection(int, int); + QPoint getCellPos(QPointF); + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + virtual void drawSelection(); +}; + +#endif // SELECTABLEPIXMAPITEM_H