diff --git a/editor.cpp b/editor.cpp index e29bb667..ac470c02 100755 --- a/editor.cpp +++ b/editor.cpp @@ -306,7 +306,7 @@ void Editor::onBorderMetatilesChanged() { } void Editor::setConnectionsVisibility(bool visible) { - for (QGraphicsPixmapItem* item : map->connection_items) { + for (QGraphicsPixmapItem* item : connection_items) { item->setVisible(visible); item->setActive(visible); } @@ -348,8 +348,13 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm } void Editor::displayMap() { - scene = new QGraphicsScene; + if (!scene) + scene = new QGraphicsScene; + if (map_item && scene) { + scene->removeItem(map_item); + delete map_item; + } map_item = new MapPixmapItem(map); connect(map_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,MapPixmapItem*)), this, SLOT(mouseEvent_map(QGraphicsSceneMouseEvent*,MapPixmapItem*))); @@ -357,6 +362,10 @@ void Editor::displayMap() { map_item->draw(true); scene->addItem(map_item); + if (collision_item && scene) { + scene->removeItem(collision_item); + delete collision_item; + } collision_item = new CollisionPixmapItem(map); connect(collision_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)), this, SLOT(mouseEvent_collision(QGraphicsSceneMouseEvent*,CollisionPixmapItem*))); @@ -364,19 +373,6 @@ void Editor::displayMap() { collision_item->draw(true); scene->addItem(collision_item); - events_group = new EventGroup; - scene->addItem(events_group); - - if (map_item) { - map_item->setVisible(false); - } - if (collision_item) { - collision_item->setVisible(false); - } - if (events_group) { - events_group->setVisible(false); - } - int tw = 16; int th = 16; scene->setSceneRect( @@ -394,9 +390,24 @@ void Editor::displayMap() { displayMapConnections(); displayMapBorder(); displayMapGrid(); + + if (map_item) { + map_item->setVisible(false); + } + if (collision_item) { + collision_item->setVisible(false); + } + if (events_group) { + events_group->setVisible(false); + } } void Editor::displayMetatiles() { + if (metatiles_item && metatiles_item->scene()) { + metatiles_item->scene()->removeItem(metatiles_item); + delete metatiles_item; + } + scene_metatiles = new QGraphicsScene; metatiles_item = new MetatilesPixmapItem(map); metatiles_item->draw(); @@ -404,6 +415,11 @@ void Editor::displayMetatiles() { } void Editor::displayBorderMetatiles() { + if (selected_border_metatiles_item && selected_border_metatiles_item->scene()) { + selected_border_metatiles_item->scene()->removeItem(selected_border_metatiles_item); + delete selected_border_metatiles_item; + } + scene_selected_border_metatiles = new QGraphicsScene; selected_border_metatiles_item = new BorderMetatilesPixmapItem(map); selected_border_metatiles_item->draw(); @@ -413,6 +429,11 @@ void Editor::displayBorderMetatiles() { } void Editor::displayCollisionMetatiles() { + if (collision_metatiles_item && collision_metatiles_item->scene()) { + collision_metatiles_item->scene()->removeItem(collision_metatiles_item); + delete collision_metatiles_item; + } + scene_collision_metatiles = new QGraphicsScene; collision_metatiles_item = new CollisionMetatilesPixmapItem(map); collision_metatiles_item->draw(); @@ -420,6 +441,11 @@ void Editor::displayCollisionMetatiles() { } void Editor::displayElevationMetatiles() { + if (elevation_metatiles_item && elevation_metatiles_item->scene()) { + elevation_metatiles_item->scene()->removeItem(elevation_metatiles_item); + delete elevation_metatiles_item; + } + scene_elevation_metatiles = new QGraphicsScene; elevation_metatiles_item = new ElevationMetatilesPixmapItem(map); elevation_metatiles_item->draw(); @@ -427,10 +453,22 @@ void Editor::displayElevationMetatiles() { } void Editor::displayMapEvents() { - for (QGraphicsItem *child : events_group->childItems()) { - events_group->removeFromGroup(child); + if (events_group) { + for (QGraphicsItem *child : events_group->childItems()) { + events_group->removeFromGroup(child); + delete child; + } + + if (events_group->scene()) { + events_group->scene()->removeItem(events_group); + } + + delete events_group; } + events_group = new EventGroup; + scene->addItem(events_group); + QList events = map->getAllEvents(); project->loadEventPixmaps(events); for (Event *event : events) { @@ -450,12 +488,18 @@ DraggablePixmapItem *Editor::addMapEvent(Event *event) { } void Editor::displayMapConnections() { - for (QGraphicsPixmapItem* item : map->connection_items) { + for (QGraphicsPixmapItem* item : connection_items) { + if (item->scene()) { + item->scene()->removeItem(item); + } delete item; } - map->connection_items.clear(); + connection_items.clear(); for (ConnectionPixmapItem* item : connection_edit_items) { + if (item->scene()) { + item->scene()->removeItem(item); + } delete item; } selected_connection_item = NULL; @@ -497,7 +541,7 @@ void Editor::createConnectionItem(Connection* connection, bool hide) { item->setX(x); item->setY(y); scene->addItem(item); - map->connection_items.append(item); + connection_items.append(item); item->setVisible(!hide); ConnectionPixmapItem *connection_edit_item = new ConnectionPixmapItem(pixmap, connection, x, y, map->getWidth(), map->getHeight()); @@ -512,6 +556,14 @@ void Editor::createConnectionItem(Connection* connection, bool hide) { } void Editor::displayMapBorder() { + for (QGraphicsPixmapItem* item : borderItems) { + if (item->scene()) { + item->scene()->removeItem(item); + } + delete item; + } + borderItems.clear(); + QPixmap pixmap = map->renderBorder(); for (int y = -6; y < map->getHeight() + 6; y += 2) for (int x = -6; x < map->getWidth() + 6; x += 2) { @@ -525,18 +577,29 @@ void Editor::displayMapBorder() { } void Editor::displayMapGrid() { + for (QGraphicsLineItem* item : gridLines) { + if (item && item->scene()) { + item->scene()->removeItem(item); + } + delete item; + } + gridLines.clear(); + ui->checkBox_ToggleGrid->disconnect(); + int pixelWidth = map->getWidth() * 16; int pixelHeight = map->getHeight() * 16; for (int i = 0; i <= map->getWidth(); i++) { int x = i * 16; QGraphicsLineItem *line = scene->addLine(x, 0, x, pixelHeight); line->setVisible(ui->checkBox_ToggleGrid->isChecked()); + gridLines.append(line); connect(ui->checkBox_ToggleGrid, &QCheckBox::toggled, [=](bool checked){line->setVisible(checked);}); } for (int j = 0; j <= map->getHeight(); j++) { int y = j * 16; QGraphicsLineItem *line = scene->addLine(0, y, pixelWidth, y); line->setVisible(ui->checkBox_ToggleGrid->isChecked()); + gridLines.append(line); connect(ui->checkBox_ToggleGrid, &QCheckBox::toggled, [=](bool checked){line->setVisible(checked);}); } } @@ -679,8 +742,11 @@ void Editor::removeCurrentConnection() { connection_edit_items.removeOne(selected_connection_item); removeMirroredConnection(selected_connection_item->connection); - scene->removeItem(selected_connection_item); - delete selected_connection_item; + if (selected_connection_item && selected_connection_item->scene()) { + selected_connection_item->scene()->removeItem(selected_connection_item); + delete selected_connection_item; + } + selected_connection_item = NULL; setConnectionEditControlsEnabled(false); ui->spinBox_ConnectionOffset->setValue(0); @@ -737,6 +803,20 @@ void Editor::updateDiveEmergeMap(QString mapName, QString direction) { ui->label_NumConnections->setText(QString::number(map->connections.length())); } +void Editor::updatePrimaryTileset(QString tilesetLabel) +{ + map->layout->tileset_primary_label = tilesetLabel; + map->layout->tileset_primary = project->getTileset(tilesetLabel); + emit tilesetChanged(map->name); +} + +void Editor::updateSecondaryTileset(QString tilesetLabel) +{ + map->layout->tileset_secondary_label = tilesetLabel; + map->layout->tileset_secondary = project->getTileset(tilesetLabel); + emit tilesetChanged(map->name); +} + void MetatilesPixmapItem::paintTileChanged(Map *map) { draw(); } diff --git a/editor.h b/editor.h index d2ec601b..b93f9bd5 100755 --- a/editor.h +++ b/editor.h @@ -59,6 +59,8 @@ public: void updateDiveMap(QString mapName); void updateEmergeMap(QString mapName); void setSelectedConnectionFromMap(QString mapName); + void updatePrimaryTileset(QString tilesetLabel); + void updateSecondaryTileset(QString tilesetLabel); DraggablePixmapItem *addMapEvent(Event *event); void selectMapEvent(DraggablePixmapItem *object); @@ -74,10 +76,12 @@ public: QGraphicsPixmapItem *current_view = NULL; MapPixmapItem *map_item = NULL; ConnectionPixmapItem* selected_connection_item = NULL; + QList connection_items; QList connection_edit_items; CollisionPixmapItem *collision_item = NULL; QGraphicsItemGroup *events_group = NULL; QList borderItems; + QList gridLines; QGraphicsScene *scene_metatiles = NULL; QGraphicsScene *scene_selected_border_metatiles = NULL; @@ -133,6 +137,7 @@ signals: void objectsChanged(); void selectedObjectsChanged(); void loadMapRequested(QString, QString); + void tilesetChanged(QString); }; diff --git a/mainwindow.cpp b/mainwindow.cpp index ea3a571c..697963cd 100755 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -34,6 +34,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(editor, SIGNAL(objectsChanged()), this, SLOT(updateSelectedObjects())); connect(editor, SIGNAL(selectedObjectsChanged()), this, SLOT(updateSelectedObjects())); connect(editor, SIGNAL(loadMapRequested(QString, QString)), this, SLOT(onLoadMapRequested(QString, QString))); + connect(editor, SIGNAL(tilesetChanged(QString)), this, SLOT(onTilesetChanged(QString))); on_toolButton_Paint_clicked(); @@ -206,6 +207,8 @@ void MainWindow::displayMapProperties() { ui->comboBox_Weather->clear(); ui->comboBox_Type->clear(); ui->comboBox_BattleScene->clear(); + ui->comboBox_PrimaryTileset->clear(); + ui->comboBox_SecondaryTileset->clear(); ui->checkBox_ShowLocation->setChecked(false); if (!editor || !editor->map || !editor->project) { ui->frame_3->setEnabled(false); @@ -222,6 +225,12 @@ void MainWindow::displayMapProperties() { ui->comboBox_Location->addItems(project->getLocations()); ui->comboBox_Location->setCurrentText(map->location); + QMap tilesets = project->getTilesets(); + ui->comboBox_PrimaryTileset->addItems(tilesets.value("primary")); + ui->comboBox_PrimaryTileset->setCurrentText(map->layout->tileset_primary_label); + ui->comboBox_SecondaryTileset->addItems(tilesets.value("secondary")); + ui->comboBox_SecondaryTileset->setCurrentText(map->layout->tileset_secondary_label); + ui->comboBox_Visibility->addItems(project->getVisibilities()); ui->comboBox_Visibility->setCurrentText(map->visibility); @@ -412,6 +421,11 @@ void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction) setMap(newMapName); } +void MainWindow::onTilesetChanged(QString mapName) +{ + setMap(mapName); +} + void MainWindow::on_mapList_activated(const QModelIndex &index) { QVariant data = index.data(Qt::UserRole); @@ -814,3 +828,13 @@ void MainWindow::on_comboBox_EmergeMap_currentTextChanged(const QString &mapName { editor->updateEmergeMap(mapName); } + +void MainWindow::on_comboBox_PrimaryTileset_activated(const QString &tilesetLabel) +{ + editor->updatePrimaryTileset(tilesetLabel); +} + +void MainWindow::on_comboBox_SecondaryTileset_activated(const QString &tilesetLabel) +{ + editor->updateSecondaryTileset(tilesetLabel); +} diff --git a/mainwindow.h b/mainwindow.h index 5f1b7a2b..88f08661 100755 --- a/mainwindow.h +++ b/mainwindow.h @@ -71,6 +71,7 @@ private slots: void onOpenMapListContextMenu(const QPoint &point); void onAddNewMapToGroupClick(QAction* triggeredAction); + void onTilesetChanged(QString); void on_action_Export_Map_Image_triggered(); @@ -88,6 +89,10 @@ private slots: void on_comboBox_EmergeMap_currentTextChanged(const QString &mapName); + void on_comboBox_PrimaryTileset_activated(const QString &arg1); + + void on_comboBox_SecondaryTileset_activated(const QString &arg1); + private: Ui::MainWindow *ui; QStandardItemModel *mapListModel; diff --git a/mainwindow.ui b/mainwindow.ui index 8714f10d..77405325 100755 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -290,7 +290,7 @@ 0 0 - 475 + 436 621 @@ -451,9 +451,146 @@ 0 + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Primary Tileset + + + + + + + true + + + + + + + Secondary Tileset + + + + + + + true + + + + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + QLayout::SetDefaultConstraint + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Border + + + + + + + + 0 + 0 + + + + + 16777215 + 48 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + Qt::ScrollBarAsNeeded + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + - + 0 0 @@ -470,6 +607,9 @@ true + + Qt::AlignHCenter|Qt::AlignTop + true @@ -479,7 +619,7 @@ 0 0 358 - 612 + 497 @@ -488,7 +628,7 @@ 0 - + QLayout::SetDefaultConstraint @@ -504,97 +644,26 @@ 0 - - 0 - - - 8 - - - - - - 0 - 0 - + + + + Qt::Vertical - - QFrame::NoFrame + + + 20 + 40 + - - QFrame::Raised - - - - 6 - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - Border - - - - - - - - 0 - 0 - - - - - 16777215 - 48 - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - Qt::ScrollBarAsNeeded - - - - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 40 - 20 - - - - - - + - + true - + 0 0 @@ -610,6 +679,32 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/map.h b/map.h index 43f57e06..a98359a1 100755 --- a/map.h +++ b/map.h @@ -193,7 +193,6 @@ public: QMap> events; QList connections; - QList connection_items; QPixmap renderConnection(Connection); QPixmap renderBorder(); diff --git a/project.cpp b/project.cpp index 5422e0a2..68b7a742 100755 --- a/project.cpp +++ b/project.cpp @@ -64,7 +64,6 @@ void Project::loadMapConnections(Map *map) { } map->connections.clear(); - map->connection_items.clear(); if (!map->connections_label.isNull()) { QString path = root + QString("/data/maps/%1/connections.inc").arg(map->name); QString text = readTextFile(path); @@ -354,7 +353,7 @@ void Project::readMapLayout(Map* map) { map->layout = mapLayouts[map->layout_label]; } - getTilesets(map); + loadMapTilesets(map); loadBlockdata(map); loadMapBorder(map); } @@ -494,7 +493,7 @@ void Project::saveMapConstantsHeader() { saveTextFile(root + "/include/constants/maps.h", text); } -void Project::getTilesets(Map* map) { +void Project::loadMapTilesets(Map* map) { if (map->layout->has_unsaved_changes) { return; } @@ -955,7 +954,7 @@ Map* Project::addNewMapToGroup(QString mapName, int groupNum) { mapNamesToMapConstants->insert(map->name, map->constantName); setNewMapHeader(map, mapLayoutsTable.size() + 1); setNewMapLayout(map); - getTilesets(map); + loadMapTilesets(map); setNewMapBlockdata(map); setNewMapBorder(map); setNewMapEvents(map); @@ -1001,6 +1000,47 @@ QStringList Project::getVisibilities() { return names; } +QMap Project::getTilesets() { + QMap allTilesets; + QStringList primaryTilesets; + QStringList secondaryTilesets; + allTilesets.insert("primary", primaryTilesets); + allTilesets.insert("secondary", secondaryTilesets); + QString headers_text = readTextFile(root + "/data/tilesets/headers.inc"); + QList* commands = parseAsm(headers_text); + int i = 0; + while (i < commands->length()) { + if (commands->at(i).length() != 2) + continue; + + if (commands->at(i).at(0) == ".label") { + QString tilesetLabel = commands->at(i).at(1); + // Advance to command specifying whether or not it is a secondary tileset + i += 2; + if (commands->at(i).at(0) != ".byte") { + qDebug() << "Unexpected command found for secondary tileset flag. Expected '.byte', but found: " << commands->at(i).at(0); + continue; + } + + QString secondaryTilesetValue = commands->at(i).at(1); + if (secondaryTilesetValue != "TRUE" && secondaryTilesetValue != "FALSE" && secondaryTilesetValue != "0" && secondaryTilesetValue != "1") { + qDebug() << "Unexpected secondary tileset flag found. Expected \"TRUE\", \"FALSE\", \"0\", or \"1\", but found: " << secondaryTilesetValue; + continue; + } + + bool isSecondaryTileset = (secondaryTilesetValue == "TRUE" || secondaryTilesetValue == "1"); + if (isSecondaryTileset) + allTilesets["secondary"].append(tilesetLabel); + else + allTilesets["primary"].append(tilesetLabel); + } + + i++; + } + + return allTilesets; +} + QStringList Project::getWeathers() { // TODO QStringList names; diff --git a/project.h b/project.h index ca5a29d2..18ab4282 100755 --- a/project.h +++ b/project.h @@ -57,7 +57,7 @@ public: QStringList* readLayoutValues(QString layoutName); void readMapLayout(Map*); void readMapsWithConnections(); - void getTilesets(Map*); + void loadMapTilesets(Map*); void loadTilesetAssets(Tileset*); void saveBlockdata(Map*); @@ -74,6 +74,7 @@ public: QStringList getSongNames(); QStringList getLocations(); QStringList getVisibilities(); + QMap getTilesets(); QStringList getWeathers(); QStringList getMapTypes(); QStringList getBattleScenes(); diff --git a/tileset.cpp b/tileset.cpp index 4fac3f4f..1e5dde68 100755 --- a/tileset.cpp +++ b/tileset.cpp @@ -2,6 +2,7 @@ #include #include +#include Tileset::Tileset() { @@ -43,9 +44,13 @@ QImage Metatile::getMetatileImage(int tile, Tileset *primaryTileset, Tileset *se } // Colorize the metatile tiles with its palette. - QList palette = palettes.value(tile_.palette); - for (int j = 0; j < palette.length(); j++) { - tile_image.setColor(j, palette.value(j)); + if (tile_.palette < palettes.length()) { + QList palette = palettes.value(tile_.palette); + for (int j = 0; j < palette.length(); j++) { + tile_image.setColor(j, palette.value(j)); + } + } else { + qDebug() << "Tile is referring to invalid palette number: " << tile_.palette; } // The top layer of the metatile has its last color displayed at transparent. @@ -105,7 +110,7 @@ QList> Metatile::getBlockPalettes(Tileset *primaryTileset, Tileset * for (int i = 0; i < 6; i++) { palettes.append(primaryTileset->palettes->at(i)); } - for (int i = 6; i < secondaryTileset->palettes->length(); i++) { + for (int i = 6; i < 12; i++) { palettes.append(secondaryTileset->palettes->at(i)); } return palettes;