Add better error handling for region map editor loading

This commit is contained in:
Marcus Huderle 2020-02-12 15:45:21 -06:00
parent 9a48fc1467
commit 342bcae174
5 changed files with 87 additions and 29 deletions

View file

@ -76,10 +76,10 @@ public:
const int padTop = 2; const int padTop = 2;
const int padBottom = 3; const int padBottom = 3;
void init(Project*); bool init(Project*);
void readBkgImgBin(); bool readBkgImgBin();
void readLayout(); bool readLayout();
void save(); void save();
void saveTileImages(); void saveTileImages();

View file

@ -28,8 +28,8 @@ public:
RegionMap *region_map; RegionMap *region_map;
void loadRegionMapData(); bool loadRegionMapData();
void loadCityMaps(); bool loadCityMaps();
void setCurrentSquareOptions(); void setCurrentSquareOptions();
void onRegionMapTileSelectorSelectedTileChanged(unsigned id); void onRegionMapTileSelectorSelectedTileChanged(unsigned id);

View file

@ -10,7 +10,15 @@
#include <QImage> #include <QImage>
#include <math.h> #include <math.h>
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; QString path = pro->root;
this->project = pro; 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_entries_path = path + "/src/data/region_map/region_map_entries.h";
region_map_layout_bin_path = path + "/graphics/pokenav/region_map_section_layout.bin"; region_map_layout_bin_path = path + "/graphics/pokenav/region_map_section_layout.bin";
city_map_tiles_path = path + "/graphics/pokenav/zoom_tiles.png"; 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(); return allFilesExist
readLayout(); && readBkgImgBin()
&& readLayout();
} }
void RegionMap::save() { 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); 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(); QByteArray mapBinData = binFile.readAll();
binFile.close(); binFile.close();
if (mapBinData.size() < img_height_ * img_width_) { if (mapBinData.size() < img_height_ * img_width_) {
logError(QString("The region map tilemap at %1 is too small.").arg(region_map_bin_path)); 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 m = 0; m < img_height_; m++) {
for (int n = 0; n < img_width_; n++) { for (int n = 0; n < img_width_; n++) {
@ -83,6 +101,7 @@ void RegionMap::readBkgImgBin() {
map_squares.append(square); map_squares.append(square);
} }
} }
return true;
} }
void RegionMap::saveBkgImgBin() { void RegionMap::saveBkgImgBin() {
@ -100,11 +119,15 @@ void RegionMap::saveBkgImgBin() {
file.close(); file.close();
} }
void RegionMap::readLayout() { bool RegionMap::readLayout() {
sMapNames.clear();
sMapNamesMap.clear();
mapSecToMapEntry.clear();
QFile file(region_map_entries_path); QFile file(region_map_entries_path);
if (!file.open(QIODevice::ReadOnly)) return; if (!file.open(QIODevice::ReadOnly)) {
logError(QString("Failed to read region map entries file %1").arg(region_map_entries_path));
QString line; return false;
}
QMap<QString, QString> *qmap = new QMap<QString, QString>; QMap<QString, QString> *qmap = new QMap<QString, QString>;
@ -113,7 +136,7 @@ void RegionMap::readLayout() {
QTextStream in(&file); QTextStream in(&file);
in.setCodec("UTF-8"); in.setCodec("UTF-8");
while (!in.atEnd()) { while (!in.atEnd()) {
line = in.readLine(); QString line = in.readLine();
if (line.contains(QRegularExpression(".*sMapName.*="))) { if (line.contains(QRegularExpression(".*sMapName.*="))) {
QRegularExpression reBefore("sMapName_(.*)\\["); QRegularExpression reBefore("sMapName_(.*)\\[");
QRegularExpression reAfter("_\\(\"(.*)\""); QRegularExpression reAfter("_\\(\"(.*)\"");
@ -148,23 +171,43 @@ void RegionMap::readLayout() {
project->mapSecToMapHoverName = qmap; project->mapSecToMapHoverName = qmap;
QFile binFile(region_map_layout_bin_path); 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(); QByteArray mapBinData = binFile.readAll();
binFile.close(); binFile.close();
for (int y = 0; y < layout_height_; y++) { for (int y = 0; y < layout_height_; y++) {
for (int x = 0; x < layout_width_; x++) { for (int x = 0; x < layout_width_; x++) {
int i = img_index_(x,y); int i = img_index_(x,y);
uint8_t id = static_cast<uint8_t>(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<uint8_t>(mapBinData.at(layoutIndex));
map_squares[i].secid = id; map_squares[i].secid = id;
QString secname = project->mapSectionValueToName.value(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].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].x = x;
map_squares[i].y = y; map_squares[i].y = y;
} }
} }
return true;
} }
void RegionMap::saveLayout() { void RegionMap::saveLayout() {

View file

@ -294,7 +294,7 @@ bool MainWindow::openProject(QString dir) {
} else { } else {
this->statusBar()->showMessage(QString("Failed to open project %1").arg(nativeDir)); this->statusBar()->showMessage(QString("Failed to open project %1").arg(nativeDir));
QMessageBox msgBox(this); 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(dir)
.arg(getLogPath()) .arg(getLogPath())
.arg(getMostRecentError()); .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. // Open the destination map, and select the target warp event.
if (!setMap(map_name, true)) { if (!setMap(map_name, true)) {
QMessageBox msgBox(this); 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(map_name)
.arg(getLogPath()) .arg(getLogPath())
.arg(getMostRecentError()); .arg(getMostRecentError());
@ -1044,7 +1044,7 @@ void MainWindow::on_mapList_activated(const QModelIndex &index)
QString mapName = data.toString(); QString mapName = data.toString();
if (!setMap(mapName)) { if (!setMap(mapName)) {
QMessageBox msgBox(this); 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(mapName)
.arg(getLogPath()) .arg(getLogPath())
.arg(getMostRecentError()); .arg(getMostRecentError());
@ -1961,7 +1961,7 @@ void MainWindow::checkToolButtons() {
void MainWindow::onLoadMapRequested(QString mapName, QString fromMapName) { void MainWindow::onLoadMapRequested(QString mapName, QString fromMapName) {
if (!setMap(mapName, true)) { if (!setMap(mapName, true)) {
QMessageBox msgBox(this); 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(mapName)
.arg(getLogPath()) .arg(getLogPath())
.arg(getMostRecentError()); .arg(getMostRecentError());
@ -2274,8 +2274,18 @@ void MainWindow::on_horizontalSlider_MetatileZoom_valueChanged(int value) {
void MainWindow::on_actionRegion_Map_Editor_triggered() { void MainWindow::on_actionRegion_Map_Editor_triggered() {
if (!this->regionMapEditor) { if (!this->regionMapEditor) {
this->regionMapEditor = new RegionMapEditor(this, this->editor->project); this->regionMapEditor = new RegionMapEditor(this, this->editor->project);
this->regionMapEditor->loadRegionMapData(); bool success = this->regionMapEditor->loadRegionMapData()
this->regionMapEditor->loadCityMaps(); && 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; }); connect(this->regionMapEditor, &QObject::destroyed, [=](QObject *) { this->regionMapEditor = nullptr; });
this->regionMapEditor->setAttribute(Qt::WA_DeleteOnClose); this->regionMapEditor->setAttribute(Qt::WA_DeleteOnClose);
} }

View file

@ -62,13 +62,17 @@ void RegionMapEditor::setCurrentSquareOptions() {
} }
} }
void RegionMapEditor::loadRegionMapData() { bool RegionMapEditor::loadRegionMapData() {
this->region_map->init(project); if (!this->region_map->init(project)) {
return false;
}
this->currIndex = this->region_map->width() * this->region_map->padTop + this->region_map->padLeft; this->currIndex = this->region_map->width() * this->region_map->padTop + this->region_map->padLeft;
displayRegionMap(); displayRegionMap();
return true;
} }
void RegionMapEditor::loadCityMaps() { bool RegionMapEditor::loadCityMaps() {
QDir directory(project->root + "/graphics/pokenav/city_maps"); QDir directory(project->root + "/graphics/pokenav/city_maps");
QStringList files = directory.entryList(QStringList() << "*.bin", QDir::Files); QStringList files = directory.entryList(QStringList() << "*.bin", QDir::Files);
QStringList without_bin; QStringList without_bin;
@ -76,6 +80,7 @@ void RegionMapEditor::loadCityMaps() {
without_bin.append(file.remove(".bin")); without_bin.append(file.remove(".bin"));
} }
this->ui->comboBox_CityMap_picker->addItems(without_bin); this->ui->comboBox_CityMap_picker->addItems(without_bin);
return true;
} }
void RegionMapEditor::displayRegionMap() { void RegionMapEditor::displayRegionMap() {