Skip to content

Commit

Permalink
Merge pull request #306 from ultima-soul/import_amap_map
Browse files Browse the repository at this point in the history
Add Import Map from Advance Map 1.92 feature.
  • Loading branch information
garakmon committed Nov 8, 2021
2 parents 795336f + 2d87a62 commit f64b03d
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 5 deletions.
7 changes: 7 additions & 0 deletions forms/mainwindow.ui
Expand Up @@ -2642,6 +2642,8 @@
<addaction name="actionTileset_Editor"/>
<addaction name="actionRegion_Map_Editor"/>
<addaction name="separator"/>
<addaction name="actionImport_Map_from_Advance_Map_1_92"/>
<addaction name="separator"/>
<addaction name="actionOpen_Project_in_Text_Editor"/>
</widget>
<widget class="QMenu" name="menuHelp">
Expand Down Expand Up @@ -2956,6 +2958,11 @@
<string>Open Config Folder</string>
</property>
</action>
<action name="actionImport_Map_from_Advance_Map_1_92">
<property name="text">
<string>Import Map from Advance Map 1.92...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
Expand Down
16 changes: 16 additions & 0 deletions include/core/mapparser.h
@@ -0,0 +1,16 @@
#ifndef MAPPARSER_H
#define MAPPARSER_H

#include "maplayout.h"
#include "project.h"
#include <QList>
#include <QString>

class MapParser
{
public:
MapParser();
MapLayout *parse(QString filepath, bool *error, Project *project);
};

#endif // MAPPARSER_H
3 changes: 3 additions & 0 deletions include/mainwindow.h
Expand Up @@ -132,8 +132,10 @@ private slots:
void onTilesetsSaved(QString, QString);
void onWildMonDataChanged();
void openNewMapPopupWindow(int, QVariant);
void openNewMapPopupWindowImportMap(MapLayout *);
void onNewMapCreated();
void onMapCacheCleared();
void importMapFromAdvanceMap1_92();
void onMapRulerStatusChanged(const QString &);
void applyUserShortcuts();

Expand Down Expand Up @@ -193,6 +195,7 @@ private slots:
void on_action_Export_Map_Image_triggered();
void on_actionExport_Stitched_Map_Image_triggered();
void on_actionExport_Map_Timelapse_Image_triggered();
void on_actionImport_Map_from_Advance_Map_1_92_triggered();

void on_comboBox_ConnectionDirection_currentTextChanged(const QString &arg1);
void on_spinBox_ConnectionOffset_valueChanged(int offset);
Expand Down
3 changes: 2 additions & 1 deletion include/project.h
Expand Up @@ -93,6 +93,7 @@ class Project : public QObject
Tileset* loadTileset(QString, Tileset *tileset = nullptr);
Tileset* getTileset(QString, bool forceLoad = false);
QMap<QString, QStringList> tilesetLabels;
QList<QString> tilesetLabelsOrdered;

Blockdata readBlockdata(QString);
bool loadBlockdata(MapLayout*);
Expand All @@ -103,7 +104,7 @@ class Project : public QObject
void deleteFile(QString path);

bool readMapGroups();
Map* addNewMapToGroup(QString, int, Map*, bool);
Map* addNewMapToGroup(QString, int, Map*, bool, bool);
QString getNewMapName();
QString getProjectTitle();

Expand Down
4 changes: 4 additions & 0 deletions include/ui/newmappopup.h
Expand Up @@ -20,8 +20,10 @@ class NewMapPopup : public QMainWindow
Map *map;
int group;
bool existingLayout;
bool importedMap;
QString layoutId;
void init(int, int, QString, QString);
void initImportMap(MapLayout *);
void useLayout(QString);
void connectSignals();

Expand All @@ -32,6 +34,8 @@ class NewMapPopup : public QMainWindow
Ui::NewMapPopup *ui;
Project *project;
void setDefaultValues(int, QString);
void setDefaultValuesImportMap(MapLayout *);
void setDefaultValuesProjectConfig(bool, MapLayout*);
bool checkNewMapDimensions();
bool checkNewMapGroup();

Expand Down
2 changes: 2 additions & 0 deletions porymap.pro
Expand Up @@ -22,6 +22,7 @@ SOURCES += src/core/block.cpp \
src/core/imageexport.cpp \
src/core/map.cpp \
src/core/maplayout.cpp \
src/core/mapparser.cpp \
src/core/metatile.cpp \
src/core/metatileparser.cpp \
src/core/paletteutil.cpp \
Expand Down Expand Up @@ -93,6 +94,7 @@ HEADERS += include/core/block.h \
include/core/map.h \
include/core/mapconnection.h \
include/core/maplayout.h \
include/core/mapparser.h \
include/core/metatile.h \
include/core/metatileparser.h \
include/core/paletteutil.h \
Expand Down
97 changes: 97 additions & 0 deletions src/core/mapparser.cpp
@@ -0,0 +1,97 @@
#include "mapparser.h"
#include "config.h"
#include "log.h"
#include "project.h"

MapParser::MapParser()
{
}

MapLayout *MapParser::parse(QString filepath, bool *error, Project *project)
{
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
*error = true;
logError(QString("Could not open Advance Map 1.92 Map .map file '%1': ").arg(filepath) + file.errorString());
return nullptr;
}

QByteArray in = file.readAll();
file.close();

if (in.length() < 20 || in.length() % 2 != 0) {
*error = true;
logError(QString("Advance Map 1.92 Map .map file '%1' is an unexpected size.").arg(filepath));
return nullptr;
}

int borderWidth = static_cast<unsigned char>(in.at(16)); // 0 in RSE .map files
int borderHeight = static_cast<unsigned char>(in.at(17)); // 0 in RSE .map files
int numBorderTiles = borderWidth * borderHeight; // 0 if RSE

int mapDataOffset = 20 + (numBorderTiles * 2); // FRLG .map files store border metatile data after the header
int mapWidth = static_cast<unsigned char>(in.at(0)) |
(static_cast<unsigned char>(in.at(1)) << 8) |
(static_cast<unsigned char>(in.at(2)) << 16) |
(static_cast<unsigned char>(in.at(3)) << 24);
int mapHeight = static_cast<unsigned char>(in.at(4)) |
(static_cast<unsigned char>(in.at(5)) << 8) |
(static_cast<unsigned char>(in.at(6)) << 16) |
(static_cast<unsigned char>(in.at(7)) << 24);
int mapPrimaryTilesetNum = static_cast<unsigned char>(in.at(8)) |
(static_cast<unsigned char>(in.at(9)) << 8) |
(static_cast<unsigned char>(in.at(10)) << 16) |
(static_cast<unsigned char>(in.at(11)) << 24);
int mapSecondaryTilesetNum = static_cast<unsigned char>(in.at(12)) |
(static_cast<unsigned char>(in.at(13)) << 8) |
(static_cast<unsigned char>(in.at(14)) << 16) |
(static_cast<unsigned char>(in.at(15)) << 24);

int numMetatiles = mapWidth * mapHeight;
int expectedFileSize = 20 + (numBorderTiles * 2) + (numMetatiles * 2);
if (in.length() != expectedFileSize) {
*error = true;
logError(QString(".map file is an unexpected size. Expected %1 bytes, but it has %2 bytes.").arg(expectedFileSize).arg(in.length()));
return nullptr;
}

Blockdata blockdata;
for (int i = mapDataOffset; (i + 1) < in.length(); i += 2) {
uint16_t word = static_cast<uint16_t>((in[i] & 0xff) + ((in[i + 1] & 0xff) << 8));
blockdata.append(word);
}

Blockdata border;
if (numBorderTiles != 0) {
for (int i = 20; (i + 1) < mapDataOffset; i += 2) {
uint16_t word = static_cast<uint16_t>((in[i] & 0xff) + ((in[i + 1] & 0xff) << 8));
border.append(word);
}
}

MapLayout *mapLayout = new MapLayout();
mapLayout->width = QString::number(mapWidth);
mapLayout->height = QString::number(mapHeight);
mapLayout->border_width = (borderWidth == 0) ? QString::number(2) : QString::number(borderWidth);
mapLayout->border_height = (borderHeight == 0) ? QString::number(2) : QString::number(borderHeight);

QList<QString> tilesets = project->tilesetLabelsOrdered;

if (mapPrimaryTilesetNum > tilesets.size())
mapLayout->tileset_primary_label = tilesets.at(0);
else
mapLayout->tileset_primary_label = tilesets.at(mapPrimaryTilesetNum);

if (mapSecondaryTilesetNum > tilesets.size())
mapLayout->tileset_secondary_label = tilesets.at(1);
else
mapLayout->tileset_secondary_label = tilesets.at(mapSecondaryTilesetNum);

mapLayout->blockdata = blockdata;

if (!border.isEmpty()) {
mapLayout->border = border;
}

return mapLayout;
}
54 changes: 53 additions & 1 deletion src/mainwindow.cpp
Expand Up @@ -15,6 +15,7 @@
#include "editcommands.h"
#include "flowlayout.h"
#include "shortcut.h"
#include "mapparser.h"

#include <QFileDialog>
#include <QClipboard>
Expand Down Expand Up @@ -1161,8 +1162,9 @@ void MainWindow::onNewMapCreated() {
int newMapGroup = this->newmapprompt->group;
Map *newMap = this->newmapprompt->map;
bool existingLayout = this->newmapprompt->existingLayout;
bool importedMap = this->newmapprompt->importedMap;

newMap = editor->project->addNewMapToGroup(newMapName, newMapGroup, newMap, existingLayout);
newMap = editor->project->addNewMapToGroup(newMapName, newMapGroup, newMap, existingLayout, importedMap);

logInfo(QString("Created a new map named %1.").arg(newMapName));

Expand Down Expand Up @@ -1215,6 +1217,24 @@ void MainWindow::openNewMapPopupWindow(int type, QVariant data) {
this->newmapprompt->setAttribute(Qt::WA_DeleteOnClose);
}

void MainWindow::openNewMapPopupWindowImportMap(MapLayout *mapLayout) {
if (!this->newmapprompt) {
this->newmapprompt = new NewMapPopup(this, this->editor->project);
}
if (!this->newmapprompt->isVisible()) {
this->newmapprompt->show();
} else {
this->newmapprompt->raise();
this->newmapprompt->activateWindow();
}

this->newmapprompt->initImportMap(mapLayout);

connect(this->newmapprompt, SIGNAL(applied()), this, SLOT(onNewMapCreated()));
connect(this->newmapprompt, &QObject::destroyed, [=](QObject *) { this->newmapprompt = nullptr; });
this->newmapprompt->setAttribute(Qt::WA_DeleteOnClose);
}

void MainWindow::on_action_NewMap_triggered() {
openNewMapPopupWindow(MapSortOrder::Group, 0);
}
Expand Down Expand Up @@ -2726,6 +2746,38 @@ void MainWindow::on_actionExport_Map_Timelapse_Image_triggered() {
showExportMapImageWindow(ImageExporterMode::Timelapse);
}

void MainWindow::on_actionImport_Map_from_Advance_Map_1_92_triggered(){
importMapFromAdvanceMap1_92();
}

void MainWindow::importMapFromAdvanceMap1_92()
{
QString filepath = QFileDialog::getOpenFileName(
this,
QString("Import Map from Advance Map 1.92"),
this->editor->project->root,
"Advance Map 1.92 Map Files (*.map)");
if (filepath.isEmpty()) {
return;
}

MapParser parser;
bool error = false;
MapLayout *mapLayout = parser.parse(filepath, &error, editor->project);
if (error) {
QMessageBox msgBox(this);
msgBox.setText("Failed to import map from Advance Map 1.92 .map file.");
QString message = QString("The .map file could not be processed. View porymap.log for specific errors.");
msgBox.setInformativeText(message);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.setIcon(QMessageBox::Icon::Critical);
msgBox.exec();
return;
}

openNewMapPopupWindowImportMap(mapLayout);
}

void MainWindow::showExportMapImageWindow(ImageExporterMode mode) {
if (!editor->project) return;

Expand Down
13 changes: 10 additions & 3 deletions src/project.cpp
Expand Up @@ -1848,7 +1848,7 @@ bool Project::readMapGroups() {
return true;
}

Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool existingLayout) {
Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool existingLayout, bool importedMap) {
mapNames.append(mapName);
mapGroups.insert(mapName, groupNum);
groupedMapNames[groupNum].append(mapName);
Expand All @@ -1861,8 +1861,12 @@ Map* Project::addNewMapToGroup(QString mapName, int groupNum, Map *newMap, bool
if (!existingLayout) {
mapLayouts.insert(newMap->layoutId, newMap->layout);
mapLayoutsTable.append(newMap->layoutId);
setNewMapBlockdata(newMap);
setNewMapBorder(newMap);
if (!importedMap) {
setNewMapBlockdata(newMap);
}
if (newMap->layout->border.isEmpty()) {
setNewMapBorder(newMap);
}
}

loadLayoutTilesets(newMap->layout);
Expand Down Expand Up @@ -1910,6 +1914,7 @@ QMap<QString, QStringList> Project::getTilesetLabels() {
QStringList secondaryTilesets;
allTilesets.insert("primary", primaryTilesets);
allTilesets.insert("secondary", secondaryTilesets);
QList<QString> tilesetLabelsOrdered;

QString filename = "data/tilesets/headers.inc";
QString headers_text = parser.readTextFile(root + "/" + filename);
Expand Down Expand Up @@ -1938,8 +1943,10 @@ QMap<QString, QStringList> Project::getTilesetLabels() {
allTilesets["secondary"].append(tilesetLabel);
else
allTilesets["primary"].append(tilesetLabel);
tilesetLabelsOrdered.append(tilesetLabel);
}
this->tilesetLabels = allTilesets;
this->tilesetLabelsOrdered = tilesetLabelsOrdered;
return allTilesets;
}

Expand Down

0 comments on commit f64b03d

Please sign in to comment.