diff --git a/include/core/regionmap.h b/include/core/regionmap.h index 6ee651fa..7efc0b01 100644 --- a/include/core/regionmap.h +++ b/include/core/regionmap.h @@ -76,10 +76,10 @@ public: const int padTop = 2; const int padBottom = 3; - void init(Project*); + bool init(Project*); - void readBkgImgBin(); - void readLayout(); + bool readBkgImgBin(); + bool readLayout(); void save(); void saveTileImages(); diff --git a/include/ui/regionmapeditor.h b/include/ui/regionmapeditor.h index d5dc00d2..3ced4e18 100644 --- a/include/ui/regionmapeditor.h +++ b/include/ui/regionmapeditor.h @@ -28,8 +28,8 @@ public: RegionMap *region_map; - void loadRegionMapData(); - void loadCityMaps(); + bool loadRegionMapData(); + bool loadCityMaps(); void setCurrentSquareOptions(); void onRegionMapTileSelectorSelectedTileChanged(unsigned id); diff --git a/src/core/regionmap.cpp b/src/core/regionmap.cpp index a87ab726..c44339d0 100644 --- a/src/core/regionmap.cpp +++ b/src/core/regionmap.cpp @@ -10,7 +10,15 @@ #include #include -void RegionMap::init(Project *pro) { +static bool ensureRegionMapFileExists(QString filepath) { + if (!QFile::exists(filepath)) { + logError(QString("Region map file does not exist: %1").arg(filepath)); + return false; + } + return true; +} + +bool RegionMap::init(Project *pro) { QString path = pro->root; this->project = pro; @@ -26,9 +34,15 @@ void RegionMap::init(Project *pro) { region_map_entries_path = path + "/src/data/region_map/region_map_entries.h"; region_map_layout_bin_path = path + "/graphics/pokenav/region_map_section_layout.bin"; city_map_tiles_path = path + "/graphics/pokenav/zoom_tiles.png"; + bool allFilesExist = ensureRegionMapFileExists(region_map_bin_path) + && ensureRegionMapFileExists(region_map_png_path) + && ensureRegionMapFileExists(region_map_entries_path) + && ensureRegionMapFileExists(region_map_layout_bin_path) + && ensureRegionMapFileExists(city_map_tiles_path); - readBkgImgBin(); - readLayout(); + return allFilesExist + && readBkgImgBin() + && readLayout(); } void RegionMap::save() { @@ -65,16 +79,20 @@ void RegionMap::saveTileImages() { } } -void RegionMap::readBkgImgBin() { +bool RegionMap::readBkgImgBin() { + map_squares.clear(); QFile binFile(region_map_bin_path); - if (!binFile.open(QIODevice::ReadOnly)) return; + if (!binFile.open(QIODevice::ReadOnly)) { + logError(QString("Failed to open region map map file %1.").arg(region_map_bin_path)); + return false; + } QByteArray mapBinData = binFile.readAll(); binFile.close(); if (mapBinData.size() < img_height_ * img_width_) { logError(QString("The region map tilemap at %1 is too small.").arg(region_map_bin_path)); - return; + return false; } for (int m = 0; m < img_height_; m++) { for (int n = 0; n < img_width_; n++) { @@ -83,6 +101,7 @@ void RegionMap::readBkgImgBin() { map_squares.append(square); } } + return true; } void RegionMap::saveBkgImgBin() { @@ -100,11 +119,15 @@ void RegionMap::saveBkgImgBin() { file.close(); } -void RegionMap::readLayout() { +bool RegionMap::readLayout() { + sMapNames.clear(); + sMapNamesMap.clear(); + mapSecToMapEntry.clear(); QFile file(region_map_entries_path); - if (!file.open(QIODevice::ReadOnly)) return; - - QString line; + if (!file.open(QIODevice::ReadOnly)) { + logError(QString("Failed to read region map entries file %1").arg(region_map_entries_path)); + return false; + } QMap *qmap = new QMap; @@ -113,7 +136,7 @@ void RegionMap::readLayout() { QTextStream in(&file); in.setCodec("UTF-8"); while (!in.atEnd()) { - line = in.readLine(); + QString line = in.readLine(); if (line.contains(QRegularExpression(".*sMapName.*="))) { QRegularExpression reBefore("sMapName_(.*)\\["); QRegularExpression reAfter("_\\(\"(.*)\""); @@ -148,23 +171,43 @@ void RegionMap::readLayout() { project->mapSecToMapHoverName = qmap; QFile binFile(region_map_layout_bin_path); - if (!binFile.open(QIODevice::ReadOnly)) return; + if (!binFile.open(QIODevice::ReadOnly)) { + logError(QString("Failed to read region map layout file %1").arg(region_map_layout_bin_path)); + return false; + } QByteArray mapBinData = binFile.readAll(); binFile.close(); for (int y = 0; y < layout_height_; y++) { for (int x = 0; x < layout_width_; x++) { int i = img_index_(x,y); - uint8_t id = static_cast(mapBinData.at(layout_index_(x,y))); + if (i >= map_squares.size()) { + continue; + } + int layoutIndex = layout_index_(x,y); + if (layoutIndex >= mapBinData.size()) { + continue; + } + uint8_t id = static_cast(mapBinData.at(layoutIndex)); map_squares[i].secid = id; QString secname = project->mapSectionValueToName.value(id); - if (secname != "MAPSEC_NONE") map_squares[i].has_map = true; + if (secname != "MAPSEC_NONE") { + map_squares[i].has_map = true; + } map_squares[i].mapsec = secname; - map_squares[i].map_name = sMapNamesMap.value(mapSecToMapEntry.value(secname).name); + if (!mapSecToMapEntry.contains(secname)) { + continue; + } + QString name = mapSecToMapEntry.value(secname).name; + if (!sMapNamesMap.contains(name)) { + continue; + } + map_squares[i].map_name = sMapNamesMap.value(name); map_squares[i].x = x; map_squares[i].y = y; } } + return true; } void RegionMap::saveLayout() { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c748cd82..6f9a3989 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -294,7 +294,7 @@ bool MainWindow::openProject(QString dir) { } else { this->statusBar()->showMessage(QString("Failed to open project %1").arg(nativeDir)); QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening the project %1. Please see %2 for full error details.\n%3") + QString errorMsg = QString("There was an error opening the project %1. Please see %2 for full error details.\n\n%3") .arg(dir) .arg(getLogPath()) .arg(getMostRecentError()); @@ -451,7 +451,7 @@ void MainWindow::openWarpMap(QString map_name, QString warp_num) { // Open the destination map, and select the target warp event. if (!setMap(map_name, true)) { QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n%3") + QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n\n%3") .arg(map_name) .arg(getLogPath()) .arg(getMostRecentError()); @@ -1044,7 +1044,7 @@ void MainWindow::on_mapList_activated(const QModelIndex &index) QString mapName = data.toString(); if (!setMap(mapName)) { QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n%3") + QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n\n%3") .arg(mapName) .arg(getLogPath()) .arg(getMostRecentError()); @@ -1961,7 +1961,7 @@ void MainWindow::checkToolButtons() { void MainWindow::onLoadMapRequested(QString mapName, QString fromMapName) { if (!setMap(mapName, true)) { QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n%3") + QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n\n%3") .arg(mapName) .arg(getLogPath()) .arg(getMostRecentError()); @@ -2274,8 +2274,18 @@ void MainWindow::on_horizontalSlider_MetatileZoom_valueChanged(int value) { void MainWindow::on_actionRegion_Map_Editor_triggered() { if (!this->regionMapEditor) { this->regionMapEditor = new RegionMapEditor(this, this->editor->project); - this->regionMapEditor->loadRegionMapData(); - this->regionMapEditor->loadCityMaps(); + bool success = this->regionMapEditor->loadRegionMapData() + && this->regionMapEditor->loadCityMaps(); + if (!success) { + delete this->regionMapEditor; + this->regionMapEditor = nullptr; + QMessageBox msgBox(this); + QString errorMsg = QString("There was an error opening the region map data. Please see %1 for full error details.\n\n%3") + .arg(getLogPath()) + .arg(getMostRecentError()); + msgBox.critical(nullptr, "Error Opening Region Map Editor", errorMsg); + return; + } connect(this->regionMapEditor, &QObject::destroyed, [=](QObject *) { this->regionMapEditor = nullptr; }); this->regionMapEditor->setAttribute(Qt::WA_DeleteOnClose); } diff --git a/src/ui/regionmapeditor.cpp b/src/ui/regionmapeditor.cpp index b8bc99a3..07415297 100644 --- a/src/ui/regionmapeditor.cpp +++ b/src/ui/regionmapeditor.cpp @@ -62,13 +62,17 @@ void RegionMapEditor::setCurrentSquareOptions() { } } -void RegionMapEditor::loadRegionMapData() { - this->region_map->init(project); +bool RegionMapEditor::loadRegionMapData() { + if (!this->region_map->init(project)) { + return false; + } + this->currIndex = this->region_map->width() * this->region_map->padTop + this->region_map->padLeft; displayRegionMap(); + return true; } -void RegionMapEditor::loadCityMaps() { +bool RegionMapEditor::loadCityMaps() { QDir directory(project->root + "/graphics/pokenav/city_maps"); QStringList files = directory.entryList(QStringList() << "*.bin", QDir::Files); QStringList without_bin; @@ -76,6 +80,7 @@ void RegionMapEditor::loadCityMaps() { without_bin.append(file.remove(".bin")); } this->ui->comboBox_CityMap_picker->addItems(without_bin); + return true; } void RegionMapEditor::displayRegionMap() {