AGI: support new WinAGI *.wag file format

This commit is contained in:
Zvika Haramaty 2021-02-10 21:23:14 +02:00 committed by Filippos Karapetis
parent 6609abf1d0
commit 03fb100226
3 changed files with 60 additions and 4 deletions

View File

@ -32,7 +32,7 @@ bool INIFile::isValidName(const String &name) const {
if (_allowNonEnglishCharacters)
return true;
const char *p = name.c_str();
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' '))
while (*p && (isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' ' || *p == ':'))
p++;
return *p == 0;
}
@ -109,7 +109,8 @@ bool INIFile::loadFromStream(SeekableReadStream &stream) {
// is, verify that it only consists of alphanumerics,
// periods, dashes and underscores). Mohawk Living Books games
// can have periods in their section names.
while (*p && ((_allowNonEnglishCharacters && *p != ']') || isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' '))
// WinAGI games can have colons in their section names.
while (*p && ((_allowNonEnglishCharacters && *p != ']') || isAlnum(*p) || *p == '-' || *p == '_' || *p == '.' || *p == ' ' || *p == ':'))
p++;
if (*p == '\0')

View File

@ -25,6 +25,7 @@
#include "common/fs.h"
#include "common/debug.h"
#include "common/textconsole.h"
#include "common/ini-file.h"
#include "agi/wagparser.h"
@ -170,6 +171,16 @@ bool WagFileParser::checkWagVersion(Common::SeekableReadStream &stream) {
}
}
void WagFileParser::addPropFromIni(Common::INIFile *iniWagFile, Common::String section, Common::String key, Agi::WagProperty::WagPropertyCode code) {
WagProperty property;
property.setPropCode(code);
Common::String value;
if (iniWagFile->getKey(key, section, value)) {
property.setPropDataSize(value);
_propList.push_back(property);
}
}
bool WagFileParser::parse(const Common::FSNode &node) {
WagProperty property; // Temporary property used for reading
Common::SeekableReadStream *stream = NULL; // The file stream
@ -198,8 +209,21 @@ bool WagFileParser::parse(const Common::FSNode &node) {
if (!_parsedOk) // Error parsing stream
warning("Error parsing WAG file (%s). WAG file ignored", node.getPath().c_str());
} else // Invalid WinAGI version string or it couldn't be read
warning("Invalid WAG file (%s) version or error reading it. WAG file ignored", node.getPath().c_str());
} else {
// Invalid WinAGI version string or it couldn't be read
// Let's try to read WAG file as newer INI format
Common::INIFile *iniWagFile = new Common::INIFile();
_parsedOk = iniWagFile->loadFromStream(*stream);
if (_parsedOk) {
addPropFromIni(iniWagFile, "General", "Interpreter", WagProperty::PC_INTVERSION);
addPropFromIni(iniWagFile, "General", "GameID", WagProperty::PC_GAMEID);
addPropFromIni(iniWagFile, "General", "Description", WagProperty::PC_GAMEDESC);
addPropFromIni(iniWagFile, "General", "GameVersion", WagProperty::PC_GAMEVERSION);
addPropFromIni(iniWagFile, "General", "LastEdit", WagProperty::PC_GAMELAST);
} else
warning("Invalid WAG file (%s) version or error reading it. WAG file ignored", node.getPath().c_str());
}
} else // Couldn't open file
warning("Couldn't open WAG file (%s). WAG file ignored", node.getPath().c_str());
@ -217,4 +241,14 @@ bool WagFileParser::endOfProperties(const Common::SeekableReadStream &stream) co
return stream.pos() >= (stream.size() - WINAGI_VERSION_LENGTH);
}
void WagProperty::setPropCode(WagPropertyCode propCode) {
_propCode = propCode;
}
void WagProperty::setPropDataSize(Common::String str) {
_propData = scumm_strdup(str.c_str());
_propSize = str.size();
}
} // End of namespace Agi

View File

@ -180,6 +180,18 @@ public:
*/
const char *getData() const { return _propData; }
/**
* Set property's code
* @param propCode the code value to set
*/
void setPropCode(WagPropertyCode propCode);
/**
* Set property's data and property's size
* @param str the string that according to it these are set
*/
void setPropDataSize(Common::String str);
// Member variables
protected:
bool _readOk; ///< Was the property read ok from the source stream?
@ -214,6 +226,15 @@ public:
*/
~WagFileParser();
/**
* Add property to _propList from INI file, if key exist
* @param iniWagFile ini loaded from WAG file stream
* @param section ini section
* @param key ini key
* @param code corresponding WAG code
*/
void addPropFromIni(Common::INIFile *iniWagFile, Common::String section, Common::String key, Agi::WagProperty::WagPropertyCode code);
/**
* Loads a *.wag file and parses it.
* @note After this you can access the loaded properties using getProperty() and getProperties() etc.