summaryrefslogtreecommitdiff
path: root/Sprite.cs
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2005-07-30 01:55:41 +0000
committerIan C <ianc@noddybox.co.uk>2005-07-30 01:55:41 +0000
commit93ac9c657ce285c5daa5a3ea6ed8c91b50e0281c (patch)
tree40524242c2f73c6b922e2152f63b233f02545852 /Sprite.cs
parentbe2ad76237e13937a37a4a9c419300bba563712c (diff)
Development checkin
Diffstat (limited to 'Sprite.cs')
-rw-r--r--Sprite.cs546
1 files changed, 546 insertions, 0 deletions
diff --git a/Sprite.cs b/Sprite.cs
new file mode 100644
index 0000000..47678e9
--- /dev/null
+++ b/Sprite.cs
@@ -0,0 +1,546 @@
+// BitmapSpriteEd - Bitmap Sprite Editor
+// Copyright (C) 2005 Ian Cowburn
+//
+// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// $Id$
+//
+using System;
+using System.Drawing;
+using System.IO;
+using System.Collections;
+
+namespace BitmapSpriteEd
+{
+ /// <summary>
+ /// A sprite frame.
+ /// </summary>
+ public class Frame
+ {
+ public Frame(int width, int height)
+ {
+ CheckSize(width,height);
+ m_width=width;
+ m_height=height;
+ m_data=new Color[m_width,m_height];
+ Clear(Color.Transparent);
+ m_changed=false;
+ }
+
+ public Frame() : this(16,16)
+ {
+ }
+
+ public Frame(Frame old)
+ {
+ m_width=old.m_width;
+ m_height=old.m_height;
+ m_data=new Color[m_width,m_height];
+
+ for(int x=0;x<m_width;x++)
+ {
+ for(int y=0;y<m_height;y++)
+ {
+ m_data[x,y]=old.m_data[x,y];
+ }
+ }
+
+ m_changed=old.m_changed;
+ }
+
+ public int Width
+ {
+ get {return m_width;}
+ }
+
+ public int Height
+ {
+ get {return m_height;}
+ }
+
+ public bool Changed
+ {
+ get {return m_changed;}
+ }
+
+ public void Resize(int width, int height)
+ {
+ CheckSize(width,height);
+
+ if (width==m_width && height==m_height)
+ {
+ return;
+ }
+
+ Color[,] data=new Color[width,height];
+
+ for(int y=0;y<height;y++)
+ {
+ for(int x=0;x<width;x++)
+ {
+ data[x,y]=Color.Transparent;
+ }
+ }
+
+ int mx=Math.Min(width,m_width);
+ int my=Math.Min(height,m_height);
+
+ for(int x=0;x<mx;x++)
+ {
+ for(int y=0;y<my;y++)
+ {
+ data[x,y]=m_data[x,y];
+ }
+ }
+
+ m_width=width;
+ m_height=height;
+ m_data=data;
+ m_changed=true;
+ }
+
+ public Color this [int x, int y]
+ {
+ set
+ {
+ m_data[x,y]=value;
+ m_changed=true;
+ }
+ get {return m_data[x,y];}
+ }
+
+ public void Clear(Color c)
+ {
+ for(int y=0;y<m_height;y++)
+ {
+ for(int x=0;x<m_width;x++)
+ {
+ m_data[x,y]=c;
+ }
+ }
+
+ m_changed=true;
+ }
+
+ public void MirrorHorizontal()
+ {
+ Color[,] d=new Color[m_width,m_height];
+
+ for(int y=0;y<m_height;y++)
+ for(int x=0;x<m_width;x++)
+ d[x,y]=m_data[m_width-x-1,y];
+
+ m_data=d;
+ m_changed=true;
+ }
+
+ public void MirrorVertical()
+ {
+ Color[,] d=new Color[m_width,m_height];
+
+ for(int y=0;y<m_height;y++)
+ for(int x=0;x<m_width;x++)
+ d[x,y]=m_data[x,m_height-y-1];
+
+ m_data=d;
+ m_changed=true;
+ }
+
+ public void Scroll(int dx, int dy)
+ {
+ Color[,] d=new Color[m_width,m_height];
+
+ for(int y=0;y<m_height;y++)
+ for(int x=0;x<m_width;x++)
+ d[Mod(x+dx,m_width),Mod(y+dy,m_height)]=m_data[x,y];
+
+ m_data=d;
+ m_changed=true;
+ }
+
+ public void RotateRight()
+ {
+ Color[,] d=new Color[m_width,m_height];
+ int min=Math.Min(m_width,m_height);
+
+ for(int y=0;y<m_height;y++)
+ for(int x=0;x<m_width;x++)
+ {
+ long nx=min-y-1;
+ long ny=x;
+
+ if (nx>=0 && nx<m_width && ny>=0 && ny<m_height)
+ {
+ d[nx,ny]=m_data[x,y];
+ }
+ }
+
+ m_data=d;
+ m_changed=true;
+ }
+
+ public void RotateLeft()
+ {
+ Color[,] d=new Color[m_width,m_height];
+ int min=Math.Min(m_width,m_height);
+
+ for(int y=0;y<m_height;y++)
+ for(int x=0;x<m_width;x++)
+ {
+ long nx=y;
+ long ny=min-x-1;
+
+ if (nx>=0 && nx<m_width && ny>=0 && ny<m_height)
+ {
+ d[nx,ny]=m_data[x,y];
+ }
+ }
+
+ m_data=d;
+ m_changed=true;
+ }
+
+ public void Output(Stream stream)
+ {
+ Util.WriteInt(stream,m_width);
+ Util.WriteInt(stream,m_height);
+
+ for(int x=0;x<m_width;x++)
+ {
+ for(int y=0;y<m_height;y++)
+ {
+ stream.WriteByte(m_data[x,y].B);
+ stream.WriteByte(m_data[x,y].G);
+ stream.WriteByte(m_data[x,y].R);
+ stream.WriteByte(m_data[x,y].A);
+ }
+ }
+
+ m_changed=false;
+ }
+
+ public static Frame Input(Stream stream)
+ {
+ int width=Util.ReadInt(stream);
+ int height=Util.ReadInt(stream);
+
+ Frame s=new Frame(width,height);
+
+ for(int x=0;x<width;x++)
+ {
+ for(int y=0;y<height;y++)
+ {
+ int B=stream.ReadByte();
+ int G=stream.ReadByte();
+ int R=stream.ReadByte();
+ int A=stream.ReadByte();
+
+ s[x,y]=Color.FromArgb(A,R,G,B);
+ }
+ }
+
+ s.m_changed=false;
+
+ return s;
+ }
+
+ // ------------------------------------------------
+ // PRIVATE
+ //
+ private int m_width;
+ private int m_height;
+ private Color[,] m_data;
+ private bool m_changed;
+
+ private void CheckSize(int width, int height)
+ {
+ if (width<0 || height<0)
+ {
+ throw new ArgumentException("Cannot use negative sizes");
+ }
+ }
+
+ private int Mod(int v, int m)
+ {
+ while (v<0)
+ {
+ v+=m;
+ }
+
+ return v%m;
+ }
+ }
+
+ /// <summary>
+ /// Describes a set of sprite frames that make up a single sprite
+ /// </summary>
+ public class Sprite : IEnumerable
+ {
+ // ------------------------------------------------
+ // PUBLIC
+ //
+ public Sprite()
+ {
+ m_changed=false;
+ m_name="Untitled";
+ m_frames=new ArrayList();
+ m_frames.Add(new Frame(16,16));
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return m_frames.GetEnumerator();
+ }
+
+ public string Name
+ {
+ get {return m_name;}
+ set {m_name=value;}
+ }
+
+ public static bool IsValidNameChar(char c)
+ {
+ return (Char.IsLetterOrDigit(c) || c=='_');
+ }
+
+ public Frame this[int i]
+ {
+ get
+ {
+ return (Frame)m_frames[i];
+ }
+ set
+ {
+ m_frames[i]=value;
+ m_changed=true;
+ }
+ }
+
+ public void Add(Frame s)
+ {
+ m_frames.Add(s);
+ m_changed=true;
+ }
+
+ public void Remove(Frame s)
+ {
+ m_frames.Remove(s);
+ m_changed=true;
+ }
+
+ public bool Changed
+ {
+ get
+ {
+ if (!m_changed)
+ {
+ foreach (Frame s in m_frames)
+ {
+ if (s.Changed)
+ {
+ return true;
+ }
+ }
+ }
+
+ return m_changed;
+ }
+ set {m_changed=value;}
+ }
+
+ public int Count
+ {
+ get {return m_frames.Count;}
+ }
+
+ public void Output(Stream stream)
+ {
+ Util.WriteString(stream,m_name);
+ Util.WriteInt(stream,m_frames.Count);
+
+ foreach (Frame s in m_frames)
+ {
+ s.Output(stream);
+ }
+
+ m_changed=false;
+ }
+
+ public static Sprite Input(Stream stream)
+ {
+ Sprite fr=new Sprite();
+
+ fr.Name=Util.ReadString(stream);
+
+ int num=Util.ReadInt(stream);
+
+ for(int f=0;f<num;f++)
+ {
+ fr.Add(Frame.Input(stream));
+ }
+
+ fr.Changed=false;
+
+ return fr;
+ }
+
+ // ------------------------------------------------
+ // PRIVATE
+ //
+ private bool m_changed;
+ private string m_name;
+ private ArrayList m_frames;
+ }
+
+
+ /// <summary>
+ /// Describes a list of sprites
+ /// </summary>
+ public class SpriteList : IEnumerable
+ {
+ // ------------------------------------------------
+ // PUBLIC
+ //
+ public SpriteList()
+ {
+ m_changed=false;
+ m_list=new ArrayList();
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return m_list.GetEnumerator();
+ }
+
+ public Sprite this[int i]
+ {
+ get
+ {
+ return (Sprite)m_list[i];
+ }
+ set
+ {
+ m_list[i]=value;
+ m_changed=true;
+ }
+ }
+
+ public void Add(Sprite s)
+ {
+ m_list.Add(s);
+ m_changed=true;
+ }
+
+ public void Remove(Sprite s)
+ {
+ m_list.Remove(s);
+ m_changed=true;
+ }
+
+ public bool Changed
+ {
+ get
+ {
+ if (!m_changed)
+ {
+ foreach (Sprite s in m_list)
+ {
+ if (s.Changed)
+ {
+ return true;
+ }
+ }
+ }
+
+ return m_changed;
+ }
+
+ set {m_changed=value;}
+ }
+
+ public int Count
+ {
+ get {return m_list.Count;}
+ }
+
+ public void Validate()
+ {
+ int num=m_list.Count;
+
+ for(int i=0;i<num;i++)
+ {
+ if (this[i].Name.Length==0)
+ {
+ throw new ApplicationException("Empty sprite name found");
+ }
+
+ for(int j=0;j<num;i++)
+ {
+ if (i!=j)
+ {
+ if (this[i].Name.ToLower()==this[j].Name.ToLower())
+ {
+ throw new ApplicationException
+ ("Sprite name " + this[i].Name + " is used more than once");
+ }
+ }
+ }
+ }
+ }
+
+ public void Output(Stream stream)
+ {
+ Util.WriteInt(stream,MAGIC);
+ Util.WriteInt(stream,m_list.Count);
+
+ foreach (Sprite s in m_list)
+ {
+ s.Output(stream);
+ }
+
+ m_changed=false;
+ }
+
+ public static SpriteList Input(Stream stream)
+ {
+ SpriteList l=new SpriteList();
+
+ int magic=Util.ReadInt(stream);
+
+ if (magic!=MAGIC)
+ {
+ throw new ApplicationException("Not a recognised sprite file");
+ }
+
+ int num=Util.ReadInt(stream);
+
+ for(int f=0;f<num;f++)
+ {
+ l.Add(Sprite.Input(stream));
+ }
+
+ l.Changed=false;
+
+ return l;
+ }
+
+ // ------------------------------------------------
+ // PRIVATE
+ //
+ private const int MAGIC=0x424d5331;
+ private bool m_changed;
+ private ArrayList m_list;
+ }
+}