diff --git a/axios.suo b/axios.suo
index ebbe51d..d52e932 100644
Binary files a/axios.suo and b/axios.suo differ
diff --git a/axios/Axios_WP7.csproj b/axios/Axios_WP7.csproj
index 1eb439b..c08a9d5 100644
--- a/axios/Axios_WP7.csproj
+++ b/axios/Axios_WP7.csproj
@@ -172,6 +172,7 @@
+
diff --git a/axios/Axios_Windows.csproj b/axios/Axios_Windows.csproj
index a6d6a15..e97654d 100644
--- a/axios/Axios_Windows.csproj
+++ b/axios/Axios_Windows.csproj
@@ -215,6 +215,7 @@
+
diff --git a/axios/Axios_Xbox_360.csproj b/axios/Axios_Xbox_360.csproj
index 29027e3..a982dc3 100644
--- a/axios/Axios_Xbox_360.csproj
+++ b/axios/Axios_Xbox_360.csproj
@@ -165,6 +165,7 @@
+
diff --git a/axios/Axios_settings.cs b/axios/Axios_settings.cs
index 381763e..d54ed88 100644
--- a/axios/Axios_settings.cs
+++ b/axios/Axios_settings.cs
@@ -69,6 +69,7 @@
* - Adding SplitFlat extension for Texture2D
* - Removing uneeded Game Screen checking code
* - Adding SplitFlat extension with offsets for Texture2D
+ * - Adding support for Glee2D
*
*/
diff --git a/axios/Engine/Glee2D/Level.cs b/axios/Engine/Glee2D/Level.cs
new file mode 100644
index 0000000..eba32c8
--- /dev/null
+++ b/axios/Engine/Glee2D/Level.cs
@@ -0,0 +1,505 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Content;
+using System.IO;
+using FarseerPhysics.Dynamics;
+using FarseerPhysics.Common;
+using FarseerPhysics.SamplesFramework;
+using FarseerPhysics.Factories;
+
+namespace Axios.Engine.Glee2D
+{
+ public partial class Level
+ {
+ private World _world;
+
+ ///
+ /// The name of the level.
+ ///
+ [XmlAttribute()]
+ public String Name;
+
+ [XmlAttribute()]
+ public bool Visible;
+
+ ///
+ /// A Level contains several Layers. Each Layer contains several Items.
+ ///
+ public List Layers;
+
+ ///
+ /// A Dictionary containing any user-defined Properties.
+ ///
+ public SerializableDictionary CustomProperties;
+
+
+ public Level()
+ {
+ Visible = true;
+ Layers = new List();
+ CustomProperties = new SerializableDictionary();
+ }
+
+ public Level(World world)
+ {
+ Visible = true;
+ Layers = new List();
+ CustomProperties = new SerializableDictionary();
+ _world = world;
+ }
+
+ public static Level FromFile(string filename, ContentManager cm, World world)
+ {
+ FileStream stream = System.IO.File.Open(filename, FileMode.Open);
+ XmlSerializer serializer = new XmlSerializer(typeof(Level));
+ Level level = (Level)serializer.Deserialize(stream);
+ stream.Close();
+
+ foreach (Layer layer in level.Layers)
+ {
+ foreach (Item item in layer.Items)
+ {
+ item.CustomProperties.RestoreItemAssociations(level);
+ item.load(cm, world);
+ }
+ }
+
+ return level;
+ }
+
+ public Item getItemByName(string name)
+ {
+ foreach (Layer layer in Layers)
+ {
+ foreach (Item item in layer.Items)
+ {
+ if (item.Name == name) return item;
+ }
+ }
+ return null;
+ }
+
+ public Layer getLayerByName(string name)
+ {
+ foreach (Layer layer in Layers)
+ {
+ if (layer.Name == name) return layer;
+ }
+ return null;
+ }
+
+ public void draw(SpriteBatch sb)
+ {
+ foreach (Layer layer in Layers) layer.draw(sb);
+ }
+
+
+ }
+
+
+ public partial class Layer
+ {
+ ///
+ /// The name of the layer.
+ ///
+ [XmlAttribute()]
+ public String Name;
+
+ ///
+ /// Should this layer be visible?
+ ///
+ [XmlAttribute()]
+ public bool Visible;
+
+ ///
+ /// The list of the items in this layer.
+ ///
+ public List- Items;
+
+ ///
+ /// The Scroll Speed relative to the main camera. The X and Y components are
+ /// interpreted as factors, so (1;1) means the same scrolling speed as the main camera.
+ /// Enables parallax scrolling.
+ ///
+ public Vector2 ScrollSpeed;
+
+
+ public Layer()
+ {
+ Items = new List
- ();
+ ScrollSpeed = Vector2.One;
+ }
+
+ public void draw(SpriteBatch sb)
+ {
+ if (!Visible) return;
+ foreach (Item item in Items) item.draw(sb);
+ }
+
+ }
+
+
+ [XmlInclude(typeof(TextureItem))]
+ [XmlInclude(typeof(RectangleItem))]
+ [XmlInclude(typeof(CircleItem))]
+ [XmlInclude(typeof(PathItem))]
+ public partial class Item
+ {
+ ///
+ /// The name of this item.
+ ///
+ [XmlAttribute()]
+ public String Name;
+
+ ///
+ /// Should this item be visible?
+ ///
+ [XmlAttribute()]
+ public bool Visible;
+
+ ///
+ /// The item's position in world space.
+ ///
+ public Vector2 Position;
+
+ ///
+ /// A Dictionary containing any user-defined Properties.
+ ///
+ public SerializableDictionary CustomProperties;
+
+
+ public Item()
+ {
+ CustomProperties = new SerializableDictionary();
+ }
+
+ ///
+ /// Called by Level.FromFile(filename) on each Item after the deserialization process.
+ /// Should be overriden and can be used to load anything needed by the Item (e.g. a texture).
+ ///
+ public virtual void load(ContentManager cm, World world)
+ {
+ }
+
+ public virtual void draw(SpriteBatch sb)
+ {
+ }
+ }
+
+
+ public partial class TextureItem : Item
+ {
+ ///
+ /// The item's rotation in radians.
+ ///
+ public float Rotation;
+
+ ///
+ /// The item's scale factor.
+ ///
+ public float Scale;
+
+ ///
+ /// The color to tint the item's texture with (use white for no tint).
+ ///
+ public Color TintColor;
+
+ ///
+ /// If true, the texture is flipped horizontally when drawn.
+ ///
+ public bool FlipHorizontally;
+
+ ///
+ /// If true, the texture is flipped vertically when drawn.
+ ///
+ public bool FlipVertically;
+
+ ///
+ /// The path to the texture's filename (including the extension) relative to ContentRootFolder.
+ ///
+ public String texture_filename;
+
+ ///
+ /// The texture_filename without extension. For using in Content.Load().
+ ///
+ public String asset_name;
+
+ ///
+ /// The XNA texture to be drawn. Can be loaded either from file (using "texture_filename")
+ /// or via the Content Pipeline (using "asset_name") - then you must ensure that the texture
+ /// exists as an asset in your project.
+ /// Loading is done in the Item's load() method.
+ ///
+ Texture2D texture;
+
+ ///
+ /// The item's origin relative to the upper left corner of the texture. Usually the middle of the texture.
+ /// Used for placing and rotating the texture when drawn.
+ ///
+ public Vector2 Origin;
+
+
+ public TextureItem()
+ {
+ }
+
+ ///
+ /// Called by Level.FromFile(filename) on each Item after the deserialization process.
+ /// Loads all assets needed by the TextureItem, especially the Texture2D.
+ /// You must provide your own implementation. However, you can rely on all public fields being
+ /// filled by the level deserialization process.
+ ///
+ public override void load(ContentManager cm, World world)
+ {
+ //throw new NotImplementedException();
+
+ //TODO: provide your own implementation of how a TextureItem loads its assets
+ //for example:
+ //this.texture = Texture2D.FromFile(, texture_filename);
+ //or by using the Content Pipeline:
+ this.texture = cm.Load(asset_name);
+
+ }
+
+ public override void draw(SpriteBatch sb)
+ {
+ if (!Visible) return;
+ SpriteEffects effects = SpriteEffects.None;
+ if (FlipHorizontally) effects |= SpriteEffects.FlipHorizontally;
+ if (FlipVertically) effects |= SpriteEffects.FlipVertically;
+ sb.Draw(texture, Position, null, TintColor, Rotation, Origin, Scale, effects, 0);
+ }
+ }
+
+
+ public partial class RectangleItem : Item
+ {
+ public float Width;
+ public float Height;
+ public Color FillColor;
+
+ Body _body;
+
+ public RectangleItem()
+ {
+ }
+
+ public override void load(ContentManager cm, World world)
+ {
+ base.load(cm, world);
+
+ _body = BodyFactory.CreateRectangle(world, Width, Height, 1f);
+ _body.Position = Position;
+ _body.UserData = this;
+ }
+ }
+
+
+ public partial class CircleItem : Item
+ {
+ public float Radius;
+ public Color FillColor;
+
+ Body _body;
+
+ public CircleItem()
+ {
+ }
+
+ public override void load(ContentManager cm, World world)
+ {
+ base.load(cm, world);
+
+ _body = BodyFactory.CreateCircle(world, Radius, 1f);
+ _body.Position = Position;
+ _body.UserData = this;
+ }
+
+ }
+
+
+ public partial class PathItem : Item
+ {
+ public Vector2[] LocalPoints;
+ public Vector2[] WorldPoints;
+ public bool IsPolygon;
+ public int LineWidth;
+ public Color LineColor;
+
+ Body _body;
+
+ public PathItem()
+ {
+ }
+
+ public override void load(ContentManager cm, World world)
+ {
+ base.load(cm, world);
+
+ Vertices v = new Vertices(WorldPoints.Length);
+ foreach (Vector2 vec in WorldPoints)
+ v.Add(new Vector2(ConvertUnits.ToSimUnits(vec.X), ConvertUnits.ToSimUnits(vec.Y)));
+
+ _body = BodyFactory.CreateLoopShape(world, v);
+ _body.Position = this.Position;
+ _body.UserData = this;
+ }
+
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // NEEDED FOR SERIALIZATION. YOU SHOULDN'T CHANGE ANYTHING BELOW!
+ //
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+
+ public class CustomProperty
+ {
+ public string name;
+ public object value;
+ public Type type;
+ public string description;
+
+ public CustomProperty()
+ {
+ }
+
+ public CustomProperty(string n, object v, Type t, string d)
+ {
+ name = n;
+ value = v;
+ type = t;
+ description = d;
+ }
+
+ public CustomProperty clone()
+ {
+ CustomProperty result = new CustomProperty(name, value, type, description);
+ return result;
+ }
+ }
+
+
+ public class SerializableDictionary : Dictionary, IXmlSerializable
+ {
+
+ public SerializableDictionary()
+ : base()
+ {
+
+ }
+
+ public SerializableDictionary(SerializableDictionary copyfrom)
+ : base(copyfrom)
+ {
+ string[] keyscopy = new string[Keys.Count];
+ Keys.CopyTo(keyscopy, 0);
+ foreach (string key in keyscopy)
+ {
+ this[key] = this[key].clone();
+ }
+ }
+
+ public System.Xml.Schema.XmlSchema GetSchema()
+ {
+ return null;
+ }
+
+ public void ReadXml(System.Xml.XmlReader reader)
+ {
+
+ bool wasEmpty = reader.IsEmptyElement;
+ reader.Read();
+
+ if (wasEmpty) return;
+
+ while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
+ {
+ CustomProperty cp = new CustomProperty();
+ cp.name = reader.GetAttribute("Name");
+ cp.description = reader.GetAttribute("Description");
+
+ string type = reader.GetAttribute("Type");
+ if (type == "string") cp.type = typeof(string);
+ if (type == "bool") cp.type = typeof(bool);
+ if (type == "Vector2") cp.type = typeof(Vector2);
+ if (type == "Color") cp.type = typeof(Color);
+ if (type == "Item") cp.type = typeof(Item);
+
+ if (cp.type == typeof(Item))
+ {
+ cp.value = reader.ReadInnerXml();
+ this.Add(cp.name, cp);
+ }
+ else
+ {
+ reader.ReadStartElement("Property");
+ XmlSerializer valueSerializer = new XmlSerializer(cp.type);
+ object obj = valueSerializer.Deserialize(reader);
+#if WINDOWS
+ cp.value = Convert.ChangeType(obj, cp.type);
+#elif WINDOWS_PHONE || XBOX360
+ cp.value = Convert.ChangeType(obj, cp.type, null);
+#endif
+ this.Add(cp.name, cp);
+ reader.ReadEndElement();
+ }
+
+ reader.MoveToContent();
+ }
+ reader.ReadEndElement();
+ }
+
+ public void WriteXml(System.Xml.XmlWriter writer)
+ {
+ foreach (String key in this.Keys)
+ {
+ writer.WriteStartElement("Property");
+ writer.WriteAttributeString("Name", this[key].name);
+ if (this[key].type == typeof(string)) writer.WriteAttributeString("Type", "string");
+ if (this[key].type == typeof(bool)) writer.WriteAttributeString("Type", "bool");
+ if (this[key].type == typeof(Vector2)) writer.WriteAttributeString("Type", "Vector2");
+ if (this[key].type == typeof(Color)) writer.WriteAttributeString("Type", "Color");
+ if (this[key].type == typeof(Item)) writer.WriteAttributeString("Type", "Item");
+ writer.WriteAttributeString("Description", this[key].description);
+
+ if (this[key].type == typeof(Item))
+ {
+ Item item = (Item)this[key].value;
+ if (item != null) writer.WriteString(item.Name);
+ else writer.WriteString("$null$");
+ }
+ else
+ {
+ XmlSerializer valueSerializer = new XmlSerializer(this[key].type);
+ valueSerializer.Serialize(writer, this[key].value);
+ }
+ writer.WriteEndElement();
+ }
+ }
+
+ ///
+ /// Must be called after all Items have been deserialized.
+ /// Restores the Item references in CustomProperties of type Item.
+ ///
+ public void RestoreItemAssociations(Level level)
+ {
+ foreach (CustomProperty cp in Values)
+ {
+ if (cp.type == typeof(Item)) cp.value = level.getItemByName((string)cp.value);
+ }
+ }
+
+
+ }
+}