From 11212dc64042cdeda1fc1c33f7b141a9744f84b8 Mon Sep 17 00:00:00 2001 From: yenatch Date: Mon, 27 Nov 2017 23:46:27 -0500 Subject: [PATCH] lots of changes --- blockdata.cpp | 16 + blockdata.h | 3 +- editor.cpp | 422 +++++++++-- editor.h | 375 +++++++--- event.cpp | 47 -- event.h | 96 +-- graphicsview.cpp | 22 + graphicsview.h | 38 + mainwindow.cpp | 365 +++++++++- mainwindow.h | 19 +- mainwindow.ui | 1041 ++++++++++++++++++--------- map.cpp | 221 ++++-- map.h | 54 +- metatile.h | 2 +- objectpropertiesframe.cpp | 14 + objectpropertiesframe.h | 22 + objectpropertiesframe.ui | 250 +++++++ pretmap.pro | 11 +- project.cpp | 424 ++++++++--- project.h | 14 +- resources/icons/add.ico | Bin 0 -> 5430 bytes resources/icons/cursor.ico | Bin 0 -> 1150 bytes resources/icons/delete.ico | Bin 0 -> 5430 bytes resources/icons/fill_color.ico | Bin 0 -> 1150 bytes resources/icons/pencil.ico | Bin 0 -> 1150 bytes resources/icons/pipette.ico | Bin 0 -> 1150 bytes resources/icons/viewsprites.ico | Bin 0 -> 5430 bytes resources/images.qrc | 8 + resources/images/Entities_16x16.png | Bin 0 -> 274 bytes tileset.h | 6 +- 30 files changed, 2575 insertions(+), 895 deletions(-) create mode 100755 graphicsview.cpp create mode 100755 graphicsview.h create mode 100755 objectpropertiesframe.cpp create mode 100755 objectpropertiesframe.h create mode 100755 objectpropertiesframe.ui create mode 100755 resources/icons/add.ico create mode 100755 resources/icons/cursor.ico create mode 100755 resources/icons/delete.ico create mode 100755 resources/icons/fill_color.ico create mode 100755 resources/icons/pencil.ico create mode 100755 resources/icons/pipette.ico create mode 100755 resources/icons/viewsprites.ico create mode 100755 resources/images/Entities_16x16.png diff --git a/blockdata.cpp b/blockdata.cpp index b08b936d..eb99ea65 100755 --- a/blockdata.cpp +++ b/blockdata.cpp @@ -1,4 +1,5 @@ #include "blockdata.h" +#include Blockdata::Blockdata(QObject *parent) : QObject(parent) { @@ -37,3 +38,18 @@ Blockdata* Blockdata::copy() { 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/blockdata.h index 5ba4930b..0be540dc 100755 --- a/blockdata.h +++ b/blockdata.h @@ -13,12 +13,13 @@ public: explicit Blockdata(QObject *parent = 0); public: - QList *blocks; + QList *blocks = NULL; void addBlock(uint16_t); void addBlock(Block); QByteArray serialize(); void copyFrom(Blockdata*); Blockdata* copy(); + bool equals(Blockdata *); signals: diff --git a/editor.cpp b/editor.cpp index 9a56e5fc..b00c7948 100755 --- a/editor.cpp +++ b/editor.cpp @@ -1,8 +1,10 @@ #include "editor.h" +#include +#include Editor::Editor() { - + selected_events = new QList; } void Editor::saveProject() { @@ -31,53 +33,111 @@ void Editor::redo() { void Editor::setEditingMap() { current_view = map_item; - map_item->draw(); - map_item->setVisible(true); - map_item->setEnabled(true); - collision_item->setVisible(false); - objects_group->setVisible(false); + if (map_item) { + map_item->draw(); + map_item->setVisible(true); + map_item->setEnabled(true); + } + if (collision_item) { + collision_item->setVisible(false); + } + if (objects_group) { + objects_group->setVisible(false); + } } void Editor::setEditingCollision() { current_view = collision_item; - collision_item->draw(); - collision_item->setVisible(true); - map_item->setVisible(false); - objects_group->setVisible(false); + if (collision_item) { + collision_item->draw(); + collision_item->setVisible(true); + } + if (map_item) { + map_item->setVisible(false); + } + if (objects_group) { + objects_group->setVisible(false); + } } void Editor::setEditingObjects() { - objects_group->setVisible(true); - map_item->setVisible(true); - map_item->setEnabled(false); - collision_item->setVisible(false); + current_view = map_item; + if (objects_group) { + objects_group->setVisible(true); + } + if (map_item) { + map_item->setVisible(true); + map_item->setEnabled(false); + } + if (collision_item) { + collision_item->setVisible(false); + } } void Editor::setMap(QString map_name) { if (map_name.isNull()) { return; } - map = project->getMap(map_name); - displayMap(); + if (project) { + map = project->loadMap(map_name); + displayMap(); + selected_events->clear(); + updateSelectedObjects(); + } +} + +void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) { + if (map_edit_mode == "paint") { + item->paint(event); + } else if (map_edit_mode == "fill") { + item->floodFill(event); + } else if (map_edit_mode == "pick") { + item->pick(event); + } else if (map_edit_mode == "select") { + item->select(event); + } +} +void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item) { + if (map_edit_mode == "paint") { + item->paint(event); + } else if (map_edit_mode == "fill") { + item->floodFill(event); + } else if (map_edit_mode == "pick") { + item->pick(event); + } else if (map_edit_mode == "select") { + item->select(event); + } } void Editor::displayMap() { scene = new QGraphicsScene; map_item = new MapPixmapItem(map); + connect(map_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,MapPixmapItem*)), + this, SLOT(mouseEvent_map(QGraphicsSceneMouseEvent*,MapPixmapItem*))); + map_item->draw(); scene->addItem(map_item); collision_item = new CollisionPixmapItem(map); + connect(collision_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)), + this, SLOT(mouseEvent_collision(QGraphicsSceneMouseEvent*,CollisionPixmapItem*))); + collision_item->draw(); scene->addItem(collision_item); - objects_group = new QGraphicsItemGroup; + objects_group = new EventGroup; scene->addItem(objects_group); - map_item->setVisible(false); - collision_item->setVisible(false); - objects_group->setVisible(false); + if (map_item) { + map_item->setVisible(false); + } + if (collision_item) { + collision_item->setVisible(false); + } + if (objects_group) { + objects_group->setVisible(false); + } int tw = 16; int th = 16; @@ -122,13 +182,22 @@ void Editor::displayMapObjects() { objects_group->removeFromGroup(child); } - project->loadObjectPixmaps(map->object_events); - for (int i = 0; i < map->object_events.length(); i++) { - ObjectEvent *object_event = map->object_events.value(i); - DraggablePixmapItem *object = new DraggablePixmapItem(object_event); - objects_group->addToGroup(object); + QList events = map->getAllEvents(); + project->loadObjectPixmaps(events); + for (Event *event : events) { + addMapObject(event); } - objects_group->setFiltersChildEvents(false); + //objects_group->setFiltersChildEvents(false); + objects_group->setHandlesChildEvents(false); + + emit objectsChanged(); +} + +DraggablePixmapItem *Editor::addMapObject(Event *event) { + DraggablePixmapItem *object = new DraggablePixmapItem(event); + object->editor = this; + objects_group->addToGroup(object); + return object; } void Editor::displayMapConnections() { @@ -139,7 +208,7 @@ void Editor::displayMapConnections() { Map *connected_map = project->getMap(connection->map_name); QPixmap pixmap = connected_map->renderConnection(*connection); int offset = connection->offset.toInt(nullptr, 0); - int x, y; + int x = 0, y = 0; if (connection->direction == "up") { x = offset * 16; y = -pixmap.height(); @@ -154,6 +223,7 @@ void Editor::displayMapConnections() { y = offset * 16; } QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap); + item->setZValue(-1); item->setX(x); item->setY(y); scene->addItem(item); @@ -167,11 +237,14 @@ void Editor::displayMapBorder() { QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap); item->setX(x * 16); item->setY(y * 16); - item->setZValue(-1); + item->setZValue(-2); scene->addItem(item); } } +void MetatilesPixmapItem::paintTileChanged(Map *map) { + draw(); +} void MetatilesPixmapItem::draw() { setPixmap(map->renderMetatiles()); @@ -179,7 +252,7 @@ void MetatilesPixmapItem::draw() { void MetatilesPixmapItem::pick(uint tile) { map->paint_tile = tile; - draw(); + emit map->paintTileChanged(map); } void MetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { @@ -193,6 +266,9 @@ void MetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { pick(y * width + x); } } +void MetatilesPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + mousePressEvent(event); +} void MetatilesPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { mousePressEvent(event); } @@ -206,7 +282,10 @@ void MapPixmapItem::paint(QGraphicsSceneMouseEvent *event) { Block *block = map->getBlock(x, y); if (block) { block->tile = map->paint_tile; - map->setBlock(x, y, *block); + map->_setBlock(x, y, *block); + } + if (event->type() == QEvent::GraphicsSceneMouseRelease) { + map->commit(); } draw(); } @@ -222,45 +301,95 @@ void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) { } } -void MapPixmapItem::draw() { - setPixmap(map->render()); -} - -void MapPixmapItem::undo() { - map->undo(); - draw(); -} - -void MapPixmapItem::redo() { - map->redo(); - draw(); -} - -void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - active = true; - if (event->button() == Qt::RightButton) { - right_click = true; - floodFill(event); - } else { - right_click = false; - paint(event); +void MapPixmapItem::pick(QGraphicsSceneMouseEvent *event) { + QPointF pos = event->pos(); + int x = (int)(pos.x()) / 16; + int y = (int)(pos.y()) / 16; + Block *block = map->getBlock(x, y); + if (block) { + map->paint_tile = block->tile; + emit map->paintTileChanged(map); } } -void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - if (active) { - if (right_click) { - floodFill(event); - } else { - paint(event); + +#define SWAP(a, b) do { if (a != b) { a ^= b; b ^= a; a ^= b; } } while (0) + +void MapPixmapItem::select(QGraphicsSceneMouseEvent *event) { + QPointF pos = event->pos(); + int x = (int)(pos.x()) / 16; + int y = (int)(pos.y()) / 16; + if (event->type() == QEvent::GraphicsSceneMousePress) { + selection_origin = QPoint(x, y); + selection.clear(); + } else if (event->type() == QEvent::GraphicsSceneMouseMove) { + if (event->buttons() & Qt::LeftButton) { + selection.clear(); + selection.append(QPoint(x, y)); + } + } else if (event->type() == QEvent::GraphicsSceneMouseRelease) { + if (!selection.isEmpty()) { + QPoint pos = selection.last(); + int x1 = selection_origin.x(); + int y1 = selection_origin.y(); + int x2 = pos.x(); + int y2 = pos.y(); + if (x1 > x2) SWAP(x1, x2); + if (y1 > y2) SWAP(y1, y2); + selection.clear(); + for (int y = y1; y <= y2; y++) { + for (int x = x1; x <= x2; x++) { + selection.append(QPoint(x, y)); + } + } + qDebug() << QString("selected (%1, %2) -> (%3, %4)").arg(x1).arg(y1).arg(x2).arg(y2); } } } + +void MapPixmapItem::draw() { + if (map) { + setPixmap(map->render()); + } +} + +void MapPixmapItem::undo() { + if (map) { + map->undo(); + draw(); + } +} + +void MapPixmapItem::redo() { + if (map) { + map->redo(); + draw(); + } +} + +void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { + emit mouseEvent(event, this); +} +void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + emit mouseEvent(event, this); +} void MapPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { - active = false; + emit mouseEvent(event, this); +} + +void CollisionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { + emit mouseEvent(event, this); +} +void CollisionPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + emit mouseEvent(event, this); +} +void CollisionPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { + emit mouseEvent(event, this); } void CollisionPixmapItem::draw() { - setPixmap(map->renderCollision()); + if (map) { + setPixmap(map->renderCollision()); + } } void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) { @@ -276,7 +405,10 @@ void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) { if (map->paint_elevation >= 0) { block->elevation = map->paint_elevation; } - map->setBlock(x, y, *block); + map->_setBlock(x, y, *block); + } + if (event->type() == QEvent::GraphicsSceneMouseRelease) { + map->commit(); } draw(); } @@ -300,25 +432,177 @@ void CollisionPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) { } } +void CollisionPixmapItem::pick(QGraphicsSceneMouseEvent *event) { + QPointF pos = event->pos(); + int x = (int)(pos.x()) / 16; + int y = (int)(pos.y()) / 16; + Block *block = map->getBlock(x, y); + if (block) { + map->paint_collision = block->collision; + map->paint_elevation = block->elevation; + emit map->paintCollisionChanged(map); + } +} + void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { active = true; - last_x = mouse->pos().x() / 16; - last_y = mouse->pos().y() / 16; - qDebug() << event->x_ + ", " + event->y_; + clicking = true; + last_x = (mouse->pos().x() + this->pos().x()) / 16; + last_y = (mouse->pos().y() + this->pos().y()) / 16; + //qDebug() << QString("(%1, %2)").arg(event->get("x")).arg(event->get("y")); +} + +void DraggablePixmapItem::move(int x, int y) { + event->setX(event->x() + x); + event->setY(event->y() + y); + updatePosition(); + emitPositionChanged(); } void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { if (active) { - int x = mouse->pos().x() / 16; - int y = mouse->pos().y() / 16; + int x = (mouse->pos().x() + this->pos().x()) / 16; + int y = (mouse->pos().y() + this->pos().y()) / 16; if (x != last_x || y != last_y) { - event->setX(event->x() + x - last_x); - event->setY(event->y() + y - last_y); - update(); + clicking = false; + if (editor->selected_events->contains(this)) { + for (DraggablePixmapItem *item : *editor->selected_events) { + item->move(x - last_x, y - last_y); + } + } else { + move(x - last_x, y - last_y); + } + last_x = x; + last_y = y; + //qDebug() << QString("(%1, %2)").arg(event->get("x")).arg(event->get("x")); } } } void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouse) { + if (clicking) { + this->editor->selectMapObject(this, mouse->modifiers() & Qt::ControlModifier); + this->editor->updateSelectedObjects(); + } active = false; } + +QList *Editor::getObjects() { + QList *list = new QList; + for (Event *event : map->getAllEvents()) { + for (QGraphicsItem *child : objects_group->childItems()) { + DraggablePixmapItem *item = (DraggablePixmapItem *)child; + if (item->event == event) { + list->append(item); + break; + } + } + } + return list; +} + +void Editor::redrawObject(DraggablePixmapItem *item) { + if (item) { + item->setPixmap(item->event->pixmap); + if (selected_events && selected_events->contains(item)) { + QImage image = item->pixmap().toImage(); + QPainter painter(&image); + painter.setPen(QColor(250, 100, 25)); + painter.drawRect(0, 0, image.width() - 1, image.height() - 1); + painter.end(); + item->setPixmap(QPixmap::fromImage(image)); + } + } +} + +void Editor::updateSelectedObjects() { + for (DraggablePixmapItem *item : *(getObjects())) { + redrawObject(item); + } + emit selectedObjectsChanged(); +} + +void Editor::selectMapObject(DraggablePixmapItem *object) { + selectMapObject(object, false); +} + +void Editor::selectMapObject(DraggablePixmapItem *object, bool toggle) { + if (selected_events && object) { + if (selected_events->contains(object)) { + if (toggle) { + selected_events->removeOne(object); + } + } else { + if (!toggle) { + selected_events->clear(); + } + selected_events->append(object); + } + updateSelectedObjects(); + } +} + +DraggablePixmapItem* Editor::addNewEvent() { + return addNewEvent("object"); +} + +DraggablePixmapItem* Editor::addNewEvent(QString event_type) { + if (project && map) { + Event *event = new Event; + event->put("map_name", map->name); + event->put("event_type", event_type); + map->addEvent(event); + project->loadObjectPixmaps(map->getAllEvents()); + DraggablePixmapItem *object = addMapObject(event); + + return object; + } + return NULL; +} + +void Editor::deleteEvent(Event *event) { + Map *map = project->getMap(event->get("map_name")); + if (map) { + map->removeEvent(event); + } + //selected_events->removeAll(event); + //updateSelectedObjects(); +} + + +// dunno how to detect bubbling. QMouseEvent::isAccepted seems to always be true +// check if selected_events changed instead. this has the side effect of deselecting +// when you click on a selected event, since selected_events doesn't change. + +QList selected_events_test; +bool clicking = false; + +void Editor::objectsView_onMousePress(QMouseEvent *event) { + clicking = true; + selected_events_test = *selected_events; +} + +void Editor::objectsView_onMouseMove(QMouseEvent *event) { + clicking = false; +} + +void Editor::objectsView_onMouseRelease(QMouseEvent *event) { + if (clicking) { + if (selected_events_test.length()) { + if (selected_events_test.length() == selected_events->length()) { + bool deselect = true; + for (int i = 0; i < selected_events_test.length(); i++) { + if (selected_events_test.at(i) != selected_events->at(i)) { + deselect = false; + break; + } + } + if (deselect) { + selected_events->clear(); + updateSelectedObjects(); + } + } + } + clicking = false; + } +} diff --git a/editor.h b/editor.h index 54564247..e099809c 100755 --- a/editor.h +++ b/editor.h @@ -4,123 +4,27 @@ #include #include #include +#include +#include #include "project.h" +class DraggablePixmapItem; +class MapPixmapItem; +class CollisionPixmapItem; +class MetatilesPixmapItem; +class CollisionMetatilesPixmapItem; +class ElevationMetatilesPixmapItem; -class DraggablePixmapItem : public QGraphicsPixmapItem { -public: - DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) { - } - Event *event; - DraggablePixmapItem(Event *event_) : QGraphicsPixmapItem(event_->pixmap) { - event = event_; - update(); - } - bool active; - bool right_click; - int last_x; - int last_y; - void update() { - int x = event->x() * 16; - int y = event->y() * 16; - x -= pixmap().width() / 32 * 16; - y -= pixmap().height() - 16; - setX(x); - setY(y); - setZValue(event->y()); - } - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); -}; - -class MapPixmapItem : public QGraphicsPixmapItem { -public: - MapPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) { - } - Map *map; - MapPixmapItem(Map *map_) { - map = map_; - } - bool active; - bool right_click; - virtual void paint(QGraphicsSceneMouseEvent*); - virtual void floodFill(QGraphicsSceneMouseEvent*); - virtual void undo(); - virtual void redo(); - virtual void draw(); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); -}; - -class CollisionPixmapItem : public MapPixmapItem { -public: - CollisionPixmapItem(QPixmap pixmap): MapPixmapItem(pixmap) { - } - CollisionPixmapItem(Map *map_): MapPixmapItem(map_) { - } - -public: - virtual void paint(QGraphicsSceneMouseEvent*); - virtual void floodFill(QGraphicsSceneMouseEvent*); - virtual void draw(); -}; - -class MetatilesPixmapItem : public QGraphicsPixmapItem { -public: - MetatilesPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) { - } - MetatilesPixmapItem(Map *map_) { - map = map_; - } - Map* map; - virtual void pick(uint); - virtual void draw(); -protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); -}; - -class CollisionMetatilesPixmapItem : public MetatilesPixmapItem { -public: - CollisionMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) { - } - virtual void pick(uint collision) { - map->paint_collision = collision; - draw(); - } - virtual void draw() { - setPixmap(map->renderCollisionMetatiles()); - } -}; - -class ElevationMetatilesPixmapItem : public MetatilesPixmapItem { -public: - ElevationMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) { - } - virtual void pick(uint elevation) { - map->paint_elevation = elevation; - draw(); - } - virtual void draw() { - setPixmap(map->renderElevationMetatiles()); - } -}; - - -class Editor +class Editor : public QObject { + Q_OBJECT public: Editor(); public: - Project *project; - Map *map; + QObject *parent = NULL; + Project *project = NULL; + Map *map = NULL; void saveProject(); void save(); void undo(); @@ -138,18 +42,249 @@ public: void setEditingCollision(); void setEditingObjects(); - QGraphicsScene *scene; - QGraphicsPixmapItem *current_view; - MapPixmapItem *map_item; - CollisionPixmapItem *collision_item; - QGraphicsItemGroup *objects_group; + DraggablePixmapItem *addMapObject(Event *event); + void selectMapObject(DraggablePixmapItem *object); + void selectMapObject(DraggablePixmapItem *object, bool toggle); + DraggablePixmapItem *addNewEvent(); + DraggablePixmapItem *addNewEvent(QString event_type); + void deleteEvent(Event *); + void updateSelectedObjects(); + void redrawObject(DraggablePixmapItem *item); + QList *getObjects(); - QGraphicsScene *scene_metatiles; - QGraphicsScene *scene_collision_metatiles; - QGraphicsScene *scene_elevation_metatiles; - MetatilesPixmapItem *metatiles_item; - CollisionMetatilesPixmapItem *collision_metatiles_item; - ElevationMetatilesPixmapItem *elevation_metatiles_item; + QGraphicsScene *scene = NULL; + QGraphicsPixmapItem *current_view = NULL; + MapPixmapItem *map_item = NULL; + CollisionPixmapItem *collision_item = NULL; + QGraphicsItemGroup *objects_group = NULL; + + QGraphicsScene *scene_metatiles = NULL; + QGraphicsScene *scene_collision_metatiles = NULL; + QGraphicsScene *scene_elevation_metatiles = NULL; + MetatilesPixmapItem *metatiles_item = NULL; + CollisionMetatilesPixmapItem *collision_metatiles_item = NULL; + ElevationMetatilesPixmapItem *elevation_metatiles_item = NULL; + + QList *events = NULL; + QList *selected_events = NULL; + + QString map_edit_mode; + + void objectsView_onMousePress(QMouseEvent *event); + void objectsView_onMouseMove(QMouseEvent *event); + void objectsView_onMouseRelease(QMouseEvent *event); + +private slots: + void mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item); + void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item); + +signals: + void objectsChanged(); + void selectedObjectsChanged(); }; + + +class DraggablePixmapItem : public QObject, public QGraphicsPixmapItem { + Q_OBJECT +public: + DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) { + } + Editor *editor = NULL; + Event *event = NULL; + QGraphicsItemAnimation *pos_anim = NULL; + DraggablePixmapItem(Event *event_) : QGraphicsPixmapItem(event_->pixmap) { + event = event_; + updatePosition(); + } + bool active; + bool right_click; + bool clicking; + int last_x; + int last_y; + void updatePosition() { + int x = event->x() * 16; + int y = event->y() * 16; + x -= pixmap().width() / 32 * 16; + y -= pixmap().height() - 16; + setX(x); + setY(y); + setZValue(event->y()); + } + void move(int x, int y); + void emitPositionChanged() { + emit xChanged(event->x()); + emit yChanged(event->y()); + emit elevationChanged(event->elevation()); + } + void updatePixmap() { + QList objects; + objects.append(event); + event->pixmap = QPixmap(); + editor->project->loadObjectPixmaps(objects); + editor->redrawObject(this); + emit spriteChanged(event->pixmap); + } + void bind(QComboBox *combo, QString key) { + connect(combo, static_cast(&QComboBox::activated), + this, [this, key](QString value){ + this->event->put(key, value); + }); + connect(this, &DraggablePixmapItem::onPropertyChanged, + this, [combo, key](QString key2, QString value){ + if (key2 == key) { + combo->addItem(value); + combo->setCurrentText(value); + } + }); + } + +signals: + void positionChanged(Event *event); + void xChanged(int); + void yChanged(int); + void elevationChanged(int); + void spriteChanged(QPixmap pixmap); + void onPropertyChanged(QString key, QString value); + +public slots: + void set_x(const QString &text) { + event->put("x", text); + updatePosition(); + } + void set_y(const QString &text) { + event->put("y", text); + updatePosition(); + } + void set_elevation(const QString &text) { + event->put("elevation", text); + updatePosition(); + } + void set_sprite(const QString &text) { + event->put("sprite", text); + updatePixmap(); + } + void set_script(const QString &text) { + event->put("script_label", text); + } + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); +}; + +class EventGroup : public QGraphicsItemGroup { +}; + +class MapPixmapItem : public QObject, public QGraphicsPixmapItem { + Q_OBJECT +public: + MapPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) { + } + Map *map = NULL; + MapPixmapItem(Map *map_) { + map = map_; + } + bool active; + bool right_click; + QPoint selection_origin; + QList selection; + virtual void paint(QGraphicsSceneMouseEvent*); + virtual void floodFill(QGraphicsSceneMouseEvent*); + virtual void pick(QGraphicsSceneMouseEvent*); + virtual void select(QGraphicsSceneMouseEvent*); + virtual void undo(); + virtual void redo(); + virtual void draw(); + +signals: + void mouseEvent(QGraphicsSceneMouseEvent *, MapPixmapItem *); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); +}; + +class CollisionPixmapItem : public MapPixmapItem { + Q_OBJECT +public: + CollisionPixmapItem(QPixmap pixmap): MapPixmapItem(pixmap) { + } + CollisionPixmapItem(Map *map_): MapPixmapItem(map_) { + } + virtual void paint(QGraphicsSceneMouseEvent*); + virtual void floodFill(QGraphicsSceneMouseEvent*); + virtual void pick(QGraphicsSceneMouseEvent*); + virtual void draw(); + +signals: + void mouseEvent(QGraphicsSceneMouseEvent *, CollisionPixmapItem *); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); +}; + +class MetatilesPixmapItem : public QObject, public QGraphicsPixmapItem { + Q_OBJECT +public: + MetatilesPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) { + } + MetatilesPixmapItem(Map *map_) { + map = map_; + connect(map, SIGNAL(paintTileChanged(Map*)), this, SLOT(paintTileChanged(Map *))); + } + Map* map = NULL; + virtual void pick(uint); + virtual void draw(); +private slots: + void paintTileChanged(Map *map); +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); +}; + +class CollisionMetatilesPixmapItem : public MetatilesPixmapItem { + Q_OBJECT +public: + CollisionMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) { + connect(map, SIGNAL(paintCollisionChanged(Map*)), this, SLOT(paintCollisionChanged(Map *))); + } + virtual void pick(uint collision) { + map->paint_collision = collision; + draw(); + } + virtual void draw() { + setPixmap(map->renderCollisionMetatiles()); + } +private slots: + void paintCollisionChanged(Map *map) { + draw(); + } +}; + +class ElevationMetatilesPixmapItem : public MetatilesPixmapItem { + Q_OBJECT +public: + ElevationMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) { + connect(map, SIGNAL(paintCollisionChanged(Map*)), this, SLOT(paintCollisionChanged(Map *))); + } + virtual void pick(uint elevation) { + map->paint_elevation = elevation; + draw(); + } + virtual void draw() { + setPixmap(map->renderElevationMetatiles()); + } +private slots: + void paintCollisionChanged(Map *map) { + draw(); + } +}; + + #endif // EDITOR_H diff --git a/event.cpp b/event.cpp index 11ca06cd..efee19ef 100755 --- a/event.cpp +++ b/event.cpp @@ -2,51 +2,4 @@ Event::Event() { - -} - -ObjectEvent::ObjectEvent() -{ - -} - -Warp::Warp() -{ - -} - -CoordEvent::CoordEvent() -{ - -} - -BGEvent::BGEvent() -{ - -} - -Sign::Sign() -{ - -} - -Sign::Sign(const BGEvent &bg) -{ - x_ = bg.x_; - y_ = bg.y_; - elevation_ = bg.elevation_; - type = bg.type; -} - -HiddenItem::HiddenItem() -{ - -} - -HiddenItem::HiddenItem(const BGEvent &bg) -{ - x_ = bg.x_; - y_ = bg.y_; - elevation_ = bg.elevation_; - type = bg.type; } diff --git a/event.h b/event.h index 3b1dc635..daccb900 100755 --- a/event.h +++ b/event.h @@ -3,6 +3,7 @@ #include #include +#include class Event { @@ -11,90 +12,39 @@ public: public: int x() { - return x_.toInt(nullptr, 0); + return getInt("x"); } int y() { - return y_.toInt(nullptr, 0); + return getInt("y"); } int elevation() { - return elevation_.toInt(nullptr, 0); + return getInt("elevation"); } void setX(int x) { - x_ = QString("%1").arg(x); + put("x", x); } void setY(int y) { - y_ = QString("%1").arg(y); + put("y", y); + } + QString get(QString key) { + return values.value(key); + } + int getInt(QString key) { + return values.value(key).toInt(nullptr, 0); + } + void put(QString key, int value) { + put(key, QString("%1").arg(value)); + } + void put(QString key, QString value) { + values.insert(key, value); } - QString x_; - QString y_; - QString elevation_; + bool is_hidden_item() { + return getInt("type") >= 5; + } + + QMap values; QPixmap pixmap; }; -class ObjectEvent : public Event { -public: - ObjectEvent(); - -public: - QString sprite; - QString replacement; // ???? - QString behavior; - QString radius_x; - QString radius_y; - QString property; - QString sight_radius; - QString script_label; - QString event_flag; -}; - -class Warp : public Event { -public: - Warp(); - -public: - QString destination_warp; - QString destination_map; -}; - -class CoordEvent : public Event { -public: - CoordEvent(); - -public: - QString unknown1; - QString unknown2; - QString unknown3; - QString unknown4; - QString script_label; -}; - -class BGEvent : public Event { -public: - BGEvent(); -public: - bool is_item() { - return type.toInt(nullptr, 0) >= 5; - } - QString type; -}; - -class Sign : public BGEvent { -public: - Sign(); - Sign(const BGEvent&); -public: - QString script_label; -}; - -class HiddenItem : public BGEvent { -public: - HiddenItem(); - HiddenItem(const BGEvent&); -public: - QString item; - QString unknown5; - QString unknown6; -}; - #endif // EVENT_H diff --git a/graphicsview.cpp b/graphicsview.cpp new file mode 100755 index 00000000..3e11cee9 --- /dev/null +++ b/graphicsview.cpp @@ -0,0 +1,22 @@ +#include "graphicsview.h" + +void GraphicsView::mousePressEvent(QMouseEvent *event) { + QGraphicsView::mousePressEvent(event); + if (editor) { + editor->objectsView_onMousePress(event); + } +} + +void GraphicsView::mouseMoveEvent(QMouseEvent *event) { + QGraphicsView::mouseMoveEvent(event); + if (editor) { + editor->objectsView_onMouseMove(event); + } +} + +void GraphicsView::mouseReleaseEvent(QMouseEvent *event) { + QGraphicsView::mouseReleaseEvent(event); + if (editor) { + editor->objectsView_onMouseRelease(event); + } +} diff --git a/graphicsview.h b/graphicsview.h new file mode 100755 index 00000000..0734715e --- /dev/null +++ b/graphicsview.h @@ -0,0 +1,38 @@ +#ifndef GRAPHICSVIEW_H +#define GRAPHICSVIEW_H + +#include +#include + +#include "editor.h" + +/* +class GraphicsView_Object : public QObject +{ + Q_OBJECT + +signals: + void onMousePress(QMouseEvent *event); + void onMouseMove(QMouseEvent *event); + void onMouseRelease(QMouseEvent *event); +}; +*/ + +class GraphicsView : public QGraphicsView +{ +public: + GraphicsView() : QGraphicsView() {} + GraphicsView(QWidget *parent) : QGraphicsView(parent) {} + +public: +// GraphicsView_Object object; + Editor *editor = NULL; +protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); +}; + +//Q_DECLARE_METATYPE(GraphicsView) + +#endif // GRAPHICSVIEW_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 09695706..35da4aef 100755 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,12 +1,20 @@ #include "mainwindow.h" #include "ui_mainwindow.h" #include "project.h" +#include "editor.h" +#include "objectpropertiesframe.h" +#include "ui_objectpropertiesframe.h" #include #include #include #include #include +#include +#include +#include +#include +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -15,16 +23,23 @@ MainWindow::MainWindow(QWidget *parent) : QCoreApplication::setOrganizationName("pret"); QCoreApplication::setApplicationName("pretmap"); - editor = new Editor; - - new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo())); ui->setupUi(this); + new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo())); + + editor = new Editor; + connect(editor, SIGNAL(objectsChanged()), this, SLOT(updateSelectedObjects())); + connect(editor, SIGNAL(selectedObjectsChanged()), this, SLOT(updateSelectedObjects())); + + on_toolButton_Paint_clicked(); QSettings settings; QString key = "recent_projects"; if (settings.contains(key)) { QString default_dir = settings.value(key).toStringList().last(); - openProject(default_dir); + if (!default_dir.isNull()) { + qDebug() << QString("default_dir: '%1'").arg(default_dir); + openProject(default_dir); + } } } @@ -34,35 +49,53 @@ MainWindow::~MainWindow() } void MainWindow::openProject(QString dir) { - bool already_open = (editor->project != NULL) && (editor->project->root == dir); + if (dir.isNull()) { + return; + } + bool already_open = ( + (editor != NULL && editor != nullptr) + && (editor->project != NULL && editor->project != nullptr) + && (editor->project->root == dir) + ); if (!already_open) { editor->project = new Project; editor->project->root = dir; + setWindowTitle(editor->project->getProjectTitle() + " - pretmap"); populateMapList(); setMap(getDefaultMap()); } else { + setWindowTitle(editor->project->getProjectTitle() + " - pretmap"); populateMapList(); } } QString MainWindow::getDefaultMap() { - QSettings settings; - QString key = "project:" + editor->project->root; - if (settings.contains(key)) { - QMap qmap = settings.value(key).toMap(); - if (qmap.contains("recent_map")) { - QString map_name = qmap.value("recent_map").toString(); - return map_name; + if (editor && editor->project) { + QList *names = editor->project->groupedMapNames; + if (names) { + QSettings settings; + QString key = "project:" + editor->project->root; + if (settings.contains(key)) { + QMap qmap = settings.value(key).toMap(); + if (qmap.contains("recent_map")) { + QString map_name = qmap.value("recent_map").toString(); + for (int i = 0; i < names->length(); i++) { + if (names->value(i)->contains(map_name)) { + return map_name; + } + } + } + } + // Failing that, just get the first map in the list. + for (int i = 0; i < names->length(); i++) { + QStringList *list = names->value(i); + if (list->length()) { + return list->value(0); + } + } } } - // Failing that, just get the first map in the list. - for (int i = 0; i < editor->project->groupedMapNames->length(); i++) { - QStringList *list = editor->project->groupedMapNames->value(i); - if (list->length()) { - return list->value(0); - } - } - return NULL; + return QString(); } QString MainWindow::getExistingDirectory(QString dir) { @@ -92,6 +125,7 @@ void MainWindow::on_action_Open_Project_triggered() } void MainWindow::setMap(QString map_name) { + qDebug() << QString("setMap(%1)").arg(map_name); if (map_name.isNull()) { return; } @@ -114,6 +148,7 @@ void MainWindow::setMap(QString map_name) { ui->graphicsView_Objects_Map->setScene(editor->scene); ui->graphicsView_Objects_Map->setSceneRect(editor->scene->sceneRect()); ui->graphicsView_Objects_Map->setFixedSize(editor->scene->width() + 2, editor->scene->height() + 2); + ui->graphicsView_Objects_Map->editor = editor; ui->graphicsView_Metatiles->setScene(editor->scene_metatiles); //ui->graphicsView_Metatiles->setSceneRect(editor->scene_metatiles->sceneRect()); @@ -129,6 +164,10 @@ void MainWindow::setMap(QString map_name) { displayMapProperties(); + setWindowTitle(map_name + " - " + editor->project->getProjectTitle() + " - pretmap"); + + connect(editor->map, SIGNAL(mapChanged(Map*)), this, SLOT(onMapChanged(Map *))); + setRecentMap(map_name); updateMapList(); } @@ -145,11 +184,22 @@ void MainWindow::setRecentMap(QString map_name) { } void MainWindow::displayMapProperties() { + ui->comboBox_Song->clear(); + ui->comboBox_Location->clear(); + ui->comboBox_Visibility->clear(); + ui->comboBox_Weather->clear(); + ui->comboBox_Type->clear(); + ui->comboBox_BattleScene->clear(); + ui->checkBox_ShowLocation->setChecked(false); + if (!editor || !editor->map || !editor->project) { + ui->frame_3->setEnabled(false); + return; + } + ui->frame_3->setEnabled(true); Map *map = editor->map; Project *project = editor->project; QStringList songs = project->getSongNames(); - ui->comboBox_Song->clear(); ui->comboBox_Song->addItems(songs); QString song = map->song; if (!songs.contains(song)) { @@ -157,23 +207,18 @@ void MainWindow::displayMapProperties() { } ui->comboBox_Song->setCurrentText(song); - ui->comboBox_Location->clear(); ui->comboBox_Location->addItems(project->getLocations()); ui->comboBox_Location->setCurrentText(map->location); - ui->comboBox_Visibility->clear(); ui->comboBox_Visibility->addItems(project->getVisibilities()); ui->comboBox_Visibility->setCurrentText(map->visibility); - ui->comboBox_Weather->clear(); ui->comboBox_Weather->addItems(project->getWeathers()); ui->comboBox_Weather->setCurrentText(map->weather); - ui->comboBox_Type->clear(); ui->comboBox_Type->addItems(project->getMapTypes()); ui->comboBox_Type->setCurrentText(map->type); - ui->comboBox_BattleScene->clear(); ui->comboBox_BattleScene->addItems(project->getBattleScenes()); ui->comboBox_BattleScene->setCurrentText(map->battle_scene); @@ -182,40 +227,54 @@ void MainWindow::displayMapProperties() { void MainWindow::on_comboBox_Song_activated(const QString &song) { - editor->map->song = song; + if (editor && editor->map) { + editor->map->song = song; + } } void MainWindow::on_comboBox_Location_activated(const QString &location) { - editor->map->location = location; + if (editor && editor->map) { + editor->map->location = location; + } } void MainWindow::on_comboBox_Visibility_activated(const QString &visibility) { - editor->map->visibility = visibility; + if (editor && editor->map) { + editor->map->visibility = visibility; + } } void MainWindow::on_comboBox_Weather_activated(const QString &weather) { - editor->map->weather = weather; + if (editor && editor->map) { + editor->map->weather = weather; + } } void MainWindow::on_comboBox_Type_activated(const QString &type) { - editor->map->type = type; + if (editor && editor->map) { + editor->map->type = type; + } } void MainWindow::on_comboBox_BattleScene_activated(const QString &battle_scene) { - editor->map->battle_scene = battle_scene; + if (editor && editor->map) { + editor->map->battle_scene = battle_scene; + } } void MainWindow::on_checkBox_ShowLocation_clicked(bool checked) { - if (checked) { - editor->map->show_location = "TRUE"; - } else { - editor->map->show_location = "FALSE"; + if (editor && editor->map) { + if (checked) { + editor->map->show_location = "TRUE"; + } else { + editor->map->show_location = "FALSE"; + } } } @@ -281,7 +340,7 @@ void MainWindow::on_mapList_activated(const QModelIndex &index) if (!data.isNull()) { setMap(data.toString()); } - updateMapList(); + //updateMapList(); } void MainWindow::markAllEdited(QAbstractItemModel *model) { @@ -307,7 +366,8 @@ void MainWindow::markEdited(QModelIndex index) { if (editor->project->map_cache->contains(map_name)) { // Just mark anything that's been opened for now. // TODO if (project->getMap()->saved) - ui->mapList->setExpanded(index, true); + //ui->mapList->setExpanded(index, true); + ui->mapList->setExpanded(index, editor->project->map_cache->value(map_name)->hasUnsavedChanges()); } } } @@ -334,6 +394,7 @@ void MainWindow::redo() { void MainWindow::on_action_Save_triggered() { editor->save(); + updateMapList(); } void MainWindow::on_tabWidget_2_currentChanged(int index) @@ -368,3 +429,231 @@ void MainWindow::on_actionRedo_triggered() { redo(); } + +void MainWindow::on_toolButton_newObject_clicked() +{ + if (editor) { + DraggablePixmapItem *object = editor->addNewEvent(); + if (object) { + //if (editor->selected_events->length()) { + editor->selectMapObject(object, true); + //} + } + updateSelectedObjects(); + } +} + +// Should probably just pass layout and let the editor work it out +void MainWindow::updateSelectedObjects() { + + QList *all_events = editor->getObjects(); + QList *events = all_events; + + if (editor->selected_events && editor->selected_events->length()) { + events = editor->selected_events; + } + + QMap map_obj_gfx_constants = editor->project->getMapObjGfxConstants(); + + QList frames; + + for (DraggablePixmapItem *item : *events) { + ObjectPropertiesFrame *frame = new ObjectPropertiesFrame; +// frame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + QSpinBox *x = frame->ui->spinBox_x; + QSpinBox *y = frame->ui->spinBox_y; + QSpinBox *z = frame->ui->spinBox_z; + + x->setValue(item->event->x()); + connect(x, SIGNAL(valueChanged(QString)), item, SLOT(set_x(QString))); + connect(item, SIGNAL(xChanged(int)), x, SLOT(setValue(int))); + + y->setValue(item->event->y()); + connect(y, SIGNAL(valueChanged(QString)), item, SLOT(set_y(QString))); + connect(item, SIGNAL(yChanged(int)), y, SLOT(setValue(int))); + + z->setValue(item->event->elevation()); + connect(z, SIGNAL(valueChanged(QString)), item, SLOT(set_elevation(QString))); + connect(item, SIGNAL(elevationChanged(int)), z, SLOT(setValue(int))); + + QFont font; + font.setCapitalization(QFont::Capitalize); + frame->ui->label_name->setFont(font); + QString event_type = item->event->get("event_type"); + QString map_name = item->event->get("map_name"); + frame->ui->label_name->setText( + QString("%1 %2 %3") + .arg(map_name) + .arg(event_type) + .arg(editor->project->getMap(map_name)->events.value(event_type).indexOf(item->event) + 1) + ); + + frame->ui->label_spritePixmap->setPixmap(item->event->pixmap); + connect(item, SIGNAL(spriteChanged(QPixmap)), frame->ui->label_spritePixmap, SLOT(setPixmap(QPixmap))); + + frame->ui->sprite->setVisible(false); + + QMap field_labels; + field_labels["script_label"] = "Script"; + field_labels["event_flag"] = "Event Flag"; + field_labels["replacement"] = "Replacement"; + field_labels["property"] = "Property"; + field_labels["sight_radius"] = "Sight Radius"; + field_labels["destination_warp"] = "Destination Warp"; + field_labels["destination_map"] = "Destination Map"; + field_labels["coord_unknown1"] = "Unknown 1"; + field_labels["coord_unknown2"] = "Unknown 2"; + field_labels["type"] = "Type"; + field_labels["item"] = "Item"; + field_labels["item_unknown5"] = "Unknown 5"; + field_labels["item_unknown6"] = "Unknown 6"; + + QStringList fields; + + if (event_type == "object") { + + frame->ui->sprite->setVisible(true); + frame->ui->comboBox_sprite->addItems(map_obj_gfx_constants.keys()); + frame->ui->comboBox_sprite->setCurrentText(item->event->get("sprite")); + connect(frame->ui->comboBox_sprite, SIGNAL(activated(QString)), item, SLOT(set_sprite(QString))); + + /* + frame->ui->script->setVisible(true); + frame->ui->comboBox_script->addItem(item->event->get("script_label")); + frame->ui->comboBox_script->setCurrentText(item->event->get("script_label")); + //item->bind(frame->ui->comboBox_script, "script_label"); + connect(frame->ui->comboBox_script, SIGNAL(activated(QString)), item, SLOT(set_script(QString))); + //connect(frame->ui->comboBox_script, static_cast(&QComboBox::activated), item, [item](QString script_label){ item->event->put("script_label", script_label); }); + //connect(item, SIGNAL(scriptChanged(QString)), frame->ui->comboBox_script, SLOT(setValue(QString))); + */ + + fields << "script_label"; + fields << "event_flag"; + fields << "replacement"; + fields << "property"; + fields << "sight_radius"; + } + else if (event_type == "warp") { + fields << "destination_warp"; + fields << "destination_map"; + } + else if (event_type == "trap") { + fields << "script_label"; + fields << "coord_unknown1"; + fields << "coord_unknown2"; + } + else if (event_type == "sign") { + fields << "type"; + fields << "script_label"; + } + else if (event_type == "hidden item") { + fields << "type"; + fields << "item"; + fields << "item_unknown5"; + fields << "item_unknown6"; + } + + for (QString key : fields) { + QWidget *widget = new QWidget(frame); + QFormLayout *fl = new QFormLayout(widget); + fl->setContentsMargins(9, 0, 9, 0); + QComboBox *combo = new QComboBox(widget); + combo->setEditable(true); + + QString value = item->event->get(key); + if (key == "destination_map") { + if (!editor->project->mapNames->contains(value)) { + combo->addItem(value); + } + combo->addItems(*editor->project->mapNames); + } else { + combo->addItem(value); + } + combo->setCurrentText(value); + + fl->addRow(new QLabel(field_labels[key], widget), combo); + widget->setLayout(fl); + frame->layout()->addWidget(widget); + + item->bind(combo, key); + } + + frames.append(frame); + + } + + //int scroll = ui->scrollArea_4->verticalScrollBar()->value(); + + QWidget *target = ui->scrollAreaWidgetContents; + + if (target->children().length()) { + qDeleteAll(target->children()); + } + + QVBoxLayout *layout = new QVBoxLayout(target); + target->setLayout(layout); + ui->scrollArea_4->setWidgetResizable(true); + ui->scrollArea_4->setWidget(target); + + for (ObjectPropertiesFrame *frame : frames) { + layout->addWidget(frame); + } + + layout->addStretch(1); + + // doesn't work + //QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + //ui->scrollArea_4->ensureVisible(0, scroll); +} + +void MainWindow::on_toolButton_deleteObject_clicked() +{ + if (editor && editor->selected_events) { + if (editor->selected_events->length()) { + for (DraggablePixmapItem *item : *editor->selected_events) { + editor->deleteEvent(item->event); + if (editor->scene->items().contains(item)) { + editor->scene->removeItem(item); + } + editor->selected_events->removeOne(item); + } + updateSelectedObjects(); + } + } +} + +void MainWindow::on_toolButton_Paint_clicked() +{ + editor->map_edit_mode = "paint"; + checkToolButtons(); +} + +void MainWindow::on_toolButton_Select_clicked() +{ + editor->map_edit_mode = "select"; + checkToolButtons(); +} + +void MainWindow::on_toolButton_Fill_clicked() +{ + editor->map_edit_mode = "fill"; + checkToolButtons(); +} + +void MainWindow::on_toolButton_Dropper_clicked() +{ + editor->map_edit_mode = "pick"; + checkToolButtons(); +} + +void MainWindow::checkToolButtons() { + ui->toolButton_Paint->setChecked(editor->map_edit_mode == "paint"); + ui->toolButton_Select->setChecked(editor->map_edit_mode == "select"); + ui->toolButton_Fill->setChecked(editor->map_edit_mode == "fill"); + ui->toolButton_Dropper->setChecked(editor->map_edit_mode == "pick"); +} + +void MainWindow::onMapChanged(Map *map) { + updateMapList(); +} diff --git a/mainwindow.h b/mainwindow.h index 0d79638a..6e0b5bcf 100755 --- a/mainwindow.h +++ b/mainwindow.h @@ -32,6 +32,8 @@ private slots: void undo(); void redo(); + void onMapChanged(Map *map); + void on_action_Save_triggered(); void on_tabWidget_2_currentChanged(int index); void on_action_Exit_triggered(); @@ -49,9 +51,23 @@ private slots: void on_actionRedo_triggered(); + void on_toolButton_newObject_clicked(); + + void on_toolButton_deleteObject_clicked(); + + void updateSelectedObjects(); + + void on_toolButton_Paint_clicked(); + + void on_toolButton_Select_clicked(); + + void on_toolButton_Fill_clicked(); + + void on_toolButton_Dropper_clicked(); + private: Ui::MainWindow *ui; - Editor *editor; + Editor *editor = NULL; void setMap(QString); void populateMapList(); QString getExistingDirectory(QString); @@ -64,6 +80,7 @@ private: void updateMapList(); void displayMapProperties(); + void checkToolButtons(); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index adb7c468..67baef37 100755 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 1019 - 666 + 1117 + 747 @@ -17,7 +17,7 @@ - MainWindow + pretmap @@ -60,7 +60,7 @@ - 1 + 0 false @@ -76,7 +76,7 @@ Map - + 0 @@ -89,349 +89,541 @@ 0 - - 0 + + 6 Qt::Horizontal - - - - 1 - 0 - + + + QFrame::StyledPanel - - true + + QFrame::Raised - - - - 0 - 0 - 571 - 564 - + + 1 + + + + 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + true - - - 166 - 16 - + + + 0 + 0 + 31 + 31 + - - - - - - Qt::Vertical + + Paint - - - 16 - 166 - + + + :/icons/pencil.ico:/icons/pencil.ico - - - - - - Qt::Horizontal + + true - - - 166 - 16 - + + true - - - - - - Qt::Vertical - - - - 16 - 166 - - - - - - - - - 0 - 0 - - - + false - - - + + + true + + + + 30 + 0 + 31 + 31 + + + + Select + + + + :/icons/cursor.ico:/icons/cursor.ico + + + true + + + + + + 60 + 0 + 31 + 31 + + + + Fill + + + + :/icons/fill_color.ico:/icons/fill_color.ico + + + true + + + + + + 90 + 0 + 31 + 31 + + + + Dropper + + + + :/icons/pipette.ico:/icons/pipette.ico + + + true + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 1 + 0 + + + + true + + + + + 0 + 0 + 617 + 602 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + false + + + + + + + Qt::Horizontal + + + + 166 + 16 + + + + + + + + Qt::Vertical + + + + 16 + 166 + + + + + + + + Qt::Horizontal + + + + 166 + 16 + + + + + + + + Qt::Vertical + + + + 16 + 166 + + + + + + + + + + + + - - - true + + + QFrame::StyledPanel - - - 0 - 0 - + + QFrame::Raised - - - 156 - 0 - - - - 1 - - - - - 0 - 0 - + + + 0 - - Blocks - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + 156 + 0 + + + + 0 + + 0 0 - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustIgnored - - - true - - - - true + + Blocks + + + + 0 - - - 0 - 0 - 81 - 28 - + + 0 - - - 0 - 0 - + + 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - + + 0 + + + 0 + + + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + + + true + + true + + + 0 + 0 + 186 + 609 + + - + 0 0 - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - QAbstractScrollArea::AdjustIgnored - + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustIgnored + + + + - - + + + + + + + true + + + + 0 + 0 + + + + Collision + + + + + 20 + 60 + 111 + 20 + + + + Qt::Horizontal + + + + + + 0 + 80 + 151 + 101 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 47 + 13 + + + + Elevation + + + + + + 10 + 30 + 131 + 61 + + + + + + + + 0 + 0 + 151 + 61 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 47 + 13 + + + + Collision + + + + + + 40 + 30 + 66 + 18 + + + - - - - - - true - - - - 0 - 0 - - - - Collision - - - - - 20 - 60 - 111 - 20 - - - - Qt::Horizontal - - - - - - 0 - 80 - 151 - 101 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 10 - 10 - 47 - 13 - - - - Elevation - - - - - 10 - 30 - 131 - 61 - - - - - - - - 0 - 0 - 151 - 61 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 10 - 10 - 47 - 13 - - - - Collision - - - - - - 40 - 30 - 66 - 18 - - - - - + + @@ -459,6 +651,12 @@ + + + 0 + 0 + + Qt::Horizontal @@ -477,8 +675,8 @@ 0 0 - 571 - 564 + 385 + 638 @@ -498,7 +696,7 @@ 0 - + Qt::Horizontal @@ -511,7 +709,7 @@ - + Qt::Horizontal @@ -524,7 +722,7 @@ - + Qt::Vertical @@ -537,7 +735,7 @@ - + Qt::Vertical @@ -550,7 +748,7 @@ - + 0 @@ -562,7 +760,7 @@ - + true @@ -574,16 +772,92 @@ - 156 + 444 0 - + Selected + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + QAbstractScrollArea::AdjustIgnored + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 416 + 557 + + + + + 0 + 0 + + + + + + + + + @@ -600,32 +874,88 @@ QFrame::Raised - - - - 0 - 0 - 31 - 31 - + + + 0 - - New + + 0 - - - - - 100 - 0 - 31 - 31 - + + 0 - - Delete + + 0 - + + + + + 0 + 0 + + + + + 40 + 32 + + + + New + + + + :/icons/add.ico:/icons/add.ico + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 0 + 0 + + + + + 40 + 32 + + + + Delete + + + + :/icons/delete.ico:/icons/delete.ico + + + Qt::ToolButtonTextBesideIcon + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -639,6 +969,9 @@ Attributes + + false + 10 @@ -753,6 +1086,9 @@ 22 + + true + @@ -763,6 +1099,9 @@ 22 + + true + @@ -773,6 +1112,9 @@ 22 + + true + @@ -783,6 +1125,9 @@ 22 + + true + @@ -793,6 +1138,9 @@ 22 + + true + @@ -803,6 +1151,9 @@ 22 + + true + @@ -842,8 +1193,8 @@ 0 0 - 1019 - 21 + 1117 + 20 @@ -920,10 +1271,7 @@ Redo - - 50 - false - + Ctrl+Y @@ -931,6 +1279,13 @@ + + + GraphicsView + QGraphicsView +
graphicsview.h
+
+
diff --git a/map.cpp b/map.cpp index 941838ff..c83dc532 100755 --- a/map.cpp +++ b/map.cpp @@ -3,9 +3,11 @@ #include #include #include +#include Map::Map(QObject *parent) : QObject(parent) { + blockdata = new Blockdata; cached_blockdata = new Blockdata; cached_collision = new Blockdata; cached_border = new Blockdata; @@ -22,8 +24,8 @@ int Map::getHeight() { return height.toInt(nullptr, 0); } -Tileset* Map::getBlockTileset(uint metatile_index) { - uint primary_size = 0x200;//tileset_primary->metatiles->length(); +Tileset* Map::getBlockTileset(int metatile_index) { + int primary_size = 0x200;//tileset_primary->metatiles->length(); if (metatile_index < primary_size) { return tileset_primary; } else { @@ -31,23 +33,43 @@ Tileset* Map::getBlockTileset(uint metatile_index) { } } -QImage Map::getMetatileTile(uint tile) { - uint primary_size = 0x200;//tileset_primary->metatiles->length(); - if (tile < primary_size) { - return tileset_primary->tiles->value(tile); +QList> Map::getBlockPalettes(int metatile_index) { + QList> palettes; + for (int i = 0; i < 6; i++) { + palettes.append(tileset_primary->palettes->at(i)); + } + for (int i = 6; i < tileset_secondary->palettes->length(); i++) { + palettes.append(tileset_secondary->palettes->at(i)); + } + return palettes; +} + +int Map::getBlockIndex(int index) { + int primary_size = 0x200; + if (index < primary_size) { + return index; } else { - return tileset_secondary->tiles->value(tile - primary_size); + return index - primary_size; } } -Metatile* Map::getMetatile(uint index) { - uint primary_size = 0x200;//tileset_primary->metatiles->length(); - if (index < primary_size) { - return tileset_primary->metatiles->value(index); - } else { - //qDebug() << QString("secondary tileset: %1").arg(index - primary_size, 0, 16); - return tileset_secondary->metatiles->value(index - primary_size); +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) { @@ -93,28 +115,38 @@ QImage Map::getElevationMetatileImage(int elevation) { return metatile_image; } -QImage Map::getMetatileImage(uint tile) { +QImage Map::getMetatileImage(int tile) { QImage metatile_image(16, 16, QImage::Format_RGBA8888); Metatile* metatile = getMetatile(tile); - if (metatile == NULL) { + 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++) { - //qDebug() << QString("x=%1 y=%2 layer=%3").arg(x).arg(y).arg(layer); - Tile tile = metatile->tiles->value((y * 2) + x + (layer * 4)); - QImage tile_image = getMetatileTile(tile.tile); - QList palette = blockTileset->palettes->value(tile.palette); - for (int j = 0; j < palette.length(); j++) { - tile_image.setColor(j, palette.value(j)); - } + Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4)); + QImage tile_image = getMetatileTile(tile_.tile); + //if (tile_image.isNull()) { + // continue; + //} + //if (blockTileset->palettes) { + QList palette = palettes.value(tile_.palette); + for (int j = 0; j < palette.length(); j++) { + tile_image.setColor(j, palette.value(j)); + } + //} //QVector vector = palette.toVector(); //tile_image.setColorTable(vector); if (layer > 0) { @@ -122,43 +154,66 @@ QImage Map::getMetatileImage(uint tile) { color.setAlpha(0); tile_image.setColor(15, color.rgba()); } - QPainter metatile_painter(&metatile_image); QPoint origin = QPoint(x*8, y*8); - metatile_painter.drawImage(origin, tile_image.mirrored(tile.xflip == 1, tile.yflip == 1)); - metatile_painter.end(); + 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; + } + if (blockdata == NULL || blockdata == nullptr) { + return true; + } + if (cache->blocks == NULL || cache->blocks == nullptr) { + return true; + } + if (blockdata->blocks == NULL || blockdata->blocks == nullptr) { + return true; + } if (cache->blocks->length() <= i) { return true; } + if (blockdata->blocks->length() <= i) { + return true; + } return blockdata->blocks->value(i) != cache->blocks->value(i); } void Map::cacheBorder() { + if (cached_border) delete cached_border; cached_border = new Blockdata; - for (int i = 0; i < border->blocks->length(); i++) { - Block block = border->blocks->value(i); - cached_border->blocks->append(block); + if (border && border->blocks) { + for (int i = 0; i < border->blocks->length(); i++) { + Block block = border->blocks->value(i); + cached_border->blocks->append(block); + } } } void Map::cacheBlockdata() { + if (cached_blockdata) delete cached_blockdata; cached_blockdata = new Blockdata; - for (int i = 0; i < blockdata->blocks->length(); i++) { - Block block = blockdata->blocks->value(i); - cached_blockdata->blocks->append(block); + if (blockdata && blockdata->blocks) { + for (int i = 0; i < blockdata->blocks->length(); i++) { + Block block = blockdata->blocks->value(i); + cached_blockdata->blocks->append(block); + } } } void Map::cacheCollision() { + if (cached_collision) delete cached_collision; cached_collision = new Blockdata; - for (int i = 0; i < blockdata->blocks->length(); i++) { - Block block = blockdata->blocks->value(i); - cached_collision->blocks->append(block); + if (blockdata && blockdata->blocks) { + for (int i = 0; i < blockdata->blocks->length(); i++) { + Block block = blockdata->blocks->value(i); + cached_collision->blocks->append(block); + } } } @@ -174,9 +229,13 @@ QPixmap Map::renderCollision() { collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888); changed_any = true; } + if (!(blockdata && blockdata->blocks && width_ && height_)) { + collision_pixmap = collision_pixmap.fromImage(collision_image); + return collision_pixmap; + } QPainter painter(&collision_image); for (int i = 0; i < blockdata->blocks->length(); i++) { - if (!blockChanged(i, cached_collision)) { + if (cached_collision && !blockChanged(i, cached_collision)) { continue; } changed_any = true; @@ -184,8 +243,8 @@ QPixmap Map::renderCollision() { QImage metatile_image = getMetatileImage(block.tile); QImage collision_metatile_image = getCollisionMetatileImage(block); QImage elevation_metatile_image = getElevationMetatileImage(block); - int map_y = i / width_; - int map_x = i % width_; + int map_y = width_ ? i / width_ : 0; + int map_x = width_ ? i % width_ : 0; QPoint metatile_origin = QPoint(map_x * 16, map_y * 16); painter.setOpacity(1); painter.drawImage(metatile_origin, metatile_image); @@ -238,6 +297,11 @@ QPixmap Map::render() { image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888); changed_any = true; } + if (!(blockdata && blockdata->blocks && width_ && height_)) { + pixmap = pixmap.fromImage(image); + return pixmap; + } + QPainter painter(&image); for (int i = 0; i < blockdata->blocks->length(); i++) { if (!blockChanged(i, cached_blockdata)) { @@ -246,8 +310,8 @@ QPixmap Map::render() { changed_any = true; Block block = blockdata->blocks->value(i); QImage metatile_image = getMetatileImage(block.tile); - int map_y = i / width_; - int map_x = i % width_; + int map_y = width_ ? i / width_ : 0; + int map_x = width_ ? i % width_ : 0; QPoint metatile_origin = QPoint(map_x * 16, map_y * 16); painter.drawImage(metatile_origin, metatile_image); } @@ -267,6 +331,10 @@ QPixmap Map::renderBorder() { border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888); changed_any = true; } + if (!(border && border->blocks)) { + border_pixmap = border_pixmap.fromImage(border_image); + return border_pixmap; + } QPainter painter(&border_image); for (int i = 0; i < border->blocks->length(); i++) { if (!blockChanged(i, cached_border)) { @@ -371,6 +439,9 @@ void Map::drawSelection(int i, int w, QPainter *painter) { } QPixmap Map::renderMetatiles() { + if (!tileset_primary || !tileset_primary->metatiles || !tileset_secondary || !tileset_secondary->metatiles) { + return QPixmap(); + } int primary_length = tileset_primary->metatiles->length(); int length_ = primary_length + tileset_secondary->metatiles->length(); int width_ = 8; @@ -378,7 +449,7 @@ QPixmap Map::renderMetatiles() { QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888); QPainter painter(&image); for (int i = 0; i < length_; i++) { - uint tile = i; + int tile = i; if (i >= primary_length) { tile += 0x200 - primary_length; } @@ -396,17 +467,21 @@ QPixmap Map::renderMetatiles() { } Block* Map::getBlock(int x, int y) { - if (x >= 0 && x < getWidth()) - if (y >= 0 && y < getHeight()) { - int i = y * getWidth() + x; - return new Block(blockdata->blocks->value(i)); + if (blockdata && blockdata->blocks) { + if (x >= 0 && x < getWidth()) + if (y >= 0 && y < getHeight()) { + int i = y * getWidth() + x; + return new Block(blockdata->blocks->value(i)); + } } return NULL; } void Map::_setBlock(int x, int y, Block block) { int i = y * getWidth() + x; - blockdata->blocks->replace(i, block); + if (blockdata && blockdata->blocks) { + blockdata->blocks->replace(i, block); + } } void Map::_floodFill(int x, int y, uint tile) { @@ -542,22 +617,33 @@ void Map::_floodFillCollisionElevation(int x, int y, uint collision, uint elevat void Map::undo() { - Blockdata *commit = history.pop(); - if (commit != NULL) { - blockdata->copyFrom(commit); + if (blockdata) { + Blockdata *commit = history.pop(); + if (commit != NULL) { + blockdata->copyFrom(commit); + emit mapChanged(this); + } } } void Map::redo() { - Blockdata *commit = history.next(); - if (commit != NULL) { - blockdata->copyFrom(commit); + if (blockdata) { + Blockdata *commit = history.next(); + if (commit != NULL) { + blockdata->copyFrom(commit); + emit mapChanged(this); + } } } void Map::commit() { - Blockdata* commit = blockdata->copy(); - history.push(commit); + if (blockdata) { + if (!blockdata->equals(history.history.at(history.head))) { + Blockdata* commit = blockdata->copy(); + history.push(commit); + emit mapChanged(this); + } + } } void Map::setBlock(int x, int y, Block block) { @@ -598,3 +684,30 @@ void Map::floodFillCollisionElevation(int x, int y, uint collision, uint elevati commit(); } } + +QList Map::getAllEvents() { + QList all; + for (QList list : events.values()) { + all += list; + } + return all; +} + +QList Map::getEventsByType(QString type) +{ + return events.value(type); +} + +void Map::removeEvent(Event *event) { + for (QString key : events.keys()) { + events[key].removeAll(event); + } +} + +void Map::addEvent(Event *event) { + events[event->get("event_type")].append(event); +} + +bool Map::hasUnsavedChanges() { + return !history.isSaved(); +} diff --git a/map.h b/map.h index aad182cb..0902fb20 100755 --- a/map.h +++ b/map.h @@ -14,10 +14,11 @@ template class History { public: QList history; - int head; + int head = -1; + int saved = -1; History() { - head = -1; + } T pop() { if (head > 0) { @@ -35,9 +36,18 @@ public: while (head + 1 < history.length()) { history.removeLast(); } + if (saved > head) { + saved = -1; + } history.append(commit); head++; } + void save() { + saved = head; + } + bool isSaved() { + return saved == head; + } }; class Connection { @@ -79,18 +89,19 @@ public: QString tileset_primary_label; QString tileset_secondary_label; - Tileset *tileset_primary; - Tileset *tileset_secondary; + Tileset *tileset_primary = NULL; + Tileset *tileset_secondary = NULL; - Blockdata* blockdata; + Blockdata* blockdata = NULL; public: int getWidth(); int getHeight(); - Tileset* getBlockTileset(uint); - Metatile* getMetatile(uint); - QImage getMetatileImage(uint); - QImage getMetatileTile(uint); + Tileset* getBlockTileset(int); + int getBlockIndex(int index); + Metatile* getMetatile(int); + QImage getMetatileImage(int); + QImage getMetatileTile(int); QPixmap render(); QPixmap renderMetatiles(); @@ -107,9 +118,9 @@ public: void drawSelection(int i, int w, QPainter *painter); bool blockChanged(int, Blockdata*); - Blockdata* cached_blockdata; + Blockdata* cached_blockdata = NULL; void cacheBlockdata(); - Blockdata* cached_collision; + Blockdata* cached_collision = NULL; void cacheCollision(); QImage image; QPixmap pixmap; @@ -141,23 +152,30 @@ public: QString coord_events_label; QString bg_events_label; - QList object_events; - QList warps; - QList coord_events; - QList signs; - QList hidden_items; + QList getAllEvents(); + QList getEventsByType(QString type); + void removeEvent(Event *event); + void addEvent(Event *event); + QMap> events; QList connections; QPixmap renderConnection(Connection); QImage border_image; QPixmap border_pixmap; - Blockdata *border; - Blockdata *cached_border; + Blockdata *border = NULL; + Blockdata *cached_border = NULL; QPixmap renderBorder(); void cacheBorder(); + bool hasUnsavedChanges(); + + QList > getBlockPalettes(int metatile_index); + signals: + void paintTileChanged(Map *map); + void paintCollisionChanged(Map *map); + void mapChanged(Map *map); public slots: }; diff --git a/metatile.h b/metatile.h index 851d04b7..2712602d 100755 --- a/metatile.h +++ b/metatile.h @@ -9,7 +9,7 @@ class Metatile public: Metatile(); public: - QList *tiles; + QList *tiles = NULL; int attr; }; diff --git a/objectpropertiesframe.cpp b/objectpropertiesframe.cpp new file mode 100755 index 00000000..09e71ffa --- /dev/null +++ b/objectpropertiesframe.cpp @@ -0,0 +1,14 @@ +#include "objectpropertiesframe.h" +#include "ui_objectpropertiesframe.h" + +ObjectPropertiesFrame::ObjectPropertiesFrame(QWidget *parent) : + QFrame(parent), + ui(new Ui::ObjectPropertiesFrame) +{ + ui->setupUi(this); +} + +ObjectPropertiesFrame::~ObjectPropertiesFrame() +{ + delete ui; +} diff --git a/objectpropertiesframe.h b/objectpropertiesframe.h new file mode 100755 index 00000000..34b5f78e --- /dev/null +++ b/objectpropertiesframe.h @@ -0,0 +1,22 @@ +#ifndef OBJECTPROPERTIESFRAME_H +#define OBJECTPROPERTIESFRAME_H + +#include + +namespace Ui { +class ObjectPropertiesFrame; +} + +class ObjectPropertiesFrame : public QFrame +{ + Q_OBJECT + +public: + explicit ObjectPropertiesFrame(QWidget *parent = 0); + ~ObjectPropertiesFrame(); + +public: + Ui::ObjectPropertiesFrame *ui; +}; + +#endif // OBJECTPROPERTIESFRAME_H diff --git a/objectpropertiesframe.ui b/objectpropertiesframe.ui new file mode 100755 index 00000000..c11aaa6d --- /dev/null +++ b/objectpropertiesframe.ui @@ -0,0 +1,250 @@ + + + ObjectPropertiesFrame + + + + 0 + 0 + 284 + 146 + + + + + 0 + 0 + + + + + 284 + 90 + + + + Frame + + + Qt::LeftToRight + + + QFrame::Box + + + QFrame::Raised + + + 1 + + + + + + + 0 + 0 + + + + + + + + 0 + 0 + + + + + 64 + 64 + + + + QFrame::Box + + + QFrame::Sunken + + + + + + false + + + Qt::AlignCenter + + + -1 + + + + + + + + + Object 1 + + + + + + + + + + + X + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + -32768 + + + 32767 + + + + + + + + + + + Y + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + -32768 + + + 32767 + + + + + + + + + + + Z + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 15 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + 0 + 0 + + + + + 9 + + + 0 + + + 0 + + + + + Sprite + + + comboBox_sprite + + + + + + + true + + + + 0 + 0 + + + + true + + + + + + 25 + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + + + + spinBox_x + spinBox_y + spinBox_z + comboBox_sprite + + + + diff --git a/pretmap.pro b/pretmap.pro index 3b951a3c..80d4a716 100755 --- a/pretmap.pro +++ b/pretmap.pro @@ -23,7 +23,9 @@ SOURCES += main.cpp\ metatile.cpp \ tile.cpp \ event.cpp \ - editor.cpp + editor.cpp \ + objectpropertiesframe.cpp \ + graphicsview.cpp HEADERS += mainwindow.h \ project.h \ @@ -35,9 +37,12 @@ HEADERS += mainwindow.h \ metatile.h \ tile.h \ event.h \ - editor.h + editor.h \ + objectpropertiesframe.h \ + graphicsview.h -FORMS += mainwindow.ui +FORMS += mainwindow.ui \ + objectpropertiesframe.ui RESOURCES += \ resources/images.qrc diff --git a/project.cpp b/project.cpp index 93602ca7..a82a4090 100755 --- a/project.cpp +++ b/project.cpp @@ -15,12 +15,17 @@ Project::Project() { groupNames = new QStringList; groupedMapNames = new QList; + mapNames = new QStringList; map_cache = new QMap; tileset_cache = new QMap; } QString Project::getProjectTitle() { - return root.section('/', -1); + if (!root.isNull()) { + return root.section('/', -1); + } else { + return QString(); + } } Map* Project::loadMap(QString map_name) { @@ -35,6 +40,7 @@ Map* Project::loadMap(QString map_name) { readMapEvents(map); loadMapConnections(map); map->commit(); + map->history.save(); map_cache->insert(map_name, map); return map; @@ -43,9 +49,9 @@ Map* Project::loadMap(QString map_name) { void Project::loadMapConnections(Map *map) { map->connections.clear(); if (!map->connections_label.isNull()) { - QString path = root + QString("/data/maps/%1/connections.s").arg(map->name); + QString path = root + QString("/data/maps/%1/connections.inc").arg(map->name); QString text = readTextFile(path); - if (text != NULL) { + if (!text.isNull()) { QList *commands = parse(text); QStringList *list = getLabelValues(commands, map->connections_label); @@ -114,7 +120,10 @@ void Project::readMapHeader(Map* map) { QString label = map->name; Asm *parser = new Asm; - QString header_text = readTextFile(root + "/data/maps/" + label + "/header.s"); + QString header_text = readTextFile(root + "/data/maps/" + label + "/header.inc"); + if (header_text.isNull()) { + return; + } QStringList *header = getLabelValues(parser->parse(header_text), label); map->attributes_label = header->value(0); map->events_label = header->value(1); @@ -133,7 +142,7 @@ void Project::readMapHeader(Map* map) { void Project::saveMapHeader(Map *map) { QString label = map->name; - QString header_path = root + "/data/maps/" + label + "/header.s"; + QString header_path = root + "/data/maps/" + label + "/header.inc"; QString text = ""; text += QString("%1::\n").arg(label); text += QString("\t.4byte %1\n").arg(map->attributes_label); @@ -155,7 +164,10 @@ void Project::saveMapHeader(Map *map) { void Project::readMapAttributes(Map* map) { Asm *parser = new Asm; - QString assets_text = readTextFile(root + "/data/maps/_assets.s"); + QString assets_text = readTextFile(root + "/data/maps/_assets.inc"); + if (assets_text.isNull()) { + return; + } QStringList *attributes = getLabelValues(parser->parse(assets_text), map->attributes_label); map->width = attributes->value(0); map->height = attributes->value(1); @@ -173,7 +185,7 @@ void Project::getTilesets(Map* map) { Tileset* Project::loadTileset(QString label) { Asm *parser = new Asm; - QString headers_text = readTextFile(root + "/data/tilesets/headers.s"); + QString headers_text = readTextFile(root + "/data/tilesets/headers.inc"); QStringList *values = getLabelValues(parser->parse(headers_text), label); Tileset *tileset = new Tileset; tileset->name = label; @@ -193,7 +205,7 @@ Tileset* Project::loadTileset(QString label) { } QString Project::getBlockdataPath(Map* map) { - QString text = readTextFile(root + "/data/maps/_assets.s"); + QString text = readTextFile(root + "/data/maps/_assets.inc"); QStringList *values = getLabelValues(parse(text), map->blockdata_label); QString path; if (!values->isEmpty()) { @@ -205,7 +217,7 @@ QString Project::getBlockdataPath(Map* map) { } QString Project::getMapBorderPath(Map *map) { - QString text = readTextFile(root + "/data/maps/_assets.s"); + QString text = readTextFile(root + "/data/maps/_assets.inc"); QStringList *values = getLabelValues(parse(text), map->border_label); QString path; if (!values->isEmpty()) { @@ -229,6 +241,7 @@ void Project::loadMapBorder(Map *map) { void Project::saveBlockdata(Map* map) { QString path = getBlockdataPath(map); writeBlockdata(path, map->blockdata); + map->history.save(); } void Project::writeBlockdata(QString path, Blockdata *blockdata) { @@ -251,14 +264,18 @@ void Project::saveAllMaps() { void Project::saveMap(Map *map) { saveBlockdata(map); saveMapHeader(map); + saveMapEvents(map); } void Project::loadTilesetAssets(Tileset* tileset) { Asm* parser = new Asm; QString category = (tileset->is_secondary == "TRUE") ? "secondary" : "primary"; + if (tileset->name.isNull()) { + return; + } QString dir_path = root + "/data/tilesets/" + category + "/" + tileset->name.replace("gTileset_", "").toLower(); - QString graphics_text = readTextFile(root + "/data/tilesets/graphics.s"); + QString graphics_text = readTextFile(root + "/data/tilesets/graphics.inc"); QList *graphics = parser->parse(graphics_text); QStringList *tiles_values = getLabelValues(graphics, tileset->tiles_label); QStringList *palettes_values = getLabelValues(graphics, tileset->palettes_label); @@ -288,7 +305,7 @@ void Project::loadTilesetAssets(Tileset* tileset) { QString metatiles_path; QString metatile_attrs_path; - QString metatiles_text = readTextFile(root + "/data/tilesets/metatiles.s"); + QString metatiles_text = readTextFile(root + "/data/tilesets/metatiles.inc"); QList *metatiles_macros = parser->parse(metatiles_text); QStringList *metatiles_values = getLabelValues(metatiles_macros, tileset->metatiles_label); if (!metatiles_values->isEmpty()) { @@ -328,7 +345,7 @@ void Project::loadTilesetAssets(Tileset* tileset) { QList *metatiles = new QList; for (int i = 0; i < num_metatiles; i++) { Metatile *metatile = new Metatile; - int index = i * 16; + int index = i * (2 * 4 * num_layers); for (int j = 0; j < 4 * num_layers; j++) { uint16_t word = data[index++] & 0xff; word += (data[index++] & 0xff) << 8; @@ -342,6 +359,9 @@ void Project::loadTilesetAssets(Tileset* tileset) { metatiles->append(metatile); } tileset->metatiles = metatiles; + } else { + tileset->metatiles = new QList; + qDebug() << QString("Could not open '%1'").arg(metatiles_path); } QFile attrs_file(metatile_attrs_path); @@ -354,6 +374,8 @@ void Project::loadTilesetAssets(Tileset* tileset) { word += (data[i*2 + 1] & 0xff) << 8; tileset->metatiles->value(i)->attr = word; } + } else { + qDebug() << QString("Could not open '%1'").arg(metatile_attrs_path); } // palettes @@ -377,6 +399,11 @@ void Project::loadTilesetAssets(Tileset* tileset) { QRgb color = qRgb(red * 8, green * 8, blue * 8); palette.prepend(color); } + } else { + for (int j = 0; j < 16; j++) { + palette.append(qRgb(j * 16, j * 16, j * 16)); + } + qDebug() << QString("Could not open '%1'").arg(path); } //qDebug() << path; palettes->append(palette); @@ -420,7 +447,8 @@ QString Project::readTextFile(QString path) { QFile file(path); if (!file.open(QIODevice::ReadOnly)) { //QMessageBox::information(0, "Error", QString("Could not open '%1': ").arg(path) + file.errorString()); - return NULL; + qDebug() << QString("Could not open '%1': ").arg(path) + file.errorString(); + return QString(); } QTextStream in(&file); QString text = ""; @@ -434,12 +462,14 @@ void Project::saveTextFile(QString path, QString text) { QFile file(path); if (file.open(QIODevice::WriteOnly)) { file.write(text.toUtf8()); + } else { + qDebug() << QString("Could not open '%1' for writing: ").arg(path) + file.errorString(); } } void Project::readMapGroups() { - QString text = readTextFile(root + "/data/maps/_groups.s"); - if (text == NULL) { + QString text = readTextFile(root + "/data/maps/_groups.inc"); + if (text.isNull()) { return; } Asm *parser = new Asm; @@ -466,12 +496,13 @@ void Project::readMapGroups() { } } - QList *maps = new QList; + QList *groupedMaps = new QList; for (int i = 0; i < groups->length(); i++) { QStringList *list = new QStringList; - maps->append(list); + groupedMaps->append(list); } + QStringList *maps = new QStringList; int group = -1; for (int i = 0; i < commands->length(); i++) { QStringList params = commands->value(i); @@ -481,15 +512,17 @@ void Project::readMapGroups() { } else if (macro == ".4byte") { if (group != -1) { for (int j = 1; j < params.length(); j++) { - QStringList *list = maps->value(group); + QStringList *list = groupedMaps->value(group); list->append(params.value(j)); + maps->append(params.value(j)); } } } } groupNames = groups; - groupedMapNames = maps; + groupedMapNames = groupedMaps; + mapNames = maps; } QList* Project::parse(QString text) { @@ -544,8 +577,8 @@ QStringList Project::getBattleScenes() { QStringList Project::getSongNames() { QStringList names; - QString text = readTextFile(root + "/constants/songs.s"); - if (text != NULL) { + QString text = readTextFile(root + "/constants/songs.inc"); + if (!text.isNull()) { QList *commands = parse(text); for (int i = 0; i < commands->length(); i++) { QStringList params = commands->value(i); @@ -560,8 +593,8 @@ QStringList Project::getSongNames() { QString Project::getSongName(int value) { QStringList names; - QString text = readTextFile(root + "/constants/songs.s"); - if (text != NULL) { + QString text = readTextFile(root + "/constants/songs.inc"); + if (!text.isNull()) { QList *commands = parse(text); for (int i = 0; i < commands->length(); i++) { QStringList params = commands->value(i); @@ -578,8 +611,8 @@ QString Project::getSongName(int value) { QMap Project::getMapObjGfxConstants() { QMap constants; - QString text = readTextFile(root + "/constants/map_object_constants.s"); - if (text != NULL) { + QString text = readTextFile(root + "/constants/map_object_constants.inc"); + if (!text.isNull()) { QList *commands = parse(text); for (int i = 0; i < commands->length(); i++) { QStringList params = commands->value(i); @@ -602,9 +635,9 @@ QString Project::fixGraphicPath(QString path) { return path; } -void Project::loadObjectPixmaps(QList objects) { +void Project::loadObjectPixmaps(QList objects) { bool needs_update = false; - for (ObjectEvent *object : objects) { + for (Event *object : objects) { if (object->pixmap.isNull()) { needs_update = true; break; @@ -616,62 +649,152 @@ void Project::loadObjectPixmaps(QList objects) { QMap constants = getMapObjGfxConstants(); - QString pointers_path = root + "/data/graphics/field_objects/map_object_graphics_info_pointers.s"; - QString pointers_text = readTextFile(pointers_path); - if (pointers_text == NULL) { - return; - } - QString info_path = root + "/data/graphics/field_objects/map_object_graphics_info.s"; - QString info_text = readTextFile(info_path); - if (info_text == NULL) { - return; - } - QString pic_path = root + "/data/graphics/field_objects/map_object_pic_tables.s"; - QString pic_text = readTextFile(pic_path); - if (pic_text == NULL) { - return; - } - QString assets_path = root + "/data/graphics/field_objects/map_object_graphics.s"; - QString assets_text = readTextFile(assets_path); - if (assets_text == NULL) { - return; - } + QString pointers_text = readTextFile(root + "/include/data/field_map_obj/map_object_graphics_info_pointers.h"); + QString info_text = readTextFile(root + "/include/data/field_map_obj/map_object_graphics_info.h"); + QString pic_text = readTextFile(root + "/include/data/field_map_obj/map_object_pic_tables.h"); + QString assets_text = readTextFile(root + "/src/field_map_obj.c"); - QStringList *pointers = getLabelValues(parse(pointers_text), "gMapObjectGraphicsInfoPointers"); - QList *info_commands = parse(info_text); - QList *asset_commands = parse(assets_text); - QList *pic_commands = parse(pic_text); + QStringList pointers = readCArray(pointers_text, "gMapObjectGraphicsInfoPointers"); - for (ObjectEvent *object : objects) { + for (Event *object : objects) { if (!object->pixmap.isNull()) { continue; } - int id = constants.value(object->sprite); - QString info_label = pointers->value(id); - QStringList *info = getLabelValues(info_commands, info_label); - QString pic_label = info->value(12); + QString event_type = object->get("event_type"); + if (event_type == "object") { + object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(0, 0, 16, 16); + } else if (event_type == "warp") { + object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(16, 0, 16, 16); + } else if (event_type == "trap") { + object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(32, 0, 16, 16); + } else if (event_type == "sign" || event_type == "hidden item") { + object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(48, 0, 16, 16); + } - QList *pic = getLabelMacros(pic_commands, pic_label); - for (int i = 0; i < pic->length(); i++) { - QStringList command = pic->value(i); - QString macro = command.value(0); - if (macro == "obj_frame_tiles") { - QString label = command.value(1); - QStringList *incbins = getLabelValues(asset_commands, label); - QString path = incbins->value(0).section('"', 1, 1); + if (event_type == "object") { + + int sprite_id = constants.value(object->get("sprite")); + + QString info_label = pointers.value(sprite_id).replace("&", ""); + QString pic_label = readCArray(info_text, info_label).value(14); + QString gfx_label = readCArray(pic_text, pic_label).value(0); + gfx_label = gfx_label.section(QRegExp("[\\(\\)]"), 1, 1); + QString path = readCIncbin(assets_text, gfx_label); + + if (!path.isNull()) { path = fixGraphicPath(path); QPixmap pixmap(root + "/" + path); - object->pixmap = pixmap; - break; + if (!pixmap.isNull()) { + object->pixmap = pixmap; + } } + } } + +} + +void Project::saveMapEvents(Map *map) { + QString path = root + QString("/data/maps/events/%1.inc").arg(map->name); + QString text = ""; + + text += QString("%1::\n").arg(map->object_events_label); + for (int i = 0; i < map->events["object"].length(); i++) { + Event *object_event = map->events["object"].value(i); + int radius_x = object_event->getInt("radius_x"); + int radius_y = object_event->getInt("radius_y"); + QString radius = QString("%1").arg((radius_x & 0xf) + ((radius_y & 0xf) << 4)); + uint16_t x = object_event->getInt("x"); + uint16_t y = object_event->getInt("y"); + + text += QString("\tobject_event %1").arg(i + 1); + text += QString(", %1").arg(object_event->get("sprite")); + text += QString(", %1").arg(object_event->get("replacement")); + text += QString(", %1").arg(x & 0xff); + text += QString(", %1").arg((x >> 8) & 0xff); + text += QString(", %1").arg(y & 0xff); + text += QString(", %1").arg((y >> 8) & 0xff); + text += QString(", %1").arg(object_event->get("elevation")); + text += QString(", %1").arg(object_event->get("behavior")); + text += QString(", %1").arg(radius); + text += QString(", 0"); + text += QString(", %1").arg(object_event->get("property")); + text += QString(", 0"); + text += QString(", %1").arg(object_event->get("sight_radius")); + text += QString(", 0"); + text += QString(", %1").arg(object_event->get("script_label")); + text += QString(", %1").arg(object_event->get("event_flag")); + text += QString(", 0"); + text += QString(", 0"); + text += "\n"; + } + text += "\n"; + + text += QString("%1::\n").arg(map->warps_label); + for (Event *warp : map->events["warp"]) { + text += QString("\twarp_def %1").arg(warp->get("x")); + text += QString(", %1").arg(warp->get("y")); + text += QString(", %1").arg(warp->get("elevation")); + text += QString(", %1").arg(warp->get("destination_warp")); + text += QString(", %1").arg(warp->get("destination_map")); + text += "\n"; + } + text += "\n"; + + text += QString("%1::\n").arg(map->coord_events_label); + for (Event *coords : map->events["trap"]) { + text += QString("\tcoord_event %1").arg(coords->get("x")); + text += QString(", %1").arg(coords->get("y")); + text += QString(", %1").arg(coords->get("elevation")); + text += QString(", 0"); + text += QString(", %1").arg(coords->get("coord_unknown1")); + text += QString(", %1").arg(coords->get("coord_unknown2")); + text += QString(", 0"); + text += QString(", %1").arg(coords->get("script_label")); + text += "\n"; + } + text += "\n"; + + text += QString("%1::\n").arg(map->bg_events_label); + for (Event *sign : map->events["sign"]) { + text += QString("\tbg_event %1").arg(sign->get("x")); + text += QString(", %1").arg(sign->get("y")); + text += QString(", %1").arg(sign->get("elevation")); + text += QString(", %1").arg(sign->get("type")); + text += QString(", 0"); + text += QString(", %1").arg(sign->get("script_label")); + text += "\n"; + } + for (Event *item : map->events["hidden item"]) { + text += QString("\tbg_event %1").arg(item->get("x")); + text += QString(", %1").arg(item->get("y")); + text += QString(", %1").arg(item->get("elevation")); + text += QString(", %1").arg(item->get("type")); + text += QString(", 0"); + text += QString(", %1").arg(item->get("item")); + text += QString(", %1").arg(item->get("item_unknown5")); + text += QString(", %1").arg(item->get("item_unknown6")); + text += "\n"; + } + text += "\n"; + + text += QString("%1::\n").arg(map->events_label); + text += QString("\tmap_events %1, %2, %3, %4\n") + .arg(map->object_events_label) + .arg(map->warps_label) + .arg(map->coord_events_label) + .arg(map->bg_events_label); + + saveTextFile(path, text); } void Project::readMapEvents(Map *map) { // lazy - QString path = root + QString("/data/maps/events/%1.s").arg(map->name); + QString path = root + QString("/data/maps/events/%1.inc").arg(map->name); QString text = readTextFile(path); + if (text.isNull()) { + return; + } QStringList *labels = getLabelValues(parse(text), map->events_label); map->object_events_label = labels->value(0); @@ -680,10 +803,11 @@ void Project::readMapEvents(Map *map) { map->bg_events_label = labels->value(3); QList *object_events = getLabelMacros(parse(text), map->object_events_label); - map->object_events.clear(); + map->events["object"].clear(); for (QStringList command : *object_events) { if (command.value(0) == "object_event") { - ObjectEvent *object = new ObjectEvent; + Event *object = new Event; + object->put("map_name", map->name); // This macro is not fixed as of writing, but it should take fewer args. bool old_macro = false; if (command.length() >= 20) { @@ -692,96 +816,156 @@ void Project::readMapEvents(Map *map) { command.removeAt(15); command.removeAt(13); command.removeAt(11); - command.removeAt(7); - command.removeAt(5); command.removeAt(1); // id. not 0, but is just the index in the list of objects old_macro = true; } int i = 1; - object->sprite = command.value(i++); - object->replacement = command.value(i++); - object->x_ = command.value(i++); - object->y_ = command.value(i++); - object->elevation_ = command.value(i++); - object->behavior = command.value(i++); + object->put("sprite", command.value(i++)); + object->put("replacement", command.value(i++)); + int16_t x = command.value(i++).toInt(nullptr, 0) | (command.value(i++).toInt(nullptr, 0) << 8); + int16_t y = command.value(i++).toInt(nullptr, 0) | (command.value(i++).toInt(nullptr, 0) << 8); + object->put("x", x); + object->put("y", y); + object->put("elevation", command.value(i++)); + object->put("behavior", command.value(i++)); if (old_macro) { int radius = command.value(i++).toInt(nullptr, 0); - object->radius_x = QString("%1").arg(radius & 0xf); - object->radius_y = QString("%1").arg((radius >> 4) & 0xf); + object->put("radius_x", radius & 0xf); + object->put("radius_y", (radius >> 4) & 0xf); } else { - object->radius_x = command.value(i++); - object->radius_y = command.value(i++); + object->put("radius_x", command.value(i++)); + object->put("radius_y", command.value(i++)); } - object->property = command.value(i++); - object->sight_radius = command.value(i++); - object->script_label = command.value(i++); - object->event_flag = command.value(i++); + object->put("property", command.value(i++)); + object->put("sight_radius", command.value(i++)); + object->put("script_label", command.value(i++)); + object->put("event_flag", command.value(i++)); - map->object_events.append(object); + object->put("event_type", "object"); + map->events["object"].append(object); } } QList *warps = getLabelMacros(parse(text), map->warps_label); - map->warps.clear(); + map->events["warp"].clear(); for (QStringList command : *warps) { if (command.value(0) == "warp_def") { - Warp *warp = new Warp; + Event *warp = new Event; + warp->put("map_name", map->name); int i = 1; - warp->x_ = command.value(i++); - warp->y_ = command.value(i++); - warp->elevation_ = command.value(i++); - warp->destination_warp = command.value(i++); - warp->destination_map = command.value(i++); - map->warps.append(warp); + warp->put("x", command.value(i++)); + warp->put("y", command.value(i++)); + warp->put("elevation", command.value(i++)); + warp->put("destination_warp", command.value(i++)); + warp->put("destination_map", command.value(i++)); + + warp->put("event_type", "warp"); + map->events["warp"].append(warp); } } QList *coords = getLabelMacros(parse(text), map->coord_events_label); - map->coord_events.clear(); + map->events["trap"].clear(); for (QStringList command : *coords) { if (command.value(0) == "coord_event") { - CoordEvent *coord = new CoordEvent; + Event *coord = new Event; + coord->put("map_name", map->name); bool old_macro = false; if (command.length() >= 9) { command.removeAt(7); - command.removeAt(6); command.removeAt(4); old_macro = true; } int i = 1; - coord->x_ = command.value(i++); - coord->y_ = command.value(i++); - coord->elevation_ = command.value(i++); - coord->unknown1 = command.value(i++); - coord->script_label = command.value(i++); - map->coord_events.append(coord); + coord->put("x", command.value(i++)); + coord->put("y", command.value(i++)); + coord->put("elevation", command.value(i++)); + coord->put("coord_unknown1", command.value(i++)); + coord->put("coord_unknown2", command.value(i++)); + coord->put("script_label", command.value(i++)); + //coord_unknown3 + //coord_unknown4 + + coord->put("event_type", "trap"); + map->events["trap"].append(coord); } } - QList *bgs = getLabelMacros(parse(text), map->warps_label); - map->hidden_items.clear(); - map->signs.clear(); + QList *bgs = getLabelMacros(parse(text), map->bg_events_label); + map->events["hidden item"].clear(); + map->events["sign"].clear(); for (QStringList command : *bgs) { if (command.value(0) == "bg_event") { - BGEvent *bg = new BGEvent; + Event *bg = new Event; + bg->put("map_name", map->name); int i = 1; - bg->x_ = command.value(i++); - bg->y_ = command.value(i++); - bg->elevation_ = command.value(i++); - bg->type = command.value(i++); + bg->put("x", command.value(i++)); + bg->put("y", command.value(i++)); + bg->put("elevation", command.value(i++)); + bg->put("type", command.value(i++)); i++; - if (bg->is_item()) { - HiddenItem *item = new HiddenItem(*bg); - item->item = command.value(i++); - item->unknown5 = command.value(i++); - item->unknown6 = command.value(i++); - map->hidden_items.append(item); + if (bg->is_hidden_item()) { + bg->put("item", command.value(i++)); + bg->put("item_unknown5", command.value(i++)); + bg->put("item_unknown6", command.value(i++)); + + bg->put("event_type", "hidden item"); + map->events["hidden item"].append(bg); } else { - Sign *sign = new Sign(*bg); - sign->script_label = command.value(i++); - map->signs.append(sign); + bg->put("script_label", command.value(i++)); + //sign_unknown7 + + bg->put("event_type", "sign"); + map->events["sign"].append(bg); } } } } + +QStringList Project::readCArray(QString text, QString label) { + QStringList list; + + if (label.isNull()) { + return list; + } + + QRegExp *re = new QRegExp(QString("\\b%1\\b\\s*\\[?\\s*\\]?\\s*=\\s*\\{([^\\}]*)\\}").arg(label)); + int pos = re->indexIn(text); + if (pos != -1) { + QString body = re->cap(1); + body = body.replace(QRegExp("\\s*"), ""); + list = body.split(','); + /* + QRegExp *inner = new QRegExp("&?\\b([A-Za-z0-9_\\(\\)]*)\\b,"); + int pos = 0; + while ((pos = inner->indexIn(body, pos)) != -1) { + list << inner->cap(1); + pos += inner->matchedLength(); + } + */ + } + + return list; +} + +QString Project::readCIncbin(QString text, QString label) { + QString path; + + if (label.isNull()) { + return path; + } + + QRegExp *re = new QRegExp(QString( + "\\b%1\\b" + "\\s*\\[?\\s*\\]?\\s*=\\s*" + "INCBIN_[US][0-9][0-9]?" + "\\(\"([^\"]*)\"\\)").arg(label)); + + int pos = re->indexIn(text); + if (pos != -1) { + path = re->cap(1); + } + + return path; +} diff --git a/project.h b/project.h index de3820f5..24811e51 100755 --- a/project.h +++ b/project.h @@ -12,14 +12,15 @@ class Project public: Project(); QString root; - QStringList *groupNames; - QList *groupedMapNames; + QStringList *groupNames = NULL; + QList *groupedMapNames = NULL; + QStringList *mapNames = NULL; QMap *map_cache; Map* loadMap(QString); Map* getMap(QString); - QMap *tileset_cache; + QMap *tileset_cache = NULL; Tileset* loadTileset(QString); Tileset* getTileset(QString); @@ -55,7 +56,7 @@ public: QStringList getMapTypes(); QStringList getBattleScenes(); - void loadObjectPixmaps(QList objects); + void loadObjectPixmaps(QList objects); QMap getMapObjGfxConstants(); QString fixGraphicPath(QString path); @@ -64,6 +65,11 @@ public: void loadMapBorder(Map *map); QString getMapBorderPath(Map *map); + + void saveMapEvents(Map *map); + + QStringList readCArray(QString text, QString label); + QString readCIncbin(QString text, QString label); }; #endif // PROJECT_H diff --git a/resources/icons/add.ico b/resources/icons/add.ico new file mode 100755 index 0000000000000000000000000000000000000000..c23ddb99ea3016c0613ebb7484dcd3385c874c68 GIT binary patch literal 5430 zcmb_g3viXy5#A63m0Ad$!6HmUgy85hL8S8Nr@@V^G}b^5;{>QrLYZjJ3aiFvzHt3E&70xX=Z4IPDZD5D7kX0v ztx12Y!hXR#PXnt2x@EaKsd|@AKbxb0TYsvOm9UK}{q!vx+eW>SsLNW5b;sx3y5-Xj zed$uQCV7tNv?FO6i2W&<3EaP?`RS9J88<^-!#PNIsia4M@WuMd#@G|U<(c$0TmS$0 zULP&eJwl`;P-Jbu&_p@PQ;(^Gc_tL}7>N1EG$x*}-+&-@g2sTxg6?(@c^sn*Wp78r z%w;%;o=*Th0Gb7w3yN?Mc^sn*WvN45+W0z+bNCi06!aq*`^^M-Zf2gm8r6lpV9u#G zk20T<$1%!KmO7R$ZQN=+f}q3rPLuDCe;PUZqGZie+5W7`F6Q86D$J+8L>|W|Ls{xj zmo_Y0wE0yU4D8wn~*PCeW{lZ8T#UauhgXt z+A=n+I1t0RAGk-kPo}}wtCYX%$U4m9sD`y6Z?6R~ z16%KywJ`gEXM^o)Rn1?ubo|~uIk7-bIZ_UvJd?z&mqqgr3_Tqyl9CON>-`JC| z$#pPilQAHsozH*sNEY)(=m(oMy#1hMrxDl#5$hDxLC$9CAdU^BV|cl+eZb@glcR`f z-zBNh9kOe&K3ZF#AuW4g199@&L7#SQs%O2C<%Bmp;g~IFeCcl|qy_n*4)&QRiD}o zFSha$G3`5)_XldPMSm$noeBAR;FD^w&#(9Gb3f1_7}TW=%bqo#qzlKbdxMx>{8$Yv zdPQHjQ~{q6!#ZHs!jDS-eLe)F-!N?$TXn$4+y=x)ogG}9roZ~Q2LATqGY+>4pSA|a zAB!4OC!YMhCSPm78gGNYoIj}QHpCw`EPI$gV(OT`RWkwq{?l7E`IANss>9i@hQF-G z`K^S$8!>ca?~%%}|IQAu|G+b2wj6b+Yul>9{;T!de^$M=KFV|7;Z$98*{zd3d!dIl zs3ty%aeyB-aja~B^9P>Mv*q}uu8*CNCZF?{9^=9Ovuedvb5kZ1EYYN{Q#$W*Dc%HF zgMPZUFZj|f-Z9Q*-Z2K#N7jo?UXF%)iZt{T-VLmgQX*1-Z{5SQL&x*omeg@vU;Ls& z18a~2DmZ82Ij9nRpEr>02YJFVr@Z-%*w-NcofWIg!vW2PTPqFCSx+13#>x0NBS&Ehjrr z17^fs0p!p%aO&Jk&*I&EME|AhZ~j#mUaiq#ZvIDsSd_vKzJXca`VsgTyQ3msBR%hF zd`l7Lz1ph%GGZ@%1#CMah{NNTAKLe_mf+o;uOI8`o83D9@8vqhvtI)%;0yAVl)xVn z{0f49lNt*(^1?CwS$By(=zhyuZ^nFM+~r%qwtWbc^{zbb$tA6ab>GcTb#u>0`n#SB zx(fUArJhb*@kP5X{k&C|e%7MDzFMzOcAd~4;{SlVic?W%J&(PXfH!(v9t=9`Z5v~# zZ-A_PY_g<9G}Dhqi#O;qb$`<3AGtO8V!8hO{QElpT#?SLDbOF3=IVF$uhMVqc#i)i zaIKr=<;N!jz_-pG3UBc7-##)*QX`ijPc&KoLAb2{An+fN`5z)98sC^ENsC<~$+Jfd zZm9o=mIUg5MAqC8nbU*1{JO~KZjlish}l~BZj;<%v-S8bfvs-Xq-|mlit<8 literal 0 HcmV?d00001 diff --git a/resources/icons/cursor.ico b/resources/icons/cursor.ico new file mode 100755 index 0000000000000000000000000000000000000000..b502cb0444e6d7fb91794333dce0cb03b37221e7 GIT binary patch literal 1150 zcmaiz%TE(g7{#xNi5nAHx$qH9bm87VfWJb~y$g2+MTqr*3!?$s&f|8bQ-pvG_%^6< zB}5?g)l!PFg^GnDw)GKAXosB*Ies&Ey*HC6)13Lv{qFhoKAJMNjXo_cjNS*?>Ftc| zW{e#nQHwg8eJYI6T<`(Fgo1N_#`~xqR_8=MSk;X1T^;QsS1yK9G(IGHK~9Wm{wV2y z$Wh(nSSFr7dy1=$hiTYX{<6|!n?zwStOP(b=h$~8C7sHszQ50b+oaR=Q96$9*MzA$|7LO4^}l7kRJW NO#)*pqzY+`^cx*YJdywa literal 0 HcmV?d00001 diff --git a/resources/icons/delete.ico b/resources/icons/delete.ico new file mode 100755 index 0000000000000000000000000000000000000000..03aaed631b025f82507b02bee0f5856be158729f GIT binary patch literal 5430 zcmb_g2~d^S8U3v_j_t%~ThmrsL!z=h-g5;WyGX={AhHO!5cdU9S=CBXc&frLreb%<(nvTri?$yXp!?_7?ii8^(JQ^F}MxXm;74| zK-+#-b_P3p7b2JtD4 zn2>Y_y(bXpyTjjw@!Obz_T-Vez&E}r<(lfGh+UH_O{>^{1QC%*L943keDrY)_*;IPU^ zE0ZCf_|juDT)pzJZhJlYk1ALHkxe}DrN?Htc;(ga`=AEa$TFB;D}^bz1g;N&w=gL5 z2FxRiF(C9h1`>LzFS*9W6JL6EeK)^?;Qj#@u;V}l-us{qlNXi2KlTRt1{T_$>PxP1 z@x*VduitLI1;MgAXUV_u-qC6tJ5!HiX9+&lmt5oGiLYk&-_mRO>&kgKTl4G0wL^W$ z+w$~V`jsykMt*0*c(Y>*c&X^Zcqr^V=}1@ii~}*0(0ycUx_F+vF%qK-(Vgf)ym${J z)0jBoK8vOqKSwC?UW5x_B?5_{dmx#{#1U6I(v^)TX_~|HgahH;xyvs?Uv|sPHhCSt zV)o644SxBs*x`R3Zr;bQykgGG7FRm0y0Y=O>(PliT3^cxJp#wOT2EZH_+Nlm_(k~f zjv5+&1AY@q;1$QS6n!0oBW_?oSRu^8|AO1F&tUN{U@RxDcB8IrwAzx*_B8Q+PFVX5 zdjEvk?*d+(cm+|(m6-ZQEf!=pV$F77Z8q@MPGHS8Ae~sT8JM-=4nn6_!7{2Cu0j8V zg?GC1ki92ltJUVCVzB%6cJ(?{<`ecQVp1!RoY8;{dw`W&faEpwvkaKJs2S6Q#Vwdk z+5FYO;tXK?Sk5AK)KC9>V>2`uAUxJTTCVzBt0DV2{_Uv1BY z&dE#t2JQPWAo4S$X4PTqVPM|sMvP}(oS1Z%{vRLGOL(Kn_C9o9n*#m@XZQUd$`>J@ z_SUWYPeVe@eg#O`Sc}c{oxHXQv59wB8z}ET8OBjh`Uz>xNaDNDe$bx$(a%D3KJB-m z-bF8G&yOxoTv&(=`u@|1N}E3Ztl|~W=;bZt*6bowYGEN=6&+Ad=m2AeuzF7;b{+#_=hh>Nb;;N{&j!&6b%>i+k2kWwvw7WiKm4$(X^?yq-Cwb6%Zix! z1vVaPMtXKLMo+6{t#q3)JUc|pyp5E#K8U#(a#XI*Fe4>e{c7j~#NLMywD{NW~ZP#MeR`9MavgHl=7MwhC zvE_Hb-cvx(xN3}?bjyaJvDNtNr*~NnJXw>jY{*{7Ku9Sptg%&Rw+G@%N4l~hTLH1<2&V0I%-eyiA6os}>NQ9AQ&e8-l-M~Hq*P)EA5A^1d>B5r;y7H@2#?JGQgr!R5-wp!6~a86o$>Sde% z^j&u`B&7e?kByXdeXnWJ?G?c_R`W#H*x4Zka?hycT_Qk zjJ^&}p4F#;dpN(9LW;3$a}!d3)xfiOm9^o=TKl&7w}XRghKq90ex89N7x=Bdyc%x7 zMHt9@p*WrdgP8LzuN5IKxf&bZXI@)S!E;vt2e%B>=xyr{twTp=kCVH@CSSzSKLa^L zY)S=Of(p@pq~g%GUOPeVfRG}Xh8H3tp%QN&0cNhLh3ZLHuampwOAa5C3*i{}HR4jLua;{J@XdUz}GMJkNgchO?<8T_LSiZLTkRLlFb7p8NZcWz-jeA}0#laps|(P+L4?FXHU9LBL?M*||}mhpcIh4`iSf6&{f75r_XEPPHm zmTYOjZr?&@8C z0(Kq;-eKO{%G|x-z+EJ+xyc;=1@G1ZuJ^f%&eWyhd-wUne0`_9&w!m>T|7^xGM3Mk zFO;(cCxP{YY8V&mxzAm#r&Ifq`<=$x3?jcHnhj%BqhSQpvo5bRj2FH#jL!L7vo{&L Z9mZoeyPlr;wDlEj%C>ySmwd|i{{ULsF5dtE literal 0 HcmV?d00001 diff --git a/resources/icons/fill_color.ico b/resources/icons/fill_color.ico new file mode 100755 index 0000000000000000000000000000000000000000..f8945baaffb8561fc5af6e6c446cee6c5ce3f949 GIT binary patch literal 1150 zcmbV~>q}E%9LK*w(2F2~Ai{3eoHMh_5F;w;59qB$m`>f<=DanXncFOH&0N!o5fwr9 zA`+sDC|E?GC1$B}o0n|l7){OYM7`@p@a=idT11yOJ%{gk&iOs(^Zh;N_j`aP;##>9 z;+_oaQeZWJG$9cZk$7B8fLQy>(1=*(e@c^`ba&9O;VBD}M`_&br%4;2MHixV%Op#- zPP25|49jeX zX~y$^=6CL$?-e`*53zp~CI?{LJPBn}Se8kxiB%UxSw;jl{j7{Fm+=#OVyM|W55eQ; z+F|6a8--zg0QpJNFszBl?=pQ221?22;?zZyZHppX+jUUU_-WMmA@&ZJP|lhW*D))>;`EoSBN|5H%Af$(qGLH6o6WVHvRJO@h$hl|Z93QyL z{_ZX|9xGta^-keoW?Oxp=;!RHqKWg;L(1zcf!9%jW|1d2c%Lt){ESYF&}BKosj(s6 zxZJ^uo?5z{xjdc~;~%`E6lZJVd^j{lzsT({ALggm3mkdS%Lg~FiGMlAzB}h>-}zqU zP1<;FHNW7!LY@=FXttZ#P@d1=@BkyhCk&4b(%;|5riy%ePadUR|AA)hL{CxL1QL>L zLej%sX<{Ti#mDz58(Z!YE60@v@^l(=yJYAu%<#-X!I>b3}6`{S+fWoygC>tYC zlH*Enzt7S~>PMWiPpzWQzB&cIhC;MA6sVGo|8;zO1AG<7;j<2iEdw6?BKiLLfLIs$ I_7I@ZclRjdegFUf literal 0 HcmV?d00001 diff --git a/resources/icons/pencil.ico b/resources/icons/pencil.ico new file mode 100755 index 0000000000000000000000000000000000000000..202677522417f45a84c9b197f36d3172c0d277f4 GIT binary patch literal 1150 zcmb7>Pbh<79LIl)+R<{Dau^rI!37rz2RF%*lauR0JM5(8ZJXF;q?JEmmXekzqR^Uu zwWyIlvvycYqF7uc2MS-mXEV*bc=x=0-?#VoJfF|+>3N7${Ae`9?_x6K5^0I3l*1*i zBc}1Dsu>4zj6=f70|E=l=%Ri2PpI^a|m9Hs_r0~kAPY~ zP(BY7@g9^oQoL|fOM7TJ;l5co()pxgKPyKj|CgiI==pIka=e^F$LFEtRCLXLbNt4q zJH(lm@tNlHy;v5*u$oO@j=%VnqxqQovSWPb0%I;4{Oil;mW&CRJN$EJ&b{A%?z#683R%a@+gXelOM;}SX)IR9@BlyJkoi|eSUU^smU;gLO~=G%cdUb zJg@nX{}I!cFg+E)@X#RQ+ShwM(s`-D?RJX=;xUaqCUlRDwItdD-t@hdse1dLm!Nq3 zI{m48%uG*UY-A8S>xpekjSr=-+VlgzrHSt14G&qz%Cd&wm%e^$V>im*22twL?}>qD zOk0pYPVD9ymM3QP~xNqxPRW@-S0=BSB%6f}Xi==$+kzGw>M|ouja`hrLe4 z<6>un8E>m=MG4QhRx9{4zsog*@T{c|-NRAXUaC@}k;=5UJXg>^w*|+W5BM0?m=9#d z7r*dhRNF@=x(Q2t=YYf2nicPGwb@H*{alY9!ajZ7E(Wx~B^0o7S?^g<(K}Wd(Lo;3 S3G0$|okMh!5*GRFQ~C?7U@3S2 literal 0 HcmV?d00001 diff --git a/resources/icons/viewsprites.ico b/resources/icons/viewsprites.ico new file mode 100755 index 0000000000000000000000000000000000000000..14e62310453d01dc2a699646e96d2a87b5b5f77b GIT binary patch literal 5430 zcmd_uJ8l#~6a~=YBM}hT5*u)YyoAZHM8Z-W5;|lB$h&}$CCm~C2?+@a9Uu*Ldvs8# zG|$}{5g=iyxK*$2=XG_{Zn?E5?Pz7vLJo-!yWbMA-wDb$9~4Vku&yhKI-%&YxKb%G2S@QWE~vm z_Omx?Gfz!^uH)2*KAc&fb@qbMxomt2Ye{s z8qQkRZ$Ho5sbT+=K7D2Xly0nr6Rv9?G4+vqYF=sMv)037+4_jbV*~GR;r>}`AD$dX z=HFkm7M$y9+0XcS(I1-r6y!Z~)yGXAc^@r5{l!zgXY`%t*t6U<%kva;kDa||2&&_a z+RXXNsSt10^OYkPs^iUizH7PO1)Sb2h(|a3$f>Z>@vU;z@hYDxcdql{3)S6EsE!BK zXaBV|9UrJJ7pmhy^|d_v&W#?*v2P9MIvunxr$RhBSmji8I>@)mRmXE~^q%9bNXLh- zoC@*i_-xI^qvOMOEtd|TpWicEk&e&oJNHrX_-xI^qpN(Y{Cq?D=FIob{QG5Id*9D> zYu`+K_4BXg>qmdCt3u}tE1o)EIThm3RVWu$JaxWRt~wqa^nJAz=^$S@72?sst+{w~ zkZ+Z%?s=u-cP{ebE2ly{x^r{s`0%ZA=Q=*0bCJ*NzqY13HMLIsS z|Js_4&(>T#IzDT8)js{XSovicons/folder_map.ico icons/image.ico icons/map.ico + icons/cursor.ico + icons/fill_color.ico + icons/pencil.ico + icons/pipette.ico + images/Entities_16x16.png + icons/add.ico + icons/delete.ico + icons/viewsprites.ico diff --git a/resources/images/Entities_16x16.png b/resources/images/Entities_16x16.png new file mode 100755 index 0000000000000000000000000000000000000000..db480f6e7b609a066e504367fb1338fe629d60b2 GIT binary patch literal 274 zcmV+t0qy>YP)J5hbP53Dm7H1u76_11A|jb<0Px6M14y4S z`HKMD>;lMj*8re*z=^N{xKlFx41lkm7LwoI1_-whU*`qDV>JvFfNz@@01RLIr!d5R zfLwhg0Hd8O0DlWr1>i-;0765|Pr1?z *tiles; - QList *metatiles; - QList> *palettes; + QList *tiles = NULL; + QList *metatiles = NULL; + QList> *palettes = NULL; }; #endif // TILESET_H