mirror of
https://github.com/huderlem/porymap.git
synced 2026-04-19 16:17:33 -05:00
Add functionality for global constants
This commit is contained in:
parent
e8ac633700
commit
ed273b9ca0
|
|
@ -345,6 +345,7 @@ public:
|
|||
this->unusedTileCovered = 0x0000;
|
||||
this->unusedTileSplit = 0x0000;
|
||||
this->maxEventsPerGroup = 255;
|
||||
this->globalConstantsFilepaths.clear();
|
||||
this->identifiers.clear();
|
||||
this->readKeys.clear();
|
||||
}
|
||||
|
|
@ -417,6 +418,7 @@ public:
|
|||
QMargins playerViewDistance;
|
||||
QList<uint32_t> warpBehaviors;
|
||||
int maxEventsPerGroup;
|
||||
QStringList globalConstantsFilepaths;
|
||||
|
||||
protected:
|
||||
virtual QString getConfigFilepath() override;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class ParseUtil
|
|||
{
|
||||
public:
|
||||
ParseUtil();
|
||||
void set_root(const QString &dir);
|
||||
void setRoot(const QString &dir) { this->root = dir; }
|
||||
static QString readTextFile(const QString &path, QString *error = nullptr);
|
||||
bool cacheFile(const QString &path, QString *error = nullptr);
|
||||
void clearFileCache() { this->fileCache.clear(); }
|
||||
|
|
@ -58,6 +58,8 @@ public:
|
|||
QMap<QString, int> readCDefinesByRegex(const QString &filename, const QSet<QString> ®exList, QString *error = nullptr);
|
||||
QMap<QString, int> readCDefinesByName(const QString &filename, const QSet<QString> &names, QString *error = nullptr);
|
||||
QStringList readCDefineNames(const QString &filename, const QSet<QString> ®exList, QString *error = nullptr);
|
||||
void loadGlobalCDefines(const QString &filename, QString *error = nullptr);
|
||||
void resetGlobalCDefines();
|
||||
OrderedMap<QString, QHash<QString, QString>> readCStructs(const QString &, const QString & = "", const QHash<int, QString>& = {});
|
||||
QList<QStringList> getLabelMacros(const QList<QStringList>&, const QString&);
|
||||
QStringList getLabelValues(const QList<QStringList>&, const QString&);
|
||||
|
|
@ -90,6 +92,8 @@ private:
|
|||
QString curDefine;
|
||||
QHash<QString, QString> fileCache;
|
||||
QHash<QString, QStringList> errorMap;
|
||||
QMap<QString, int> globalDefineValues;
|
||||
QMap<QString, QString> globalDefineExpressions;
|
||||
int evaluateDefine(const QString&, const QString &, QMap<QString, int>*, QMap<QString, QString>*);
|
||||
QList<Token> tokenizeExpression(QString, QMap<QString, int>*, QMap<QString, QString>*);
|
||||
QList<Token> generatePostfix(const QList<Token> &tokens);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public:
|
|||
int maxEncounterRate;
|
||||
bool wildEncountersLoaded;
|
||||
|
||||
void set_root(QString);
|
||||
void setRoot(const QString&);
|
||||
|
||||
void clearMaps();
|
||||
void clearTilesetCache();
|
||||
|
|
@ -203,6 +203,7 @@ public:
|
|||
bool readEventGraphics();
|
||||
bool readFieldmapProperties();
|
||||
bool readFieldmapMasks();
|
||||
bool readGlobalConstants();
|
||||
QMap<QString, QMap<QString, QString>> readObjEventGfxInfo();
|
||||
|
||||
QPixmap getEventPixmap(const QString &gfxName, const QString &movementName);
|
||||
|
|
|
|||
|
|
@ -15,26 +15,8 @@ const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|l
|
|||
const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
|
||||
const QRegularExpression ParseUtil::re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
|
||||
|
||||
static const QMap<QString, int> globalDefineValues = {
|
||||
{"FALSE", 0},
|
||||
{"TRUE", 1},
|
||||
{"SCHAR_MIN", SCHAR_MIN},
|
||||
{"SCHAR_MAX", SCHAR_MAX},
|
||||
{"CHAR_MIN", CHAR_MIN},
|
||||
{"CHAR_MAX", CHAR_MAX},
|
||||
{"UCHAR_MAX", UCHAR_MAX},
|
||||
{"SHRT_MIN", SHRT_MIN},
|
||||
{"SHRT_MAX", SHRT_MAX},
|
||||
{"USHRT_MAX", USHRT_MAX},
|
||||
{"INT_MIN", INT_MIN},
|
||||
{"INT_MAX", INT_MAX},
|
||||
{"UINT_MAX", UINT_MAX},
|
||||
};
|
||||
|
||||
ParseUtil::ParseUtil() { }
|
||||
|
||||
void ParseUtil::set_root(const QString &dir) {
|
||||
this->root = dir;
|
||||
ParseUtil::ParseUtil() {
|
||||
resetGlobalCDefines();
|
||||
}
|
||||
|
||||
QString ParseUtil::pathWithRoot(const QString &path) {
|
||||
|
|
@ -181,10 +163,14 @@ QList<Token> ParseUtil::tokenizeExpression(QString expression, QMap<QString, int
|
|||
QString token = match.captured(tokenType);
|
||||
if (!token.isEmpty()) {
|
||||
if (tokenType == "identifier") {
|
||||
// If this expression depends on a define we know of but haven't evaluated then evaluate it now
|
||||
if (unevaluatedExpressions->contains(token)) {
|
||||
// This expression depends on a define we know of but haven't evaluated. Evaluate it now
|
||||
evaluateDefine(token, unevaluatedExpressions->value(token), knownValues, unevaluatedExpressions);
|
||||
} else if (this->globalDefineExpressions.contains(token)) {
|
||||
int value = evaluateDefine(token, this->globalDefineExpressions.value(token), &this->globalDefineValues, &this->globalDefineExpressions);
|
||||
knownValues->insert(token, value);
|
||||
}
|
||||
|
||||
if (knownValues->contains(token)) {
|
||||
// Any errors encountered when this identifier was evaluated should be recorded for this expression as well.
|
||||
recordErrors(this->errorMap.value(token));
|
||||
|
|
@ -490,7 +476,7 @@ QMap<QString, int> ParseUtil::evaluateCDefines(const QString &filename, const QS
|
|||
|
||||
// Evaluate defines
|
||||
QMap<QString, int> filteredValues;
|
||||
QMap<QString, int> allValues = globalDefineValues;
|
||||
QMap<QString, int> allValues = this->globalDefineValues;
|
||||
this->errorMap.clear();
|
||||
while (!defines.filteredNames.isEmpty()) {
|
||||
const QString name = defines.filteredNames.takeFirst();
|
||||
|
|
@ -521,6 +507,32 @@ QStringList ParseUtil::readCDefineNames(const QString &filename, const QSet<QStr
|
|||
return readCDefines(filename, regexList, true, error).filteredNames;
|
||||
}
|
||||
|
||||
// Find any defines in the specified file and save their expressions.
|
||||
// If any of these defines are encountered later by other define parsing functions then they'll be recognized and evaluated.
|
||||
void ParseUtil::loadGlobalCDefines(const QString &filename, QString *error) {
|
||||
this->globalDefineExpressions.insert(readCDefines(filename, {}, false, error).expressions);
|
||||
}
|
||||
|
||||
void ParseUtil::resetGlobalCDefines() {
|
||||
static const QMap<QString, int> defaultDefineValues = {
|
||||
{"FALSE", 0},
|
||||
{"TRUE", 1},
|
||||
{"SCHAR_MIN", SCHAR_MIN},
|
||||
{"SCHAR_MAX", SCHAR_MAX},
|
||||
{"CHAR_MIN", CHAR_MIN},
|
||||
{"CHAR_MAX", CHAR_MAX},
|
||||
{"UCHAR_MAX", UCHAR_MAX},
|
||||
{"SHRT_MIN", SHRT_MIN},
|
||||
{"SHRT_MAX", SHRT_MAX},
|
||||
{"USHRT_MAX", USHRT_MAX},
|
||||
{"INT_MIN", INT_MIN},
|
||||
{"INT_MAX", INT_MAX},
|
||||
{"UINT_MAX", UINT_MAX},
|
||||
};
|
||||
this->globalDefineValues = defaultDefineValues;
|
||||
this->globalDefineExpressions.clear();
|
||||
}
|
||||
|
||||
QStringList ParseUtil::readCArray(const QString &filename, const QString &label) {
|
||||
QStringList list;
|
||||
|
||||
|
|
|
|||
|
|
@ -660,7 +660,7 @@ bool MainWindow::openProject(QString dir, bool initial) {
|
|||
|
||||
// Create the project
|
||||
auto project = new Project(editor);
|
||||
project->set_root(dir);
|
||||
project->setRoot(dir);
|
||||
connect(project, &Project::fileChanged, this, &MainWindow::showFileWatcherWarning);
|
||||
connect(project, &Project::mapLoaded, this, &MainWindow::onMapLoaded);
|
||||
connect(project, &Project::mapCreated, this, &MainWindow::onNewMapCreated);
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@ Project::~Project()
|
|||
QPixmapCache::clear();
|
||||
}
|
||||
|
||||
void Project::set_root(QString dir) {
|
||||
void Project::setRoot(const QString &dir) {
|
||||
this->root = dir;
|
||||
FileDialog::setDirectory(dir);
|
||||
this->parser.set_root(dir);
|
||||
this->parser.setRoot(dir);
|
||||
}
|
||||
|
||||
// Before attempting the initial project load we should check for a few notable files.
|
||||
|
|
@ -78,7 +78,8 @@ bool Project::sanityCheck() {
|
|||
bool Project::load() {
|
||||
resetFileCache();
|
||||
this->disabledSettingsNames.clear();
|
||||
bool success = readMapLayouts()
|
||||
bool success = readGlobalConstants()
|
||||
&& readMapLayouts()
|
||||
&& readRegionMapSections()
|
||||
&& readItemNames()
|
||||
&& readFlagNames()
|
||||
|
|
@ -2742,6 +2743,18 @@ bool Project::readMiscellaneousConstants() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Project::readGlobalConstants() {
|
||||
this->parser.resetGlobalCDefines();
|
||||
for (const auto &path : projectConfig.globalConstantsFilepaths) {
|
||||
QString error;
|
||||
this->parser.loadGlobalCDefines(path, &error);
|
||||
if (!error.isEmpty()) {
|
||||
logWarn(QString("Failed to read global constants file '%1': %2").arg(path).arg(error));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Project::readEventScriptLabels() {
|
||||
this->globalScriptLabels.clear();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user