]> Dogcows Code - chaz/carfire/blobdiff - CarFire/CarFire/CarFire/MapReader.cs
created a new project MapProcessorLib to for importing map files
[chaz/carfire] / CarFire / CarFire / CarFire / MapReader.cs
diff --git a/CarFire/CarFire/CarFire/MapReader.cs b/CarFire/CarFire/CarFire/MapReader.cs
new file mode 100644 (file)
index 0000000..35089ba
--- /dev/null
@@ -0,0 +1,287 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Runtime.Serialization;\r
+using System.Text.RegularExpressions;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Graphics;\r
+\r
+namespace CarFire\r
+{\r
+    /// <summary>\r
+    /// This class will be instantiated by the XNA Framework Content\r
+    /// Pipeline to read cfmap files from binary .xnb format.\r
+    /// </summary>\r
+    public class MapReader : ContentTypeReader<Map>\r
+    {\r
+        public class ParserException : System.ApplicationException\r
+        {\r
+            public ParserException()\r
+            {\r
+            }\r
+\r
+            public ParserException(string message) :\r
+                base(message)\r
+            {\r
+            }\r
+\r
+            public ParserException(string message, System.Exception inner) :\r
+                base(message, inner)\r
+            {\r
+            }\r
+\r
+            protected ParserException(SerializationInfo info, StreamingContext context) :\r
+                base(info, context)\r
+            {\r
+            }\r
+        }\r
+\r
+        ContentReader mInput;\r
+        int mLineNumber = 0;\r
+        int mExpectedNumberOfLines;\r
+\r
+        Map.Data mData;\r
+\r
+\r
+        protected override Map Read(ContentReader input, Map existingInstance)\r
+        {\r
+            mInput = input;\r
+            mExpectedNumberOfLines =  mInput.ReadInt32();\r
+\r
+            ReadData();\r
+\r
+            return new Map(mData);\r
+        }\r
+\r
+\r
+        #region Private Reading Methods\r
+        \r
+        string ReadLine()\r
+        {\r
+            return mInput.ReadString();\r
+        }\r
+\r
+        void ReadData()\r
+        {\r
+            mData = new Map.Data();\r
+\r
+            while (mLineNumber < mExpectedNumberOfLines)\r
+            {\r
+                string line = ReadLine();\r
+                mLineNumber++;\r
+\r
+                while (line != null)\r
+                {\r
+                    if (!IsLineSignificant(line)) break;\r
+\r
+                    string section = Parse.IniSectionHeader(line);\r
+                    if (section != null)\r
+                    {\r
+                        if (section == "metadata")\r
+                        {\r
+                            line = ReadMetadataSection();\r
+                        }\r
+                        else if (section == "maptable")\r
+                        {\r
+                            line = ReadMapTableSection();\r
+                        }\r
+                        else if (section.Length == 1)\r
+                        {\r
+                            line = ReadEntitySection(section[0]);\r
+                        }\r
+                        else\r
+                        {\r
+                            ThrowException("Unknown section", section);\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        ThrowException("Unexpected text", line);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        string ReadMetadataSection()\r
+        {\r
+            while (mLineNumber < mExpectedNumberOfLines)\r
+            {\r
+                string line = ReadLine();\r
+                mLineNumber++;\r
+\r
+                if (!IsLineSignificant(line)) continue;\r
+\r
+                string[] pair = Parse.KeyValuePair(line);\r
+                if (pair != null)\r
+                {\r
+                    if (pair[0] == "type")\r
+                    {\r
+                        object type = Parse.Constant<Map.Type>(pair[1]);\r
+                        if (type != null)\r
+                        {\r
+                            mData.Type = (Map.Type)type;\r
+                        }\r
+                        else\r
+                        {\r
+                            ThrowException("Invalid type", pair[1]);\r
+                        }\r
+                    }\r
+                    else if (pair[0] == "dimensions")\r
+                    {\r
+                        Point? dimensions = Parse.Coordinates(pair[1]);\r
+                        if (dimensions != null)\r
+                        {\r
+                            mData.Dimensions = dimensions.Value;\r
+                            if (mData.Dimensions.X <= 0 || mData.Dimensions.Y <= 0)\r
+                            {\r
+                                ThrowException("Invalid dimensions", pair[1]);\r
+                            }\r
+                        }\r
+                        else\r
+                        {\r
+                            ThrowException("Invalid value", pair[1]);\r
+                        }\r
+                    }\r
+                    else if (pair[0] == "tileset")\r
+                    {\r
+                        string tileset = Parse.String(pair[1]);\r
+                        if (tileset != null)\r
+                        {\r
+                            mData.Tileset = tileset;\r
+                        }\r
+                        else\r
+                        {\r
+                            ThrowException("Invalid tileset", pair[1]);\r
+                        }\r
+                    }\r
+                    else if (pair[0] == "numplayers")\r
+                    {\r
+                        int[] numPlayers = Parse.Range(pair[1]);\r
+                        if (numPlayers != null)\r
+                        {\r
+                            mData.MinNumPlayers = numPlayers[0];\r
+                            mData.MaxNumPlayers = numPlayers[1];\r
+                            if (mData.MinNumPlayers <= 0 || mData.MaxNumPlayers <= 0 ||\r
+                                mData.MinNumPlayers > mData.MaxNumPlayers)\r
+                            {\r
+                                ThrowException("Invalid range", pair[1]);\r
+                            }\r
+                        }\r
+                        else\r
+                        {\r
+                            ThrowException("Invalid value", pair[1]);\r
+                        }\r
+                    }\r
+                    else if (pair[0] == "author")\r
+                    {\r
+                        string author = Parse.String(pair[1]);\r
+                        if (author != null)\r
+                        {\r
+                            mData.Author = author;\r
+                        }\r
+                        else\r
+                        {\r
+                            ThrowException("Invalid value", pair[1]);\r
+                        }\r
+                    }\r
+                    else if (pair[0] == "levelname")\r
+                    {\r
+                        string level = Parse.String(pair[1]);\r
+                        if (level != null)\r
+                        {\r
+                            mData.Name = level;\r
+                        }\r
+                        else\r
+                        {\r
+                            ThrowException("Invalid value", pair[1]);\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        Console.WriteLine("Unimplemented key: " + pair[0]);\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    return line;\r
+                }\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        string ReadMapTableSection()\r
+        {\r
+            if (mData.Dimensions.X == 0 || mData.Dimensions.Y == 0)\r
+            {\r
+                ThrowException("Unexpected section", "You must define the map dimensions before this section.");\r
+            }\r
+\r
+            mData.Grid = new char[mData.Dimensions.X, mData.Dimensions.Y];\r
+\r
+            int y;\r
+            for (y = 0; y < mData.Dimensions.Y && mLineNumber < mExpectedNumberOfLines; y++)\r
+            {\r
+                string line = ReadLine();\r
+                mLineNumber++;\r
+\r
+                if (line.Length < mData.Dimensions.X)\r
+                {\r
+                    ThrowException("Not enough characters", "Expecting " + mData.Dimensions.X + " characters.");\r
+                }\r
+\r
+                for (int x = 0; x < mData.Dimensions.X; x++)\r
+                {\r
+                    mData.Grid[x, y] = line[x];\r
+                }\r
+            }\r
+\r
+            if (y < mData.Dimensions.Y)\r
+            {\r
+                ThrowException("Unexpected ", "");\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        string ReadEntitySection(char entity)\r
+        {\r
+            while (mLineNumber < mExpectedNumberOfLines)\r
+            {\r
+                string line = ReadLine();\r
+                mLineNumber++;\r
+\r
+                string[] pair = Parse.KeyValuePair(line);\r
+                if (pair != null)\r
+                {\r
+                    // TODO\r
+                }\r
+                else\r
+                {\r
+                    return line;\r
+                }\r
+            }\r
+\r
+            return null;\r
+        }\r
+\r
+        #endregion\r
+\r
+\r
+        #region Private Methods\r
+\r
+        bool IsLineSignificant(string line)\r
+        {\r
+            if (line.Length == 0 || Regex.IsMatch(line, @"^;|^\s*$")) return false;\r
+            return true;\r
+        }\r
+\r
+        void ThrowException(string problem, string text)\r
+        {\r
+            throw new ParserException(problem + " on line " + mLineNumber + ": " + text);\r
+        }\r
+\r
+        #endregion\r
+    }\r
+}\r
This page took 0.026142 seconds and 4 git commands to generate.