diff --git a/mainwindow.cpp b/mainwindow.cpp index 378c7d71..e9e97dd1 100755 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -851,21 +851,51 @@ void MainWindow::on_pushButton_clicked() QSpinBox *widthSpinBox = new QSpinBox(); QSpinBox *heightSpinBox = new QSpinBox(); - widthSpinBox->setValue(editor->map->getWidth()); - heightSpinBox->setValue(editor->map->getHeight()); widthSpinBox->setMinimum(1); heightSpinBox->setMinimum(1); - widthSpinBox->setMaximum(255); - heightSpinBox->setMaximum(255); + // See below for explanation of maximum map dimensions + widthSpinBox->setMaximum(0x1E7); + heightSpinBox->setMaximum(0x1D1); + widthSpinBox->setValue(editor->map->getWidth()); + heightSpinBox->setValue(editor->map->getHeight()); form.addRow(new QLabel("Width"), widthSpinBox); form.addRow(new QLabel("Height"), heightSpinBox); + QLabel *errorLabel = new QLabel(); + QPalette errorPalette; + errorPalette.setColor(QPalette::WindowText, Qt::red); + errorLabel->setPalette(errorPalette); + errorLabel->setVisible(false); + QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); form.addRow(&buttonBox); - connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); + connect(&buttonBox, &QDialogButtonBox::accepted, [&dialog, &widthSpinBox, &heightSpinBox, &errorLabel](){ + // Ensure width and height are an acceptable size. + // The maximum number of metatiles in a map is the following: + // max = (width + 15) * (height + 14) + // This limit can be found in fieldmap.c in pokeruby/pokeemerald. + int realWidth = widthSpinBox->value() + 15; + int realHeight = heightSpinBox->value() + 14; + int numMetatiles = realWidth * realHeight; + if (numMetatiles <= 0x2800) { + dialog.accept(); + } else { + QString errorText = QString("Error: The specified width and height are too large.\n" + "The maximum width and height is the following: (width + 15) * (height + 14) <= 10240\n" + "The specified width and height was: (%1 + 15) * (%2 + 14) = %3") + .arg(widthSpinBox->value()) + .arg(heightSpinBox->value()) + .arg(numMetatiles); + errorLabel->setText(errorText); + errorLabel->setVisible(true); + } + }); connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); + form.addRow(errorLabel); + if (dialog.exec() == QDialog::Accepted) { - qDebug() << "Change width"; + editor->map->setDimensions(widthSpinBox->value(), heightSpinBox->value()); + setMap(editor->map->name); } } diff --git a/map.cpp b/map.cpp index 2c1189c3..858bf156 100755 --- a/map.cpp +++ b/map.cpp @@ -427,6 +427,30 @@ QPixmap Map::renderMetatiles() { return QPixmap::fromImage(image); } +void Map::setDimensions(int newWidth, int newHeight) { + int oldWidth = getWidth(); + int oldHeight = getHeight(); + + Blockdata* newBlockData = new Blockdata; + + for (int y = 0; y < newHeight; y++) + for (int x = 0; x < newWidth; x++) { + if (x < oldWidth && y < oldHeight) { + int index = y * oldWidth + x; + newBlockData->addBlock(layout->blockdata->blocks->value(index)); + } else { + newBlockData->addBlock(0); + } + } + + layout->blockdata->copyFrom(newBlockData); + layout->width = QString::number(newWidth); + layout->height = QString::number(newHeight); + commit(); + + emit mapChanged(this); +} + Block* Map::getBlock(int x, int y) { if (layout->blockdata && layout->blockdata->blocks) { if (x >= 0 && x < getWidth()) diff --git a/map.h b/map.h index a98359a1..450e39ce 100755 --- a/map.h +++ b/map.h @@ -194,6 +194,7 @@ public: QList connections; QPixmap renderConnection(Connection); + void setDimensions(int, int); QPixmap renderBorder(); void cacheBorder();