aboutsummaryrefslogtreecommitdiff
path: root/engines/agi/wagparser.h
diff options
context:
space:
mode:
authorEugene Sandulenko2007-06-14 12:06:12 +0000
committerEugene Sandulenko2007-06-14 12:06:12 +0000
commit4d4cd489f5c544f2b1e3e56d595a5f876ffa56af (patch)
treec9c62cb1e6179b26fbe2a4328efa69c5d197c405 /engines/agi/wagparser.h
parent24daa86bdd71cb2f13f9efcce49198d290d3acb3 (diff)
downloadscummvm-rg350-4d4cd489f5c544f2b1e3e56d595a5f876ffa56af.tar.gz
scummvm-rg350-4d4cd489f5c544f2b1e3e56d595a5f876ffa56af.tar.bz2
scummvm-rg350-4d4cd489f5c544f2b1e3e56d595a5f876ffa56af.zip
Patch #1735773: "WAG file parsing patch to AGI's fallback detector".
Slightly modified, split into separate files. svn-id: r27401
Diffstat (limited to 'engines/agi/wagparser.h')
-rw-r--r--engines/agi/wagparser.h288
1 files changed, 288 insertions, 0 deletions
diff --git a/engines/agi/wagparser.h b/engines/agi/wagparser.h
new file mode 100644
index 0000000000..e8ce9468a0
--- /dev/null
+++ b/engines/agi/wagparser.h
@@ -0,0 +1,288 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+namespace Agi {
+
+/**
+ * WagProperty represents a single property from WinAGI's *.wag file.
+ * A property consists of a header and of data.
+ * The header consists of the following:
+ * - Property code (Integer/Enumeration, 1 byte)
+ * - Property type (Integer/Enumeration, 1 byte)
+ * - Property number (Integer, 1 byte)
+ * - Property size (Little endian integer, 2 bytes)
+ * And then there's the data with as many bytes as defined in the header's property size variable.
+ */
+class WagProperty {
+// Constants, enumerations etc
+public:
+ /**
+ * Property codes taken from WinAGI 1.1.21's source code file WinAGI/AGIObjects.bas.
+ */
+ enum WagPropertyCode {
+ PC_GAMEDESC = 129, ///< Game description (WinAGI 1.1.21 limits these to 4096 bytes)
+ PC_GAMEAUTHOR, ///< Game author (WinAGI 1.1.21 limits these to 256 bytes)
+ PC_GAMEID, ///< Game ID
+ PC_INTVERSION, ///< Interpreter version (WinAGI 1.1.21 defaults to version 2.917)
+ PC_GAMELAST, ///< Last edit date
+ PC_GAMEVERSION, ///< Game version (WinAGI 1.1.21 limits these to 256 bytes)
+ PC_GAMEABOUT, ///< About game (WinAGI 1.1.21 limits these to 4096 bytes)
+ PC_GAMEEXEC, ///< Game executable
+ PC_RESDIR, ///< Resource directory name
+ PC_DEFSYNTAX, ///< Default syntax
+ PC_INVOBJDESC = 144,
+ PC_VOCABWORDDESC = 160,
+ PC_PALETTE = 172,
+ PC_USERESNAMES = 180,
+ PC_LOGIC = 192,
+ PC_PICTURE = 208,
+ PC_SOUND = 224,
+ PC_VIEW = 240,
+ PC_UNDEFINED = 0x100 ///< An undefined property code (Added for ScummVM).
+ };
+
+ /**
+ * Property types taken from WinAGI 1.1.21's source code file WinAGI/AGIObjects.bas.
+ * At the moment these aren't really at all needed by ScummVM. Just here if anyone decides to use them.
+ */
+ enum WagPropertyType {
+ PT_ID,
+ PT_DESC,
+ PT_SYNTAX,
+ PT_CRC32,
+ PT_KEY,
+ PT_INST0,
+ PT_INST1,
+ PT_INST2,
+ PT_MUTE0,
+ PT_MUTE1,
+ PT_MUTE2,
+ PT_MUTE3,
+ PT_TPQN,
+ PT_ROOM,
+ PT_VIS0,
+ PT_VIS1,
+ PT_VIS2,
+ PT_VIS3,
+ PT_ALL = 0xff,
+ PT_UNDEFINED = 0x100 ///< An undefined property type (Added for ScummVM).
+ };
+
+// Constructors, destructors, operators etc
+public:
+ /**
+ * Creates an empty WagProperty object.
+ * No property header or property data in it.
+ */
+ WagProperty();
+
+ /**
+ * Destructor. Releases allocated memory if any etc. The usual.
+ */
+ ~WagProperty();
+
+ /**
+ * Copy constructor. Deep copies the variables.
+ */
+ WagProperty(const WagProperty &other);
+
+ /**
+ * Assignment operator. Deep copies the variables.
+ */
+ WagProperty &operator=(const WagProperty &other);
+
+// Non-public helper methods
+protected:
+ /**
+ * Sets the default values for member variables.
+ */
+ void setDefaults();
+
+ /**
+ * Delete's the property's data from memory if we have it, otherwise does nothing.
+ */
+ void deleteData();
+
+ /**
+ * Deep copies the parameter object to this object.
+ * @param other The object to be deep copied to this object.
+ */
+ void deepCopy(const WagProperty &other);
+
+// Public methods that have side-effects
+public:
+ /**
+ * Read in a property (Header and data).
+ * @return True if reading was a success, false otherwise.
+ */
+ bool read(Common::SeekableReadStream &stream);
+
+ /**
+ * Clears the property.
+ * After this the property is empty. No header or data.
+ */
+ void clear();
+
+// Public access functions
+public:
+ /**
+ * Was the property read ok from the source stream?
+ */
+ bool readOk() const { return _readOk; };
+
+ /**
+ * Return the property's code.
+ * @return The property's code if readOk(), PC_UNDEFINED otherwise.
+ */
+ enum WagPropertyCode getCode() const { return _propCode; };
+
+ /**
+ * Return the property's type.
+ * @return The property's type if readOk(), PT_UNDEFINED otherwise.
+ */
+ enum WagPropertyType getType() const { return _propType; };
+
+ /**
+ * Return the property's number.
+ * @return The property's number if readOk(), 0 otherwise.
+ */
+ byte getNumber() const { return _propNum; };
+
+ /**
+ * Return the property's data's length.
+ * @return The property's data's length if readOk(), 0 otherwise.
+ */
+ uint16 getSize() const { return _propSize; }
+
+ /**
+ * Return property's data. Constant access version.
+ * Can be used as a C-style string (i.e. this is guaranteed to have a trailing zero).
+ * @return The property's data if readOk(), NULL otherwise.
+ */
+ const char *getData() const { return _propData; };
+
+// Member variables
+protected:
+ bool _readOk; ///< Was the property read ok from the source stream?
+ enum WagPropertyCode _propCode; ///< Property code (Part of the property's header)
+ enum WagPropertyType _propType; ///< Property type (Part of the property's header)
+ byte _propNum; ///< Property number (Part of the property's header)
+ uint16 _propSize; ///< Property's size (Part of the property's header)
+ char *_propData; ///< The property's data (Plus a trailing zero for C-style string access)
+};
+
+
+/**
+ * Class for parsing *.wag files created by WinAGI.
+ * Using this class you can get information about fanmade AGI games if they have provided a *.wag file with them.
+ */
+class WagFileParser {
+// Constants, type definitions, enumerations etc.
+public:
+ static const int WINAGI_VERSION_LENGTH = 16; ///< WinAGI's version string's length (Always 16)
+ typedef Common::Array<WagProperty> PropertyList; ///< A type definition for an array of *.wag file properties
+
+public:
+ /**
+ * Constructor. Creates a WagFileParser object in a default state.
+ */
+ WagFileParser();
+
+ /**
+ * Destructor.
+ */
+ ~WagFileParser();
+
+ /**
+ * Loads a *.wag file and parses it.
+ * @note After this you can access the loaded properties using getProperty() and getProperties() etc.
+ * @param filename Name of the file to be parsed.
+ * @return True if parsed successfully, false otherwise.
+ */
+ bool parse(const char *filename);
+
+ /**
+ * Get list of the loaded properties.
+ * @note Use only after a call to parse() first.
+ * @return The list of loaded properties.
+ */
+ const PropertyList &getProperties() const { return _propList; };
+
+ /**
+ * Get property with the given property code.
+ * @note Use only after a call to parse() first.
+ * @return Pointer to the property if its found in memory, NULL otherwise.
+ *
+ * TODO/FIXME: Handle cases where several properties with the given property code are found.
+ * At the moment we don't need this functionality because the properties we use
+ * for fallback detection probably don't have multiples in the WAG-file.
+ * TODO: Make this faster than linear time if desired/needed.
+ */
+ const WagProperty *getProperty(const WagProperty::WagPropertyCode code) const;
+
+ /**
+ * Tests if the given property contains a valid AGI interpreter version string.
+ * A valid AGI interpreter version string is of the form "X.Y" or "X,Y" where
+ * X is a single decimal digit and Y is a string of decimal digits (At least one digit).
+ * @param version The property to be tested.
+ * @return True if the given property contains a valid AGI interpreter version string, false otherwise.
+ */
+ bool checkAgiVersionProperty(const WagProperty &version) const;
+
+ /**
+ * Convert property's data to an AGI interpreter version number.
+ * @param version The property to be converted (Property code should be PC_INTVERSION).
+ * @return AGI interpreter version number if successful, 0 otherwise.
+ */
+ uint16 convertToAgiVersionNumber(const WagProperty &version);
+
+ /**
+ * Was the file parsed successfully?
+ * @return True if file was parsed successfully, false otherwise.
+ */
+ bool parsedOk() const { return _parsedOk; };
+
+protected:
+ /**
+ * Checks if stream has a valid WinAGI version string in its end.
+ * @param stream The stream to be checked.
+ * @return True if reading was successful and stream contains a valid WinAGI version string, false otherwise.
+ */
+ bool checkWagVersion(Common::SeekableReadStream &stream);
+
+ /**
+ * Checks if we're at or past the end of the properties stored in the stream.
+ * @param stream The stream whose seeking position is to be checked.
+ * @return True if stream's seeking position is at or past the end of the properties, false otherwise.
+ */
+ bool endOfProperties(const Common::SeekableReadStream &stream) const;
+
+// Member variables
+protected:
+ PropertyList _propList; ///< List of loaded properties from the file.
+ bool _parsedOk; ///< Did the parsing of the file go ok?
+};
+
+} // End of namespace Agi